From c519495201ffc1e1d6e28af178a5fa1179c8f0b0 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Tue, 29 Jul 2025 17:16:54 +0000 Subject: [PATCH] refactor: remove configurable memory optimization settings - Remove memory optimization settings from codebase-index schema - Remove memory optimization properties from config-manager - Update qdrant-client to always use memory optimization defaults - Update service-factory to remove memory optimization config passing - Update tests to remove memory optimization configuration expectations Memory optimizations are now always enabled as requested by @daniel-lxs --- packages/types/src/codebase-index.ts | 4 -- .../__tests__/config-manager.spec.ts | 21 -------- .../__tests__/service-factory.spec.ts | 50 ------------------- src/services/code-index/config-manager.ts | 38 -------------- src/services/code-index/service-factory.ts | 13 +---- .../code-index/vector-store/qdrant-client.ts | 42 +++------------- 6 files changed, 10 insertions(+), 158 deletions(-) diff --git a/packages/types/src/codebase-index.ts b/packages/types/src/codebase-index.ts index 90d49221e9..89d5b168d7 100644 --- a/packages/types/src/codebase-index.ts +++ b/packages/types/src/codebase-index.ts @@ -34,10 +34,6 @@ export const codebaseIndexConfigSchema = z.object({ // OpenAI Compatible specific fields codebaseIndexOpenAiCompatibleBaseUrl: z.string().optional(), codebaseIndexOpenAiCompatibleModelDimension: z.number().optional(), - // Memory optimization settings - codebaseIndexUseOnDiskStorage: z.boolean().optional(), - codebaseIndexMemoryMapThreshold: z.number().optional(), - codebaseIndexHnswEfSearch: z.number().optional(), }) export type CodebaseIndexConfig = z.infer diff --git a/src/services/code-index/__tests__/config-manager.spec.ts b/src/services/code-index/__tests__/config-manager.spec.ts index e62923c63f..673eeb046a 100644 --- a/src/services/code-index/__tests__/config-manager.spec.ts +++ b/src/services/code-index/__tests__/config-manager.spec.ts @@ -113,9 +113,6 @@ describe("CodeIndexConfigManager", () => { qdrantUrl: "http://localhost:6333", qdrantApiKey: "", searchMinScore: 0.4, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) expect(result.requiresRestart).toBe(false) }) @@ -151,9 +148,6 @@ describe("CodeIndexConfigManager", () => { qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) }) @@ -194,9 +188,6 @@ describe("CodeIndexConfigManager", () => { qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) }) @@ -237,9 +228,6 @@ describe("CodeIndexConfigManager", () => { qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) }) @@ -281,9 +269,6 @@ describe("CodeIndexConfigManager", () => { qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) }) @@ -324,9 +309,6 @@ describe("CodeIndexConfigManager", () => { qdrantUrl: "http://qdrant.local", qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) }) @@ -1337,9 +1319,6 @@ describe("CodeIndexConfigManager", () => { qdrantApiKey: "test-qdrant-key", searchMinScore: 0.4, searchMaxResults: 50, - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, }) }) diff --git a/src/services/code-index/__tests__/service-factory.spec.ts b/src/services/code-index/__tests__/service-factory.spec.ts index 3fa3aaa2a1..1d8f7ba478 100644 --- a/src/services/code-index/__tests__/service-factory.spec.ts +++ b/src/services/code-index/__tests__/service-factory.spec.ts @@ -49,11 +49,6 @@ describe("CodeIndexServiceFactory", () => { mockConfigManager = { getConfig: vitest.fn(), - memoryOptimizationConfig: { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, } mockCacheManager = {} @@ -372,11 +367,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 3072, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -402,11 +392,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 768, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -432,11 +417,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 3072, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -469,11 +449,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", modelDimension, // Should use model's built-in dimension, not manual "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -505,11 +480,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", manualDimension, // Should use manual dimension as fallback "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -539,11 +509,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 768, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -613,11 +578,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 3072, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -643,11 +603,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 3072, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) @@ -672,11 +627,6 @@ describe("CodeIndexServiceFactory", () => { "http://localhost:6333", 1536, "test-key", - { - useOnDiskStorage: true, - memoryMapThreshold: 50000, - hnswEfSearch: 128, - }, ) }) diff --git a/src/services/code-index/config-manager.ts b/src/services/code-index/config-manager.ts index 35c72ff1f4..32bdbc875b 100644 --- a/src/services/code-index/config-manager.ts +++ b/src/services/code-index/config-manager.ts @@ -24,10 +24,6 @@ export class CodeIndexConfigManager { private qdrantApiKey?: string private searchMinScore?: number private searchMaxResults?: number - // Memory optimization settings - private useOnDiskStorage?: boolean - private memoryMapThreshold?: number - private hnswEfSearch?: number constructor(private readonly contextProxy: ContextProxy) { // Initialize with current configuration to avoid false restart triggers @@ -55,9 +51,6 @@ export class CodeIndexConfigManager { codebaseIndexEmbedderModelId: "", codebaseIndexSearchMinScore: undefined, codebaseIndexSearchMaxResults: undefined, - codebaseIndexUseOnDiskStorage: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, - codebaseIndexMemoryMapThreshold: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD, - codebaseIndexHnswEfSearch: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.HNSW_EF_SEARCH, } const { @@ -68,9 +61,6 @@ export class CodeIndexConfigManager { codebaseIndexEmbedderModelId, codebaseIndexSearchMinScore, codebaseIndexSearchMaxResults, - codebaseIndexUseOnDiskStorage, - codebaseIndexMemoryMapThreshold, - codebaseIndexHnswEfSearch, } = codebaseIndexConfig const openAiKey = this.contextProxy?.getSecret("codeIndexOpenAiKey") ?? "" @@ -87,10 +77,6 @@ export class CodeIndexConfigManager { this.qdrantApiKey = qdrantApiKey ?? "" this.searchMinScore = codebaseIndexSearchMinScore this.searchMaxResults = codebaseIndexSearchMaxResults - this.useOnDiskStorage = codebaseIndexUseOnDiskStorage ?? QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE - this.memoryMapThreshold = - codebaseIndexMemoryMapThreshold ?? QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD - this.hnswEfSearch = codebaseIndexHnswEfSearch ?? QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.HNSW_EF_SEARCH // Validate and set model dimension const rawDimension = codebaseIndexConfig.codebaseIndexEmbedderModelDimension @@ -159,9 +145,6 @@ export class CodeIndexConfigManager { qdrantUrl?: string qdrantApiKey?: string searchMinScore?: number - useOnDiskStorage?: boolean - memoryMapThreshold?: number - hnswEfSearch?: number } requiresRestart: boolean }> { @@ -205,9 +188,6 @@ export class CodeIndexConfigManager { qdrantUrl: this.qdrantUrl, qdrantApiKey: this.qdrantApiKey, searchMinScore: this.currentSearchMinScore, - useOnDiskStorage: this.useOnDiskStorage, - memoryMapThreshold: this.memoryMapThreshold, - hnswEfSearch: this.hnswEfSearch, }, requiresRestart, } @@ -400,9 +380,6 @@ export class CodeIndexConfigManager { qdrantApiKey: this.qdrantApiKey, searchMinScore: this.currentSearchMinScore, searchMaxResults: this.currentSearchMaxResults, - useOnDiskStorage: this.useOnDiskStorage, - memoryMapThreshold: this.memoryMapThreshold, - hnswEfSearch: this.hnswEfSearch, } } @@ -437,21 +414,6 @@ export class CodeIndexConfigManager { } } - /** - * Gets the memory optimization settings - */ - public get memoryOptimizationConfig(): { - useOnDiskStorage?: boolean - memoryMapThreshold?: number - hnswEfSearch?: number - } { - return { - useOnDiskStorage: this.useOnDiskStorage, - memoryMapThreshold: this.memoryMapThreshold, - hnswEfSearch: this.hnswEfSearch, - } - } - /** * Gets the current model ID being used for embeddings. */ diff --git a/src/services/code-index/service-factory.ts b/src/services/code-index/service-factory.ts index f6fca593e2..cf9e6cd75e 100644 --- a/src/services/code-index/service-factory.ts +++ b/src/services/code-index/service-factory.ts @@ -136,17 +136,8 @@ export class CodeIndexServiceFactory { throw new Error(t("embeddings:serviceFactory.qdrantUrlMissing")) } - // Get memory optimization config from config manager - const memoryOptimization = this.configManager.memoryOptimizationConfig - - // Create QdrantVectorStore with memory optimization settings - return new QdrantVectorStore( - this.workspacePath, - config.qdrantUrl, - vectorSize, - config.qdrantApiKey, - memoryOptimization, - ) + // Create QdrantVectorStore with memory optimization always enabled + return new QdrantVectorStore(this.workspacePath, config.qdrantUrl, vectorSize, config.qdrantApiKey) } /** diff --git a/src/services/code-index/vector-store/qdrant-client.ts b/src/services/code-index/vector-store/qdrant-client.ts index e04fca26ca..875a3ad35e 100644 --- a/src/services/code-index/vector-store/qdrant-client.ts +++ b/src/services/code-index/vector-store/qdrant-client.ts @@ -7,7 +7,6 @@ import { Payload, VectorStoreSearchResult } from "../interfaces" import { DEFAULT_MAX_SEARCH_RESULTS, DEFAULT_SEARCH_MIN_SCORE } from "../constants" import { t } from "../../../i18n" import { - QdrantMemoryOptimizationConfig, QDRANT_MEMORY_OPTIMIZATION_DEFAULTS, QDRANT_HNSW_CONFIG_DEFAULTS, QDRANT_OPTIMIZER_CONFIG_DEFAULTS, @@ -24,7 +23,6 @@ export class QdrantVectorStore implements IVectorStore { private client: QdrantClient private readonly collectionName: string private readonly qdrantUrl: string = "http://localhost:6333" - private readonly memoryOptimization: QdrantMemoryOptimizationConfig /** * Creates a new Qdrant vector store @@ -32,15 +30,8 @@ export class QdrantVectorStore implements IVectorStore { * @param url Optional URL to the Qdrant server * @param vectorSize Size of the vectors * @param apiKey Optional API key for authentication - * @param memoryOptimization Optional memory optimization settings */ - constructor( - workspacePath: string, - url: string, - vectorSize: number, - apiKey?: string, - memoryOptimization?: QdrantMemoryOptimizationConfig, - ) { + constructor(workspacePath: string, url: string, vectorSize: number, apiKey?: string) { // Parse the URL to determine the appropriate QdrantClient configuration const parsedUrl = this.parseQdrantUrl(url) @@ -96,11 +87,6 @@ export class QdrantVectorStore implements IVectorStore { const hash = createHash("sha256").update(workspacePath).digest("hex") this.vectorSize = vectorSize this.collectionName = `ws-${hash.substring(0, 16)}` - this.memoryOptimization = memoryOptimization || { - useOnDiskStorage: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, - memoryMapThreshold: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD, - hnswEfSearch: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.HNSW_EF_SEARCH, - } } /** @@ -177,9 +163,7 @@ export class QdrantVectorStore implements IVectorStore { vectors: { size: this.vectorSize, distance: this.DISTANCE_METRIC, - on_disk: - this.memoryOptimization.useOnDiskStorage ?? - QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, + on_disk: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, }, // Configure HNSW index for memory efficiency hnsw_config: { @@ -187,9 +171,7 @@ export class QdrantVectorStore implements IVectorStore { ef_construct: QDRANT_HNSW_CONFIG_DEFAULTS.EF_CONSTRUCT, full_scan_threshold: QDRANT_HNSW_CONFIG_DEFAULTS.FULL_SCAN_THRESHOLD, max_indexing_threads: QDRANT_HNSW_CONFIG_DEFAULTS.MAX_INDEXING_THREADS, - on_disk: - this.memoryOptimization.useOnDiskStorage ?? - QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, + on_disk: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, payload_m: QDRANT_HNSW_CONFIG_DEFAULTS.PAYLOAD_M, }, // Enable memory-mapped storage for better memory management @@ -198,9 +180,7 @@ export class QdrantVectorStore implements IVectorStore { vacuum_min_vector_number: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.VACUUM_MIN_VECTOR_NUMBER, default_segment_number: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.DEFAULT_SEGMENT_NUMBER, max_segment_size: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.MAX_SEGMENT_SIZE, - memmap_threshold: - this.memoryOptimization.memoryMapThreshold ?? - QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD, + memmap_threshold: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD, indexing_threshold: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.INDEXING_THRESHOLD, flush_interval_sec: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.FLUSH_INTERVAL_SEC, max_optimization_threads: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.MAX_OPTIMIZATION_THREADS, @@ -293,9 +273,7 @@ export class QdrantVectorStore implements IVectorStore { vectors: { size: this.vectorSize, distance: this.DISTANCE_METRIC, - on_disk: - this.memoryOptimization.useOnDiskStorage ?? - QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, + on_disk: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, }, // Configure HNSW index for memory efficiency hnsw_config: { @@ -303,9 +281,7 @@ export class QdrantVectorStore implements IVectorStore { ef_construct: QDRANT_HNSW_CONFIG_DEFAULTS.EF_CONSTRUCT, full_scan_threshold: QDRANT_HNSW_CONFIG_DEFAULTS.FULL_SCAN_THRESHOLD, max_indexing_threads: QDRANT_HNSW_CONFIG_DEFAULTS.MAX_INDEXING_THREADS, - on_disk: - this.memoryOptimization.useOnDiskStorage ?? - QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, + on_disk: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.USE_ON_DISK_STORAGE, payload_m: QDRANT_HNSW_CONFIG_DEFAULTS.PAYLOAD_M, }, // Enable memory-mapped storage for better memory management @@ -314,9 +290,7 @@ export class QdrantVectorStore implements IVectorStore { vacuum_min_vector_number: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.VACUUM_MIN_VECTOR_NUMBER, default_segment_number: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.DEFAULT_SEGMENT_NUMBER, max_segment_size: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.MAX_SEGMENT_SIZE, - memmap_threshold: - this.memoryOptimization.memoryMapThreshold ?? - QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD, + memmap_threshold: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.MEMORY_MAP_THRESHOLD, indexing_threshold: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.INDEXING_THRESHOLD, flush_interval_sec: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.FLUSH_INTERVAL_SEC, max_optimization_threads: QDRANT_OPTIMIZER_CONFIG_DEFAULTS.MAX_OPTIMIZATION_THREADS, @@ -467,7 +441,7 @@ export class QdrantVectorStore implements IVectorStore { score_threshold: minScore ?? DEFAULT_SEARCH_MIN_SCORE, limit: maxResults ?? DEFAULT_MAX_SEARCH_RESULTS, params: { - hnsw_ef: this.memoryOptimization.hnswEfSearch ?? QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.HNSW_EF_SEARCH, + hnsw_ef: QDRANT_MEMORY_OPTIMIZATION_DEFAULTS.HNSW_EF_SEARCH, exact: false, quantization: { ignore: QDRANT_QUANTIZATION_CONFIG_DEFAULTS.IGNORE,