@soulcraft/brainy 0.41.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +605 -194
- package/dist/augmentations/conduitAugmentations.js +1158 -0
- package/dist/augmentations/conduitAugmentations.js.map +1 -0
- package/dist/augmentations/memoryAugmentations.d.ts +2 -0
- package/dist/augmentations/memoryAugmentations.d.ts.map +1 -1
- package/dist/augmentations/memoryAugmentations.js +270 -0
- package/dist/augmentations/memoryAugmentations.js.map +1 -0
- package/dist/augmentations/serverSearchAugmentations.js +531 -0
- package/dist/augmentations/serverSearchAugmentations.js.map +1 -0
- package/dist/browserFramework.d.ts +15 -0
- package/dist/demo.d.ts +106 -0
- package/dist/examples/basicUsage.js +118 -0
- package/dist/examples/basicUsage.js.map +1 -0
- package/dist/hnsw/distributedSearch.js +452 -0
- package/dist/hnsw/distributedSearch.js.map +1 -0
- package/dist/hnsw/hnswIndex.js +602 -0
- package/dist/hnsw/hnswIndex.js.map +1 -0
- package/dist/hnsw/hnswIndexOptimized.js +471 -0
- package/dist/hnsw/hnswIndexOptimized.js.map +1 -0
- package/dist/hnsw/optimizedHNSWIndex.js +313 -0
- package/dist/hnsw/optimizedHNSWIndex.js.map +1 -0
- package/dist/hnsw/partitionedHNSWIndex.js +304 -0
- package/dist/hnsw/partitionedHNSWIndex.js.map +1 -0
- package/dist/hnsw/scaledHNSWSystem.js +559 -0
- package/dist/hnsw/scaledHNSWSystem.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +81 -0
- package/dist/mcp/brainyMCPAdapter.js +142 -0
- package/dist/mcp/brainyMCPAdapter.js.map +1 -0
- package/dist/mcp/brainyMCPService.js +248 -0
- package/dist/mcp/brainyMCPService.js.map +1 -0
- package/dist/mcp/index.js +17 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/mcpAugmentationToolset.js +180 -0
- package/dist/mcp/mcpAugmentationToolset.js.map +1 -0
- package/dist/storage/adapters/baseStorageAdapter.js +349 -0
- package/dist/storage/adapters/baseStorageAdapter.js.map +1 -0
- package/dist/storage/adapters/batchS3Operations.js +287 -0
- package/dist/storage/adapters/batchS3Operations.js.map +1 -0
- package/dist/storage/adapters/fileSystemStorage.js +846 -0
- package/dist/storage/adapters/fileSystemStorage.js.map +1 -0
- package/dist/storage/adapters/memoryStorage.js +532 -0
- package/dist/storage/adapters/memoryStorage.js.map +1 -0
- package/dist/storage/adapters/opfsStorage.d.ts.map +1 -1
- package/dist/storage/adapters/opfsStorage.js +1118 -0
- package/dist/storage/adapters/opfsStorage.js.map +1 -0
- package/dist/storage/adapters/optimizedS3Search.js +248 -0
- package/dist/storage/adapters/optimizedS3Search.js.map +1 -0
- package/dist/storage/adapters/s3CompatibleStorage.js +2026 -0
- package/dist/storage/adapters/s3CompatibleStorage.js.map +1 -0
- package/dist/storage/baseStorage.js +603 -0
- package/dist/storage/baseStorage.js.map +1 -0
- package/dist/storage/cacheManager.js +1306 -0
- package/dist/storage/cacheManager.js.map +1 -0
- package/dist/storage/enhancedCacheManager.js +520 -0
- package/dist/storage/enhancedCacheManager.js.map +1 -0
- package/dist/storage/readOnlyOptimizations.js +425 -0
- package/dist/storage/readOnlyOptimizations.js.map +1 -0
- package/dist/storage/storageFactory.d.ts +0 -1
- package/dist/storage/storageFactory.d.ts.map +1 -1
- package/dist/storage/storageFactory.js +227 -0
- package/dist/storage/storageFactory.js.map +1 -0
- package/dist/types/augmentations.js +16 -0
- package/dist/types/augmentations.js.map +1 -0
- package/dist/types/brainyDataInterface.js +8 -0
- package/dist/types/brainyDataInterface.js.map +1 -0
- package/dist/types/distributedTypes.js +6 -0
- package/dist/types/distributedTypes.js.map +1 -0
- package/dist/types/fileSystemTypes.js +8 -0
- package/dist/types/fileSystemTypes.js.map +1 -0
- package/dist/types/graphTypes.js +247 -0
- package/dist/types/graphTypes.js.map +1 -0
- package/dist/types/mcpTypes.js +22 -0
- package/dist/types/mcpTypes.js.map +1 -0
- package/dist/types/paginationTypes.js +5 -0
- package/dist/types/paginationTypes.js.map +1 -0
- package/dist/types/pipelineTypes.js +7 -0
- package/dist/types/pipelineTypes.js.map +1 -0
- package/dist/types/tensorflowTypes.js +6 -0
- package/dist/types/tensorflowTypes.js.map +1 -0
- package/dist/unified.js +52 -128251
- package/dist/utils/autoConfiguration.js +341 -0
- package/dist/utils/autoConfiguration.js.map +1 -0
- package/dist/utils/cacheAutoConfig.js +261 -0
- package/dist/utils/cacheAutoConfig.js.map +1 -0
- package/dist/utils/crypto.js +45 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/distance.js +239 -0
- package/dist/utils/distance.js.map +1 -0
- package/dist/utils/embedding.d.ts.map +1 -1
- package/dist/utils/embedding.js +702 -0
- package/dist/utils/embedding.js.map +1 -0
- package/dist/utils/environment.js +75 -0
- package/dist/utils/environment.js.map +1 -0
- package/dist/utils/fieldNameTracking.js +90 -0
- package/dist/utils/fieldNameTracking.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/jsonProcessing.js +179 -0
- package/dist/utils/jsonProcessing.js.map +1 -0
- package/dist/utils/logger.js +129 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/operationUtils.js +126 -0
- package/dist/utils/operationUtils.js.map +1 -0
- package/dist/utils/robustModelLoader.d.ts +14 -0
- package/dist/utils/robustModelLoader.d.ts.map +1 -1
- package/dist/utils/robustModelLoader.js +537 -0
- package/dist/utils/robustModelLoader.js.map +1 -0
- package/dist/utils/searchCache.js +248 -0
- package/dist/utils/searchCache.js.map +1 -0
- package/dist/utils/statistics.js +25 -0
- package/dist/utils/statistics.js.map +1 -0
- package/dist/utils/statisticsCollector.js +224 -0
- package/dist/utils/statisticsCollector.js.map +1 -0
- package/dist/utils/textEncoding.js +309 -0
- package/dist/utils/textEncoding.js.map +1 -0
- package/dist/utils/typeUtils.js +40 -0
- package/dist/utils/typeUtils.js.map +1 -0
- package/dist/utils/version.d.ts +15 -3
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +24 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/utils/workerUtils.js +458 -0
- package/dist/utils/workerUtils.js.map +1 -0
- package/package.json +23 -18
- package/dist/brainy.js +0 -90220
- package/dist/brainy.min.js +0 -12511
- package/dist/patched-platform-node.d.ts +0 -17
- package/dist/statistics/statisticsManager.d.ts +0 -121
- package/dist/storage/fileSystemStorage.d.ts +0 -73
- package/dist/storage/fileSystemStorage.d.ts.map +0 -1
- package/dist/storage/opfsStorage.d.ts +0 -236
- package/dist/storage/opfsStorage.d.ts.map +0 -1
- package/dist/storage/s3CompatibleStorage.d.ts +0 -157
- package/dist/storage/s3CompatibleStorage.d.ts.map +0 -1
- package/dist/testing/prettyReporter.d.ts +0 -23
- package/dist/testing/prettySummaryReporter.d.ts +0 -22
- package/dist/unified.min.js +0 -16153
- package/dist/utils/environmentDetection.d.ts +0 -47
- package/dist/utils/environmentDetection.d.ts.map +0 -1
- package/dist/utils/tensorflowUtils.d.ts +0 -17
- package/dist/utils/tensorflowUtils.d.ts.map +0 -1
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimized HNSW Index for Large-Scale Vector Search
|
|
3
|
+
* Implements dynamic parameter tuning and performance optimizations
|
|
4
|
+
*/
|
|
5
|
+
import { HNSWIndex } from './hnswIndex.js';
|
|
6
|
+
import { euclideanDistance } from '../utils/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Optimized HNSW Index with dynamic parameter tuning for large datasets
|
|
9
|
+
*/
|
|
10
|
+
export class OptimizedHNSWIndex extends HNSWIndex {
|
|
11
|
+
constructor(config = {}, distanceFunction = euclideanDistance) {
|
|
12
|
+
// Set optimized defaults for large scale
|
|
13
|
+
const defaultConfig = {
|
|
14
|
+
M: 32, // Higher connectivity for better recall
|
|
15
|
+
efConstruction: 400, // Better build quality
|
|
16
|
+
efSearch: 100, // Dynamic - will be tuned
|
|
17
|
+
ml: 24, // Deeper hierarchy
|
|
18
|
+
useDiskBasedIndex: false, // Added missing property
|
|
19
|
+
dynamicParameterTuning: true,
|
|
20
|
+
targetSearchLatency: 100, // 100ms target
|
|
21
|
+
targetRecall: 0.95, // 95% recall target
|
|
22
|
+
maxNodes: 1000000, // 1M node limit
|
|
23
|
+
memoryBudget: 8 * 1024 * 1024 * 1024, // 8GB
|
|
24
|
+
diskCacheEnabled: true,
|
|
25
|
+
compressionEnabled: false, // Disabled by default for compatibility
|
|
26
|
+
performanceTracking: true,
|
|
27
|
+
adaptiveEfSearch: true,
|
|
28
|
+
levelMultiplier: 16,
|
|
29
|
+
seedConnections: 8,
|
|
30
|
+
pruningStrategy: 'hybrid'
|
|
31
|
+
};
|
|
32
|
+
const mergedConfig = { ...defaultConfig, ...config };
|
|
33
|
+
// Initialize parent with base config
|
|
34
|
+
super({
|
|
35
|
+
M: mergedConfig.M,
|
|
36
|
+
efConstruction: mergedConfig.efConstruction,
|
|
37
|
+
efSearch: mergedConfig.efSearch,
|
|
38
|
+
ml: mergedConfig.ml
|
|
39
|
+
}, distanceFunction, { useParallelization: true });
|
|
40
|
+
this.searchHistory = [];
|
|
41
|
+
this.optimizedConfig = mergedConfig;
|
|
42
|
+
// Initialize dynamic parameters
|
|
43
|
+
this.dynamicParams = {
|
|
44
|
+
efSearch: mergedConfig.efSearch,
|
|
45
|
+
efConstruction: mergedConfig.efConstruction,
|
|
46
|
+
M: mergedConfig.M,
|
|
47
|
+
ml: mergedConfig.ml
|
|
48
|
+
};
|
|
49
|
+
// Initialize performance metrics
|
|
50
|
+
this.performanceMetrics = {
|
|
51
|
+
averageSearchTime: 0,
|
|
52
|
+
averageRecall: 0,
|
|
53
|
+
memoryUsage: 0,
|
|
54
|
+
indexSize: 0,
|
|
55
|
+
apiCalls: 0,
|
|
56
|
+
cacheHitRate: 0
|
|
57
|
+
};
|
|
58
|
+
// Start parameter tuning if enabled
|
|
59
|
+
if (this.optimizedConfig.dynamicParameterTuning) {
|
|
60
|
+
this.startParameterTuning();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Optimized search with dynamic parameter adjustment
|
|
65
|
+
*/
|
|
66
|
+
async search(queryVector, k = 10) {
|
|
67
|
+
const startTime = Date.now();
|
|
68
|
+
// Adjust efSearch dynamically based on k and performance history
|
|
69
|
+
if (this.optimizedConfig.adaptiveEfSearch) {
|
|
70
|
+
this.adjustEfSearch(k);
|
|
71
|
+
}
|
|
72
|
+
// Check memory usage and trigger optimizations if needed
|
|
73
|
+
if (this.optimizedConfig.performanceTracking) {
|
|
74
|
+
this.checkMemoryUsage();
|
|
75
|
+
}
|
|
76
|
+
// Perform the search with current parameters
|
|
77
|
+
const originalConfig = this.getConfig();
|
|
78
|
+
// Temporarily update search parameters
|
|
79
|
+
const tempConfig = {
|
|
80
|
+
...originalConfig,
|
|
81
|
+
efSearch: this.dynamicParams.efSearch
|
|
82
|
+
};
|
|
83
|
+
// Use the parent's search method with optimized parameters
|
|
84
|
+
let results;
|
|
85
|
+
try {
|
|
86
|
+
// This is a simplified approach - in practice, we'd need to modify
|
|
87
|
+
// the parent class to accept runtime parameter changes
|
|
88
|
+
results = await super.search(queryVector, k);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error('Optimized search failed, falling back to default:', error);
|
|
92
|
+
results = await super.search(queryVector, k);
|
|
93
|
+
}
|
|
94
|
+
// Record performance metrics
|
|
95
|
+
const searchTime = Date.now() - startTime;
|
|
96
|
+
this.recordSearchMetrics(searchTime, k, results.length);
|
|
97
|
+
return results;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Dynamically adjust efSearch based on performance requirements
|
|
101
|
+
*/
|
|
102
|
+
adjustEfSearch(k) {
|
|
103
|
+
const recentSearches = this.searchHistory.slice(-10);
|
|
104
|
+
if (recentSearches.length < 3) {
|
|
105
|
+
// Not enough data, use heuristic
|
|
106
|
+
this.dynamicParams.efSearch = Math.max(k * 2, 50);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const averageLatency = recentSearches.reduce((sum, s) => sum + s.latency, 0) / recentSearches.length;
|
|
110
|
+
const targetLatency = this.optimizedConfig.targetSearchLatency;
|
|
111
|
+
// Adjust efSearch based on latency performance
|
|
112
|
+
if (averageLatency > targetLatency * 1.2) {
|
|
113
|
+
// Too slow, reduce efSearch
|
|
114
|
+
this.dynamicParams.efSearch = Math.max(Math.floor(this.dynamicParams.efSearch * 0.9), k);
|
|
115
|
+
}
|
|
116
|
+
else if (averageLatency < targetLatency * 0.8) {
|
|
117
|
+
// Fast enough, can increase efSearch for better recall
|
|
118
|
+
this.dynamicParams.efSearch = Math.min(Math.floor(this.dynamicParams.efSearch * 1.1), 500 // Maximum efSearch
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
// Ensure efSearch is at least k
|
|
122
|
+
this.dynamicParams.efSearch = Math.max(this.dynamicParams.efSearch, k);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Record search performance metrics
|
|
126
|
+
*/
|
|
127
|
+
recordSearchMetrics(latency, k, resultCount) {
|
|
128
|
+
if (!this.optimizedConfig.performanceTracking) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Add to search history
|
|
132
|
+
this.searchHistory.push({
|
|
133
|
+
latency,
|
|
134
|
+
k,
|
|
135
|
+
timestamp: Date.now()
|
|
136
|
+
});
|
|
137
|
+
// Keep only recent history (last 100 searches)
|
|
138
|
+
if (this.searchHistory.length > 100) {
|
|
139
|
+
this.searchHistory.shift();
|
|
140
|
+
}
|
|
141
|
+
// Update performance metrics
|
|
142
|
+
const recentSearches = this.searchHistory.slice(-20);
|
|
143
|
+
this.performanceMetrics.averageSearchTime =
|
|
144
|
+
recentSearches.reduce((sum, s) => sum + s.latency, 0) / recentSearches.length;
|
|
145
|
+
// Estimate recall (simplified - would need ground truth for accurate measurement)
|
|
146
|
+
this.performanceMetrics.averageRecall = Math.min(resultCount / k, 1.0);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check memory usage and trigger optimizations
|
|
150
|
+
*/
|
|
151
|
+
checkMemoryUsage() {
|
|
152
|
+
// Estimate memory usage (simplified)
|
|
153
|
+
const estimatedMemory = this.size() * 1000; // Rough estimate per node
|
|
154
|
+
this.performanceMetrics.memoryUsage = estimatedMemory;
|
|
155
|
+
if (estimatedMemory > this.optimizedConfig.memoryBudget * 0.9) {
|
|
156
|
+
console.warn('Memory usage approaching limit, consider index partitioning');
|
|
157
|
+
// Could trigger automatic partitioning or compression here
|
|
158
|
+
if (this.optimizedConfig.compressionEnabled) {
|
|
159
|
+
this.compressIndex();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Compress index to reduce memory usage (placeholder)
|
|
165
|
+
*/
|
|
166
|
+
compressIndex() {
|
|
167
|
+
console.log('Index compression not implemented yet');
|
|
168
|
+
// This would implement vector quantization or other compression techniques
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Start automatic parameter tuning
|
|
172
|
+
*/
|
|
173
|
+
startParameterTuning() {
|
|
174
|
+
this.parameterTuningInterval = setInterval(() => {
|
|
175
|
+
this.tuneParameters();
|
|
176
|
+
}, 30000); // Tune every 30 seconds
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Automatic parameter tuning based on performance metrics
|
|
180
|
+
*/
|
|
181
|
+
tuneParameters() {
|
|
182
|
+
if (this.searchHistory.length < 10) {
|
|
183
|
+
return; // Not enough data
|
|
184
|
+
}
|
|
185
|
+
const recentSearches = this.searchHistory.slice(-20);
|
|
186
|
+
const averageLatency = recentSearches.reduce((sum, s) => sum + s.latency, 0) / recentSearches.length;
|
|
187
|
+
// Tune based on performance vs targets
|
|
188
|
+
const latencyRatio = averageLatency / this.optimizedConfig.targetSearchLatency;
|
|
189
|
+
const recallRatio = this.performanceMetrics.averageRecall / this.optimizedConfig.targetRecall;
|
|
190
|
+
// Adjust M (connectivity) for long-term performance
|
|
191
|
+
if (this.size() > 10000) { // Only tune for larger indices
|
|
192
|
+
if (recallRatio < 0.95 && latencyRatio < 1.5) {
|
|
193
|
+
// Recall is low but we have latency budget, increase M
|
|
194
|
+
this.dynamicParams.M = Math.min(this.dynamicParams.M + 2, 64);
|
|
195
|
+
}
|
|
196
|
+
else if (latencyRatio > 1.2 && recallRatio > 1.0) {
|
|
197
|
+
// Latency is high but recall is good, can reduce M
|
|
198
|
+
this.dynamicParams.M = Math.max(this.dynamicParams.M - 2, 16);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
console.log(`Parameter tuning: efSearch=${this.dynamicParams.efSearch}, M=${this.dynamicParams.M}, latency=${averageLatency.toFixed(1)}ms`);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get optimized configuration recommendations for current dataset size
|
|
205
|
+
*/
|
|
206
|
+
getOptimizedConfig() {
|
|
207
|
+
const currentSize = this.size();
|
|
208
|
+
let recommendedConfig = {};
|
|
209
|
+
if (currentSize < 10000) {
|
|
210
|
+
// Small dataset - optimize for speed
|
|
211
|
+
recommendedConfig = {
|
|
212
|
+
M: 16,
|
|
213
|
+
efConstruction: 200,
|
|
214
|
+
efSearch: 50,
|
|
215
|
+
ml: 16
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
else if (currentSize < 100000) {
|
|
219
|
+
// Medium dataset - balance speed and recall
|
|
220
|
+
recommendedConfig = {
|
|
221
|
+
M: 24,
|
|
222
|
+
efConstruction: 300,
|
|
223
|
+
efSearch: 75,
|
|
224
|
+
ml: 20
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
else if (currentSize < 1000000) {
|
|
228
|
+
// Large dataset - optimize for recall
|
|
229
|
+
recommendedConfig = {
|
|
230
|
+
M: 32,
|
|
231
|
+
efConstruction: 400,
|
|
232
|
+
efSearch: 100,
|
|
233
|
+
ml: 24
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// Very large dataset - maximum quality
|
|
238
|
+
recommendedConfig = {
|
|
239
|
+
M: 48,
|
|
240
|
+
efConstruction: 500,
|
|
241
|
+
efSearch: 150,
|
|
242
|
+
ml: 28
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
...this.optimizedConfig,
|
|
247
|
+
...recommendedConfig
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get current performance metrics
|
|
252
|
+
*/
|
|
253
|
+
getPerformanceMetrics() {
|
|
254
|
+
return {
|
|
255
|
+
...this.performanceMetrics,
|
|
256
|
+
currentParams: { ...this.dynamicParams },
|
|
257
|
+
searchHistorySize: this.searchHistory.length
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Apply optimized bulk insertion strategy
|
|
262
|
+
*/
|
|
263
|
+
async bulkInsert(items) {
|
|
264
|
+
console.log(`Starting optimized bulk insert of ${items.length} items`);
|
|
265
|
+
// Sort items to optimize insertion order (by vector similarity)
|
|
266
|
+
const sortedItems = this.optimizeInsertionOrder(items);
|
|
267
|
+
// Temporarily adjust construction parameters for bulk operations
|
|
268
|
+
const originalEfConstruction = this.dynamicParams.efConstruction;
|
|
269
|
+
this.dynamicParams.efConstruction = Math.min(this.dynamicParams.efConstruction * 1.5, 800);
|
|
270
|
+
const results = [];
|
|
271
|
+
const batchSize = 100;
|
|
272
|
+
try {
|
|
273
|
+
// Process in batches to manage memory
|
|
274
|
+
for (let i = 0; i < sortedItems.length; i += batchSize) {
|
|
275
|
+
const batch = sortedItems.slice(i, i + batchSize);
|
|
276
|
+
for (const item of batch) {
|
|
277
|
+
const id = await this.addItem(item);
|
|
278
|
+
results.push(id);
|
|
279
|
+
}
|
|
280
|
+
// Periodic memory check
|
|
281
|
+
if (i % (batchSize * 10) === 0) {
|
|
282
|
+
this.checkMemoryUsage();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
// Restore original construction parameters
|
|
288
|
+
this.dynamicParams.efConstruction = originalEfConstruction;
|
|
289
|
+
}
|
|
290
|
+
console.log(`Completed bulk insert of ${results.length} items`);
|
|
291
|
+
return results;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Optimize insertion order to improve index quality
|
|
295
|
+
*/
|
|
296
|
+
optimizeInsertionOrder(items) {
|
|
297
|
+
if (items.length < 100) {
|
|
298
|
+
return items; // Not worth optimizing small batches
|
|
299
|
+
}
|
|
300
|
+
// Simple clustering-based ordering
|
|
301
|
+
// In practice, you might use more sophisticated methods
|
|
302
|
+
return items.sort(() => Math.random() - 0.5); // Shuffle for now
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Cleanup resources
|
|
306
|
+
*/
|
|
307
|
+
destroy() {
|
|
308
|
+
if (this.parameterTuningInterval) {
|
|
309
|
+
clearInterval(this.parameterTuningInterval);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=optimizedHNSWIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimizedHNSWIndex.js","sourceRoot":"","sources":["../../src/hnsw/optimizedHNSWIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Partitioned HNSW Index for Large-Scale Vector Search
|
|
3
|
+
* Implements sharding strategies to handle millions of vectors efficiently
|
|
4
|
+
*/
|
|
5
|
+
import { HNSWIndex } from './hnswIndex.js';
|
|
6
|
+
import { euclideanDistance } from '../utils/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Partitioned HNSW Index that splits large datasets across multiple smaller indices
|
|
9
|
+
* This enables efficient search across millions of vectors by reducing memory usage
|
|
10
|
+
* and parallelizing search operations
|
|
11
|
+
*/
|
|
12
|
+
export class PartitionedHNSWIndex {
|
|
13
|
+
constructor(partitionConfig = {}, hnswConfig = {}, distanceFunction = euclideanDistance) {
|
|
14
|
+
this.partitions = new Map();
|
|
15
|
+
this.partitionMetadata = new Map();
|
|
16
|
+
this.dimension = null;
|
|
17
|
+
this.nextPartitionId = 0;
|
|
18
|
+
this.config = {
|
|
19
|
+
maxNodesPerPartition: 50000, // Optimal size for memory efficiency
|
|
20
|
+
partitionStrategy: 'semantic', // Default to semantic for better performance
|
|
21
|
+
semanticClusters: 8, // Auto-tuned based on dataset
|
|
22
|
+
autoTuneSemanticClusters: true,
|
|
23
|
+
...partitionConfig
|
|
24
|
+
};
|
|
25
|
+
// Optimized HNSW parameters for large scale
|
|
26
|
+
this.hnswConfig = {
|
|
27
|
+
M: 32, // Higher connectivity for better recall
|
|
28
|
+
efConstruction: 400, // Better build quality
|
|
29
|
+
efSearch: 100, // Balance speed vs accuracy
|
|
30
|
+
ml: 24, // Deeper hierarchy
|
|
31
|
+
...hnswConfig
|
|
32
|
+
};
|
|
33
|
+
this.distanceFunction = distanceFunction;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Add a vector to the partitioned index
|
|
37
|
+
*/
|
|
38
|
+
async addItem(item) {
|
|
39
|
+
if (this.dimension === null) {
|
|
40
|
+
this.dimension = item.vector.length;
|
|
41
|
+
}
|
|
42
|
+
// Determine which partition this item belongs to
|
|
43
|
+
const partitionId = await this.selectPartition(item);
|
|
44
|
+
// Get or create the partition
|
|
45
|
+
let partition = this.partitions.get(partitionId);
|
|
46
|
+
if (!partition) {
|
|
47
|
+
partition = new HNSWIndex(this.hnswConfig, this.distanceFunction, { useParallelization: true });
|
|
48
|
+
this.partitions.set(partitionId, partition);
|
|
49
|
+
// Initialize partition metadata
|
|
50
|
+
this.partitionMetadata.set(partitionId, {
|
|
51
|
+
id: partitionId,
|
|
52
|
+
nodeCount: 0,
|
|
53
|
+
strategy: this.config.partitionStrategy,
|
|
54
|
+
created: new Date()
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Add item to the selected partition
|
|
58
|
+
await partition.addItem(item);
|
|
59
|
+
// Update partition metadata
|
|
60
|
+
const metadata = this.partitionMetadata.get(partitionId);
|
|
61
|
+
metadata.nodeCount = partition.size();
|
|
62
|
+
// Update bounds for semantic strategy
|
|
63
|
+
if (this.config.partitionStrategy === 'semantic') {
|
|
64
|
+
this.updatePartitionBounds(partitionId, item.vector);
|
|
65
|
+
}
|
|
66
|
+
// Check if partition is getting too large and needs splitting
|
|
67
|
+
if (metadata.nodeCount > this.config.maxNodesPerPartition * 1.2) {
|
|
68
|
+
await this.splitPartition(partitionId);
|
|
69
|
+
}
|
|
70
|
+
return item.id;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Search across all partitions for nearest neighbors
|
|
74
|
+
*/
|
|
75
|
+
async search(queryVector, k = 10, searchScope) {
|
|
76
|
+
if (this.partitions.size === 0) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
// Determine which partitions to search
|
|
80
|
+
const partitionsToSearch = await this.selectSearchPartitions(queryVector, searchScope);
|
|
81
|
+
// Search partitions in parallel
|
|
82
|
+
const searchPromises = partitionsToSearch.map(async (partitionId) => {
|
|
83
|
+
const partition = this.partitions.get(partitionId);
|
|
84
|
+
if (!partition)
|
|
85
|
+
return [];
|
|
86
|
+
// Search with higher k to get better global results
|
|
87
|
+
const partitionK = Math.min(k * 2, partition.size());
|
|
88
|
+
return partition.search(queryVector, partitionK);
|
|
89
|
+
});
|
|
90
|
+
const partitionResults = await Promise.all(searchPromises);
|
|
91
|
+
// Merge and sort results from all partitions
|
|
92
|
+
const allResults = [];
|
|
93
|
+
for (const results of partitionResults) {
|
|
94
|
+
allResults.push(...results);
|
|
95
|
+
}
|
|
96
|
+
// Sort by distance and return top k
|
|
97
|
+
allResults.sort((a, b) => a[1] - b[1]);
|
|
98
|
+
return allResults.slice(0, k);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Select the appropriate partition for a new item
|
|
102
|
+
* Automatically chooses semantic partitioning when beneficial, falls back to hash
|
|
103
|
+
*/
|
|
104
|
+
async selectPartition(item) {
|
|
105
|
+
// Auto-tune semantic clusters based on current dataset size
|
|
106
|
+
if (this.config.autoTuneSemanticClusters && this.config.partitionStrategy === 'semantic') {
|
|
107
|
+
this.autoTuneSemanticClusters();
|
|
108
|
+
}
|
|
109
|
+
switch (this.config.partitionStrategy) {
|
|
110
|
+
case 'semantic':
|
|
111
|
+
return await this.semanticPartition(item.vector);
|
|
112
|
+
case 'hash':
|
|
113
|
+
default:
|
|
114
|
+
return this.hashPartition(item.id);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Hash-based partitioning for even distribution
|
|
119
|
+
*/
|
|
120
|
+
hashPartition(id) {
|
|
121
|
+
const hash = this.simpleHash(id);
|
|
122
|
+
const existingPartitions = Array.from(this.partitions.keys());
|
|
123
|
+
// Find partition with space, or create new one
|
|
124
|
+
for (const partitionId of existingPartitions) {
|
|
125
|
+
const metadata = this.partitionMetadata.get(partitionId);
|
|
126
|
+
if (metadata && metadata.nodeCount < this.config.maxNodesPerPartition) {
|
|
127
|
+
return partitionId;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Create new partition
|
|
131
|
+
return `partition_${this.nextPartitionId++}`;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Semantic clustering partitioning
|
|
135
|
+
*/
|
|
136
|
+
async semanticPartition(vector) {
|
|
137
|
+
// Find closest partition centroid
|
|
138
|
+
let closestPartition = '';
|
|
139
|
+
let minDistance = Infinity;
|
|
140
|
+
for (const [partitionId, metadata] of this.partitionMetadata.entries()) {
|
|
141
|
+
if (metadata.bounds?.centroid) {
|
|
142
|
+
const distance = this.distanceFunction(vector, metadata.bounds.centroid);
|
|
143
|
+
if (distance < minDistance) {
|
|
144
|
+
minDistance = distance;
|
|
145
|
+
closestPartition = partitionId;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// If no suitable partition found or it's full, create new one
|
|
150
|
+
if (!closestPartition ||
|
|
151
|
+
this.partitionMetadata.get(closestPartition).nodeCount >= this.config.maxNodesPerPartition) {
|
|
152
|
+
closestPartition = `semantic_${this.nextPartitionId++}`;
|
|
153
|
+
}
|
|
154
|
+
return closestPartition;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Auto-tune semantic clusters based on dataset size and performance
|
|
158
|
+
*/
|
|
159
|
+
autoTuneSemanticClusters() {
|
|
160
|
+
const totalNodes = this.size();
|
|
161
|
+
const currentPartitions = this.partitions.size;
|
|
162
|
+
// Optimal clusters based on dataset size
|
|
163
|
+
let optimalClusters = Math.max(4, Math.min(32, Math.floor(totalNodes / 10000)));
|
|
164
|
+
// Adjust based on current partition performance
|
|
165
|
+
if (currentPartitions > 0) {
|
|
166
|
+
const avgNodesPerPartition = totalNodes / currentPartitions;
|
|
167
|
+
if (avgNodesPerPartition > this.config.maxNodesPerPartition * 0.8) {
|
|
168
|
+
// Partitions are getting full, increase clusters
|
|
169
|
+
optimalClusters = Math.min(32, this.config.semanticClusters + 2);
|
|
170
|
+
}
|
|
171
|
+
else if (avgNodesPerPartition < this.config.maxNodesPerPartition * 0.3 && currentPartitions > 4) {
|
|
172
|
+
// Partitions are underutilized, decrease clusters
|
|
173
|
+
optimalClusters = Math.max(4, this.config.semanticClusters - 1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (optimalClusters !== this.config.semanticClusters) {
|
|
177
|
+
console.log(`Auto-tuning semantic clusters: ${this.config.semanticClusters} → ${optimalClusters}`);
|
|
178
|
+
this.config.semanticClusters = optimalClusters;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Select which partitions to search based on query
|
|
183
|
+
*/
|
|
184
|
+
async selectSearchPartitions(queryVector, searchScope) {
|
|
185
|
+
if (searchScope?.partitionIds) {
|
|
186
|
+
return searchScope.partitionIds.filter(id => this.partitions.has(id));
|
|
187
|
+
}
|
|
188
|
+
const maxPartitions = searchScope?.maxPartitions || Math.min(5, this.partitions.size);
|
|
189
|
+
if (this.config.partitionStrategy === 'semantic') {
|
|
190
|
+
// Search partitions with closest centroids
|
|
191
|
+
const distances = [];
|
|
192
|
+
for (const [partitionId, metadata] of this.partitionMetadata.entries()) {
|
|
193
|
+
if (metadata.bounds?.centroid) {
|
|
194
|
+
const distance = this.distanceFunction(queryVector, metadata.bounds.centroid);
|
|
195
|
+
distances.push([partitionId, distance]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
distances.sort((a, b) => a[1] - b[1]);
|
|
199
|
+
return distances.slice(0, maxPartitions).map(([id]) => id);
|
|
200
|
+
}
|
|
201
|
+
// For other strategies, search all partitions or random subset
|
|
202
|
+
const allPartitionIds = Array.from(this.partitions.keys());
|
|
203
|
+
if (allPartitionIds.length <= maxPartitions) {
|
|
204
|
+
return allPartitionIds;
|
|
205
|
+
}
|
|
206
|
+
// Return random subset
|
|
207
|
+
const shuffled = [...allPartitionIds].sort(() => Math.random() - 0.5);
|
|
208
|
+
return shuffled.slice(0, maxPartitions);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Update partition bounds for semantic clustering
|
|
212
|
+
*/
|
|
213
|
+
updatePartitionBounds(partitionId, vector) {
|
|
214
|
+
const metadata = this.partitionMetadata.get(partitionId);
|
|
215
|
+
if (!metadata.bounds) {
|
|
216
|
+
metadata.bounds = {
|
|
217
|
+
centroid: [...vector],
|
|
218
|
+
radius: 0
|
|
219
|
+
};
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
// Update centroid using incremental mean
|
|
223
|
+
const { centroid } = metadata.bounds;
|
|
224
|
+
const nodeCount = metadata.nodeCount;
|
|
225
|
+
for (let i = 0; i < centroid.length; i++) {
|
|
226
|
+
centroid[i] = (centroid[i] * (nodeCount - 1) + vector[i]) / nodeCount;
|
|
227
|
+
}
|
|
228
|
+
// Update radius
|
|
229
|
+
const distance = this.distanceFunction(vector, centroid);
|
|
230
|
+
metadata.bounds.radius = Math.max(metadata.bounds.radius, distance);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Split an overgrown partition into smaller partitions
|
|
234
|
+
*/
|
|
235
|
+
async splitPartition(partitionId) {
|
|
236
|
+
const partition = this.partitions.get(partitionId);
|
|
237
|
+
if (!partition)
|
|
238
|
+
return;
|
|
239
|
+
console.log(`Splitting partition ${partitionId} with ${partition.size()} nodes`);
|
|
240
|
+
// For now, we'll implement a simple strategy
|
|
241
|
+
// In a full implementation, you'd want to analyze the data distribution
|
|
242
|
+
// and create more intelligent splits
|
|
243
|
+
// This is a placeholder - actual implementation would require
|
|
244
|
+
// accessing the internal nodes of the HNSW index
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Simple hash function for consistent partitioning
|
|
248
|
+
*/
|
|
249
|
+
simpleHash(str) {
|
|
250
|
+
let hash = 0;
|
|
251
|
+
for (let i = 0; i < str.length; i++) {
|
|
252
|
+
const char = str.charCodeAt(i);
|
|
253
|
+
hash = ((hash << 5) - hash) + char;
|
|
254
|
+
hash = hash & hash; // Convert to 32-bit integer
|
|
255
|
+
}
|
|
256
|
+
return Math.abs(hash);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get partition statistics
|
|
260
|
+
*/
|
|
261
|
+
getPartitionStats() {
|
|
262
|
+
const partitionDetails = Array.from(this.partitionMetadata.values());
|
|
263
|
+
const totalNodes = partitionDetails.reduce((sum, p) => sum + p.nodeCount, 0);
|
|
264
|
+
return {
|
|
265
|
+
totalPartitions: partitionDetails.length,
|
|
266
|
+
totalNodes,
|
|
267
|
+
averageNodesPerPartition: totalNodes / partitionDetails.length || 0,
|
|
268
|
+
partitionDetails
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Remove an item from the index
|
|
273
|
+
*/
|
|
274
|
+
async removeItem(id) {
|
|
275
|
+
// Find which partition contains this item
|
|
276
|
+
for (const [partitionId, partition] of this.partitions.entries()) {
|
|
277
|
+
if (partition.removeItem(id)) {
|
|
278
|
+
// Update metadata
|
|
279
|
+
const metadata = this.partitionMetadata.get(partitionId);
|
|
280
|
+
metadata.nodeCount = partition.size();
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Clear all partitions
|
|
288
|
+
*/
|
|
289
|
+
clear() {
|
|
290
|
+
for (const partition of this.partitions.values()) {
|
|
291
|
+
partition.clear();
|
|
292
|
+
}
|
|
293
|
+
this.partitions.clear();
|
|
294
|
+
this.partitionMetadata.clear();
|
|
295
|
+
this.nextPartitionId = 0;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Get total size across all partitions
|
|
299
|
+
*/
|
|
300
|
+
size() {
|
|
301
|
+
return Array.from(this.partitions.values()).reduce((sum, partition) => sum + partition.size(), 0);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=partitionedHNSWIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partitionedHNSWIndex.js","sourceRoot":"","sources":["../../src/hnsw/partitionedHNSWIndex.ts"],"names":[],"mappings":"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"}
|