@danielsimonjr/memoryjs 1.0.0 → 1.2.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 +385 -113
- package/README.md.backup-1768084780988 +266 -0
- package/dist/index.cjs +24156 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +16967 -0
- package/dist/index.d.ts +16963 -11
- package/dist/index.js +23887 -19
- package/dist/index.js.map +1 -1
- package/dist/workers/levenshteinWorker.cjs +102 -0
- package/dist/workers/levenshteinWorker.cjs.map +1 -0
- package/dist/workers/levenshteinWorker.js +57 -91
- package/dist/workers/levenshteinWorker.js.map +1 -1
- package/package.json +75 -69
- package/dist/core/EntityManager.d.ts +0 -268
- package/dist/core/EntityManager.d.ts.map +0 -1
- package/dist/core/EntityManager.js +0 -512
- package/dist/core/EntityManager.js.map +0 -1
- package/dist/core/GraphEventEmitter.d.ts +0 -202
- package/dist/core/GraphEventEmitter.d.ts.map +0 -1
- package/dist/core/GraphEventEmitter.js +0 -347
- package/dist/core/GraphEventEmitter.js.map +0 -1
- package/dist/core/GraphStorage.d.ts +0 -395
- package/dist/core/GraphStorage.d.ts.map +0 -1
- package/dist/core/GraphStorage.js +0 -786
- package/dist/core/GraphStorage.js.map +0 -1
- package/dist/core/GraphTraversal.d.ts +0 -141
- package/dist/core/GraphTraversal.d.ts.map +0 -1
- package/dist/core/GraphTraversal.js +0 -574
- package/dist/core/GraphTraversal.js.map +0 -1
- package/dist/core/HierarchyManager.d.ts +0 -111
- package/dist/core/HierarchyManager.d.ts.map +0 -1
- package/dist/core/HierarchyManager.js +0 -225
- package/dist/core/HierarchyManager.js.map +0 -1
- package/dist/core/ManagerContext.d.ts +0 -76
- package/dist/core/ManagerContext.d.ts.map +0 -1
- package/dist/core/ManagerContext.js +0 -129
- package/dist/core/ManagerContext.js.map +0 -1
- package/dist/core/ObservationManager.d.ts +0 -85
- package/dist/core/ObservationManager.d.ts.map +0 -1
- package/dist/core/ObservationManager.js +0 -124
- package/dist/core/ObservationManager.js.map +0 -1
- package/dist/core/RelationManager.d.ts +0 -131
- package/dist/core/RelationManager.d.ts.map +0 -1
- package/dist/core/RelationManager.js +0 -212
- package/dist/core/RelationManager.js.map +0 -1
- package/dist/core/SQLiteStorage.d.ts +0 -354
- package/dist/core/SQLiteStorage.d.ts.map +0 -1
- package/dist/core/SQLiteStorage.js +0 -919
- package/dist/core/SQLiteStorage.js.map +0 -1
- package/dist/core/StorageFactory.d.ts +0 -45
- package/dist/core/StorageFactory.d.ts.map +0 -1
- package/dist/core/StorageFactory.js +0 -65
- package/dist/core/StorageFactory.js.map +0 -1
- package/dist/core/TransactionManager.d.ts +0 -464
- package/dist/core/TransactionManager.d.ts.map +0 -1
- package/dist/core/TransactionManager.js +0 -869
- package/dist/core/TransactionManager.js.map +0 -1
- package/dist/core/index.d.ts +0 -17
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -20
- package/dist/core/index.js.map +0 -1
- package/dist/features/AnalyticsManager.d.ts +0 -44
- package/dist/features/AnalyticsManager.d.ts.map +0 -1
- package/dist/features/AnalyticsManager.js +0 -224
- package/dist/features/AnalyticsManager.js.map +0 -1
- package/dist/features/ArchiveManager.d.ts +0 -133
- package/dist/features/ArchiveManager.d.ts.map +0 -1
- package/dist/features/ArchiveManager.js +0 -282
- package/dist/features/ArchiveManager.js.map +0 -1
- package/dist/features/CompressionManager.d.ts +0 -119
- package/dist/features/CompressionManager.d.ts.map +0 -1
- package/dist/features/CompressionManager.js +0 -470
- package/dist/features/CompressionManager.js.map +0 -1
- package/dist/features/IOManager.d.ts +0 -225
- package/dist/features/IOManager.d.ts.map +0 -1
- package/dist/features/IOManager.js +0 -1093
- package/dist/features/IOManager.js.map +0 -1
- package/dist/features/KeywordExtractor.d.ts +0 -61
- package/dist/features/KeywordExtractor.d.ts.map +0 -1
- package/dist/features/KeywordExtractor.js +0 -127
- package/dist/features/KeywordExtractor.js.map +0 -1
- package/dist/features/ObservationNormalizer.d.ts +0 -90
- package/dist/features/ObservationNormalizer.d.ts.map +0 -1
- package/dist/features/ObservationNormalizer.js +0 -194
- package/dist/features/ObservationNormalizer.js.map +0 -1
- package/dist/features/StreamingExporter.d.ts +0 -128
- package/dist/features/StreamingExporter.d.ts.map +0 -1
- package/dist/features/StreamingExporter.js +0 -212
- package/dist/features/StreamingExporter.js.map +0 -1
- package/dist/features/TagManager.d.ts +0 -147
- package/dist/features/TagManager.d.ts.map +0 -1
- package/dist/features/TagManager.js +0 -211
- package/dist/features/TagManager.js.map +0 -1
- package/dist/features/index.d.ts +0 -14
- package/dist/features/index.d.ts.map +0 -1
- package/dist/features/index.js +0 -15
- package/dist/features/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/search/BM25Search.d.ts +0 -148
- package/dist/search/BM25Search.d.ts.map +0 -1
- package/dist/search/BM25Search.js +0 -340
- package/dist/search/BM25Search.js.map +0 -1
- package/dist/search/BasicSearch.d.ts +0 -51
- package/dist/search/BasicSearch.d.ts.map +0 -1
- package/dist/search/BasicSearch.js +0 -138
- package/dist/search/BasicSearch.js.map +0 -1
- package/dist/search/BooleanSearch.d.ts +0 -98
- package/dist/search/BooleanSearch.d.ts.map +0 -1
- package/dist/search/BooleanSearch.js +0 -431
- package/dist/search/BooleanSearch.js.map +0 -1
- package/dist/search/EarlyTerminationManager.d.ts +0 -140
- package/dist/search/EarlyTerminationManager.d.ts.map +0 -1
- package/dist/search/EarlyTerminationManager.js +0 -280
- package/dist/search/EarlyTerminationManager.js.map +0 -1
- package/dist/search/EmbeddingCache.d.ts +0 -175
- package/dist/search/EmbeddingCache.d.ts.map +0 -1
- package/dist/search/EmbeddingCache.js +0 -247
- package/dist/search/EmbeddingCache.js.map +0 -1
- package/dist/search/EmbeddingService.d.ts +0 -277
- package/dist/search/EmbeddingService.d.ts.map +0 -1
- package/dist/search/EmbeddingService.js +0 -531
- package/dist/search/EmbeddingService.js.map +0 -1
- package/dist/search/FuzzySearch.d.ts +0 -118
- package/dist/search/FuzzySearch.d.ts.map +0 -1
- package/dist/search/FuzzySearch.js +0 -313
- package/dist/search/FuzzySearch.js.map +0 -1
- package/dist/search/HybridScorer.d.ts +0 -181
- package/dist/search/HybridScorer.d.ts.map +0 -1
- package/dist/search/HybridScorer.js +0 -258
- package/dist/search/HybridScorer.js.map +0 -1
- package/dist/search/HybridSearchManager.d.ts +0 -80
- package/dist/search/HybridSearchManager.d.ts.map +0 -1
- package/dist/search/HybridSearchManager.js +0 -188
- package/dist/search/HybridSearchManager.js.map +0 -1
- package/dist/search/IncrementalIndexer.d.ts +0 -201
- package/dist/search/IncrementalIndexer.d.ts.map +0 -1
- package/dist/search/IncrementalIndexer.js +0 -343
- package/dist/search/IncrementalIndexer.js.map +0 -1
- package/dist/search/OptimizedInvertedIndex.d.ts +0 -163
- package/dist/search/OptimizedInvertedIndex.d.ts.map +0 -1
- package/dist/search/OptimizedInvertedIndex.js +0 -359
- package/dist/search/OptimizedInvertedIndex.js.map +0 -1
- package/dist/search/ParallelSearchExecutor.d.ts +0 -172
- package/dist/search/ParallelSearchExecutor.d.ts.map +0 -1
- package/dist/search/ParallelSearchExecutor.js +0 -310
- package/dist/search/ParallelSearchExecutor.js.map +0 -1
- package/dist/search/QuantizedVectorStore.d.ts +0 -171
- package/dist/search/QuantizedVectorStore.d.ts.map +0 -1
- package/dist/search/QuantizedVectorStore.js +0 -308
- package/dist/search/QuantizedVectorStore.js.map +0 -1
- package/dist/search/QueryAnalyzer.d.ts +0 -76
- package/dist/search/QueryAnalyzer.d.ts.map +0 -1
- package/dist/search/QueryAnalyzer.js +0 -228
- package/dist/search/QueryAnalyzer.js.map +0 -1
- package/dist/search/QueryCostEstimator.d.ts +0 -244
- package/dist/search/QueryCostEstimator.d.ts.map +0 -1
- package/dist/search/QueryCostEstimator.js +0 -653
- package/dist/search/QueryCostEstimator.js.map +0 -1
- package/dist/search/QueryPlanCache.d.ts +0 -220
- package/dist/search/QueryPlanCache.d.ts.map +0 -1
- package/dist/search/QueryPlanCache.js +0 -380
- package/dist/search/QueryPlanCache.js.map +0 -1
- package/dist/search/QueryPlanner.d.ts +0 -58
- package/dist/search/QueryPlanner.d.ts.map +0 -1
- package/dist/search/QueryPlanner.js +0 -138
- package/dist/search/QueryPlanner.js.map +0 -1
- package/dist/search/RankedSearch.d.ts +0 -71
- package/dist/search/RankedSearch.d.ts.map +0 -1
- package/dist/search/RankedSearch.js +0 -239
- package/dist/search/RankedSearch.js.map +0 -1
- package/dist/search/ReflectionManager.d.ts +0 -120
- package/dist/search/ReflectionManager.d.ts.map +0 -1
- package/dist/search/ReflectionManager.js +0 -232
- package/dist/search/ReflectionManager.js.map +0 -1
- package/dist/search/SavedSearchManager.d.ts +0 -79
- package/dist/search/SavedSearchManager.d.ts.map +0 -1
- package/dist/search/SavedSearchManager.js +0 -147
- package/dist/search/SavedSearchManager.js.map +0 -1
- package/dist/search/SearchFilterChain.d.ts +0 -120
- package/dist/search/SearchFilterChain.d.ts.map +0 -1
- package/dist/search/SearchFilterChain.js +0 -186
- package/dist/search/SearchFilterChain.js.map +0 -1
- package/dist/search/SearchManager.d.ts +0 -326
- package/dist/search/SearchManager.d.ts.map +0 -1
- package/dist/search/SearchManager.js +0 -454
- package/dist/search/SearchManager.js.map +0 -1
- package/dist/search/SearchSuggestions.d.ts +0 -27
- package/dist/search/SearchSuggestions.d.ts.map +0 -1
- package/dist/search/SearchSuggestions.js +0 -58
- package/dist/search/SearchSuggestions.js.map +0 -1
- package/dist/search/SemanticSearch.d.ts +0 -149
- package/dist/search/SemanticSearch.d.ts.map +0 -1
- package/dist/search/SemanticSearch.js +0 -324
- package/dist/search/SemanticSearch.js.map +0 -1
- package/dist/search/SymbolicSearch.d.ts +0 -61
- package/dist/search/SymbolicSearch.d.ts.map +0 -1
- package/dist/search/SymbolicSearch.js +0 -164
- package/dist/search/SymbolicSearch.js.map +0 -1
- package/dist/search/TFIDFEventSync.d.ts +0 -85
- package/dist/search/TFIDFEventSync.d.ts.map +0 -1
- package/dist/search/TFIDFEventSync.js +0 -134
- package/dist/search/TFIDFEventSync.js.map +0 -1
- package/dist/search/TFIDFIndexManager.d.ts +0 -151
- package/dist/search/TFIDFIndexManager.d.ts.map +0 -1
- package/dist/search/TFIDFIndexManager.js +0 -433
- package/dist/search/TFIDFIndexManager.js.map +0 -1
- package/dist/search/VectorStore.d.ts +0 -235
- package/dist/search/VectorStore.d.ts.map +0 -1
- package/dist/search/VectorStore.js +0 -312
- package/dist/search/VectorStore.js.map +0 -1
- package/dist/search/index.d.ts +0 -35
- package/dist/search/index.d.ts.map +0 -1
- package/dist/search/index.js +0 -53
- package/dist/search/index.js.map +0 -1
- package/dist/types/index.d.ts +0 -13
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -13
- package/dist/types/index.js.map +0 -1
- package/dist/types/types.d.ts +0 -1811
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/types.js +0 -10
- package/dist/types/types.js.map +0 -1
- package/dist/utils/BatchProcessor.d.ts +0 -271
- package/dist/utils/BatchProcessor.d.ts.map +0 -1
- package/dist/utils/BatchProcessor.js +0 -377
- package/dist/utils/BatchProcessor.js.map +0 -1
- package/dist/utils/MemoryMonitor.d.ts +0 -176
- package/dist/utils/MemoryMonitor.d.ts.map +0 -1
- package/dist/utils/MemoryMonitor.js +0 -306
- package/dist/utils/MemoryMonitor.js.map +0 -1
- package/dist/utils/WorkerPoolManager.d.ts +0 -233
- package/dist/utils/WorkerPoolManager.d.ts.map +0 -1
- package/dist/utils/WorkerPoolManager.js +0 -421
- package/dist/utils/WorkerPoolManager.js.map +0 -1
- package/dist/utils/compressedCache.d.ts +0 -221
- package/dist/utils/compressedCache.d.ts.map +0 -1
- package/dist/utils/compressedCache.js +0 -349
- package/dist/utils/compressedCache.js.map +0 -1
- package/dist/utils/compressionUtil.d.ts +0 -214
- package/dist/utils/compressionUtil.d.ts.map +0 -1
- package/dist/utils/compressionUtil.js +0 -248
- package/dist/utils/compressionUtil.js.map +0 -1
- package/dist/utils/constants.d.ts +0 -245
- package/dist/utils/constants.d.ts.map +0 -1
- package/dist/utils/constants.js +0 -253
- package/dist/utils/constants.js.map +0 -1
- package/dist/utils/entityUtils.d.ts +0 -379
- package/dist/utils/entityUtils.d.ts.map +0 -1
- package/dist/utils/entityUtils.js +0 -649
- package/dist/utils/entityUtils.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -95
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -146
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/formatters.d.ts +0 -145
- package/dist/utils/formatters.d.ts.map +0 -1
- package/dist/utils/formatters.js +0 -133
- package/dist/utils/formatters.js.map +0 -1
- package/dist/utils/index.d.ts +0 -26
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -88
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/indexes.d.ts +0 -270
- package/dist/utils/indexes.d.ts.map +0 -1
- package/dist/utils/indexes.js +0 -527
- package/dist/utils/indexes.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -31
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -41
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/operationUtils.d.ts +0 -124
- package/dist/utils/operationUtils.d.ts.map +0 -1
- package/dist/utils/operationUtils.js +0 -176
- package/dist/utils/operationUtils.js.map +0 -1
- package/dist/utils/parallelUtils.d.ts +0 -76
- package/dist/utils/parallelUtils.d.ts.map +0 -1
- package/dist/utils/parallelUtils.js +0 -192
- package/dist/utils/parallelUtils.js.map +0 -1
- package/dist/utils/schemas.d.ts +0 -556
- package/dist/utils/schemas.d.ts.map +0 -1
- package/dist/utils/schemas.js +0 -485
- package/dist/utils/schemas.js.map +0 -1
- package/dist/utils/searchAlgorithms.d.ts +0 -99
- package/dist/utils/searchAlgorithms.d.ts.map +0 -1
- package/dist/utils/searchAlgorithms.js +0 -168
- package/dist/utils/searchAlgorithms.js.map +0 -1
- package/dist/utils/searchCache.d.ts +0 -108
- package/dist/utils/searchCache.d.ts.map +0 -1
- package/dist/utils/searchCache.js +0 -210
- package/dist/utils/searchCache.js.map +0 -1
- package/dist/utils/taskScheduler.d.ts +0 -294
- package/dist/utils/taskScheduler.d.ts.map +0 -1
- package/dist/utils/taskScheduler.js +0 -487
- package/dist/utils/taskScheduler.js.map +0 -1
- package/dist/workers/index.d.ts +0 -12
- package/dist/workers/index.d.ts.map +0 -1
- package/dist/workers/index.js +0 -10
- package/dist/workers/index.js.map +0 -1
- package/dist/workers/levenshteinWorker.d.ts +0 -60
- package/dist/workers/levenshteinWorker.d.ts.map +0 -1
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Boolean Search
|
|
3
|
-
*
|
|
4
|
-
* Advanced search with boolean operators (AND, OR, NOT) and field-specific queries.
|
|
5
|
-
*
|
|
6
|
-
* @module search/BooleanSearch
|
|
7
|
-
*/
|
|
8
|
-
import { SEARCH_LIMITS, QUERY_LIMITS } from '../utils/constants.js';
|
|
9
|
-
import { ValidationError } from '../utils/errors.js';
|
|
10
|
-
import { SearchFilterChain } from './SearchFilterChain.js';
|
|
11
|
-
/**
|
|
12
|
-
* Phase 4 Sprint 4: Maximum AST cache size.
|
|
13
|
-
*/
|
|
14
|
-
const AST_CACHE_MAX_SIZE = 50;
|
|
15
|
-
/**
|
|
16
|
-
* Phase 4 Sprint 4: Result cache max size.
|
|
17
|
-
*/
|
|
18
|
-
const RESULT_CACHE_MAX_SIZE = 100;
|
|
19
|
-
/**
|
|
20
|
-
* Phase 4 Sprint 4: Cache TTL in milliseconds (5 minutes).
|
|
21
|
-
*/
|
|
22
|
-
const BOOLEAN_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
23
|
-
/**
|
|
24
|
-
* Performs boolean search with query parsing and AST evaluation.
|
|
25
|
-
*/
|
|
26
|
-
export class BooleanSearch {
|
|
27
|
-
storage;
|
|
28
|
-
/**
|
|
29
|
-
* Phase 4 Sprint 4: AST cache to avoid re-parsing queries.
|
|
30
|
-
* Maps query string -> parsed AST.
|
|
31
|
-
*/
|
|
32
|
-
astCache = new Map();
|
|
33
|
-
/**
|
|
34
|
-
* Phase 4 Sprint 4: Result cache for boolean search.
|
|
35
|
-
* Maps cache key -> cached results.
|
|
36
|
-
*/
|
|
37
|
-
resultCache = new Map();
|
|
38
|
-
constructor(storage) {
|
|
39
|
-
this.storage = storage;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Phase 4 Sprint 4: Generate cache key for boolean search.
|
|
43
|
-
*/
|
|
44
|
-
generateCacheKey(query, tags, minImportance, maxImportance, offset, limit) {
|
|
45
|
-
return JSON.stringify({
|
|
46
|
-
q: query,
|
|
47
|
-
tags: tags?.sort().join(',') ?? '',
|
|
48
|
-
min: minImportance,
|
|
49
|
-
max: maxImportance,
|
|
50
|
-
off: offset,
|
|
51
|
-
lim: limit,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Phase 4 Sprint 4: Clear all caches.
|
|
56
|
-
*/
|
|
57
|
-
clearCache() {
|
|
58
|
-
this.astCache.clear();
|
|
59
|
-
this.resultCache.clear();
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Phase 4 Sprint 4: Cleanup old cache entries.
|
|
63
|
-
*/
|
|
64
|
-
cleanupResultCache() {
|
|
65
|
-
const now = Date.now();
|
|
66
|
-
const entries = Array.from(this.resultCache.entries());
|
|
67
|
-
// Remove expired entries
|
|
68
|
-
for (const [key, entry] of entries) {
|
|
69
|
-
if (now - entry.timestamp > BOOLEAN_CACHE_TTL_MS) {
|
|
70
|
-
this.resultCache.delete(key);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// If still over limit, remove oldest entries
|
|
74
|
-
if (this.resultCache.size > RESULT_CACHE_MAX_SIZE) {
|
|
75
|
-
const sortedEntries = entries
|
|
76
|
-
.filter(([k]) => this.resultCache.has(k))
|
|
77
|
-
.sort((a, b) => a[1].timestamp - b[1].timestamp);
|
|
78
|
-
const toRemove = sortedEntries.slice(0, this.resultCache.size - RESULT_CACHE_MAX_SIZE);
|
|
79
|
-
for (const [key] of toRemove) {
|
|
80
|
-
this.resultCache.delete(key);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Phase 4 Sprint 4: Get or parse AST for a query.
|
|
86
|
-
*/
|
|
87
|
-
getOrParseAST(query) {
|
|
88
|
-
// Check AST cache
|
|
89
|
-
const cached = this.astCache.get(query);
|
|
90
|
-
if (cached) {
|
|
91
|
-
return cached;
|
|
92
|
-
}
|
|
93
|
-
// Parse and cache
|
|
94
|
-
const ast = this.parseBooleanQuery(query);
|
|
95
|
-
// Enforce cache size limit
|
|
96
|
-
if (this.astCache.size >= AST_CACHE_MAX_SIZE) {
|
|
97
|
-
// Remove first entry (oldest)
|
|
98
|
-
const firstKey = this.astCache.keys().next().value;
|
|
99
|
-
if (firstKey)
|
|
100
|
-
this.astCache.delete(firstKey);
|
|
101
|
-
}
|
|
102
|
-
this.astCache.set(query, ast);
|
|
103
|
-
return ast;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Boolean search with support for AND, OR, NOT operators, field-specific queries, and pagination.
|
|
107
|
-
*
|
|
108
|
-
* Phase 4 Sprint 4: Implements AST caching and result caching for repeated queries.
|
|
109
|
-
*
|
|
110
|
-
* Query syntax examples:
|
|
111
|
-
* - "alice AND programming" - Both terms must match
|
|
112
|
-
* - "type:person OR type:organization" - Either type matches
|
|
113
|
-
* - "NOT archived" - Exclude archived items
|
|
114
|
-
* - "name:alice AND (observation:coding OR observation:teaching)"
|
|
115
|
-
*
|
|
116
|
-
* @param query - Boolean query string
|
|
117
|
-
* @param tags - Optional tags filter
|
|
118
|
-
* @param minImportance - Optional minimum importance
|
|
119
|
-
* @param maxImportance - Optional maximum importance
|
|
120
|
-
* @param offset - Number of results to skip (default: 0)
|
|
121
|
-
* @param limit - Maximum number of results (default: 50, max: 200)
|
|
122
|
-
* @returns Filtered knowledge graph matching the boolean query with pagination applied
|
|
123
|
-
*/
|
|
124
|
-
async booleanSearch(query, tags, minImportance, maxImportance, offset = 0, limit = SEARCH_LIMITS.DEFAULT) {
|
|
125
|
-
// Validate query length
|
|
126
|
-
if (query.length > QUERY_LIMITS.MAX_QUERY_LENGTH) {
|
|
127
|
-
throw new ValidationError('Query too long', [`Query length ${query.length} exceeds maximum of ${QUERY_LIMITS.MAX_QUERY_LENGTH} characters`]);
|
|
128
|
-
}
|
|
129
|
-
const graph = await this.storage.loadGraph();
|
|
130
|
-
// Phase 4 Sprint 4: Check result cache
|
|
131
|
-
const cacheKey = this.generateCacheKey(query, tags, minImportance, maxImportance, offset, limit);
|
|
132
|
-
const cached = this.resultCache.get(cacheKey);
|
|
133
|
-
if (cached && cached.entityCount === graph.entities.length) {
|
|
134
|
-
const now = Date.now();
|
|
135
|
-
if (now - cached.timestamp < BOOLEAN_CACHE_TTL_MS) {
|
|
136
|
-
// Return cached results
|
|
137
|
-
const cachedNameSet = new Set(cached.entityNames);
|
|
138
|
-
const cachedEntities = graph.entities.filter(e => cachedNameSet.has(e.name));
|
|
139
|
-
const cachedRelations = graph.relations.filter(r => cachedNameSet.has(r.from) && cachedNameSet.has(r.to));
|
|
140
|
-
return { entities: cachedEntities, relations: cachedRelations };
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Phase 4 Sprint 4: Use cached AST or parse new one
|
|
144
|
-
let queryAst;
|
|
145
|
-
try {
|
|
146
|
-
queryAst = this.getOrParseAST(query);
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
throw new Error(`Failed to parse boolean query: ${error instanceof Error ? error.message : String(error)}`);
|
|
150
|
-
}
|
|
151
|
-
// Validate query complexity
|
|
152
|
-
this.validateQueryComplexity(queryAst);
|
|
153
|
-
// First filter by boolean query evaluation (search-specific)
|
|
154
|
-
const booleanMatched = graph.entities.filter(e => this.evaluateBooleanQuery(queryAst, e));
|
|
155
|
-
// Apply tag and importance filters using SearchFilterChain
|
|
156
|
-
const filters = { tags, minImportance, maxImportance };
|
|
157
|
-
const filteredEntities = SearchFilterChain.applyFilters(booleanMatched, filters);
|
|
158
|
-
// Apply pagination using SearchFilterChain
|
|
159
|
-
const pagination = SearchFilterChain.validatePagination(offset, limit);
|
|
160
|
-
const paginatedEntities = SearchFilterChain.paginate(filteredEntities, pagination);
|
|
161
|
-
// Phase 4 Sprint 4: Cache the results
|
|
162
|
-
this.resultCache.set(cacheKey, {
|
|
163
|
-
ast: queryAst,
|
|
164
|
-
entityNames: paginatedEntities.map(e => e.name),
|
|
165
|
-
entityCount: graph.entities.length,
|
|
166
|
-
timestamp: Date.now(),
|
|
167
|
-
});
|
|
168
|
-
// Cleanup old cache entries periodically
|
|
169
|
-
if (this.resultCache.size > RESULT_CACHE_MAX_SIZE / 2) {
|
|
170
|
-
this.cleanupResultCache();
|
|
171
|
-
}
|
|
172
|
-
const filteredEntityNames = new Set(paginatedEntities.map(e => e.name));
|
|
173
|
-
const filteredRelations = graph.relations.filter(r => filteredEntityNames.has(r.from) && filteredEntityNames.has(r.to));
|
|
174
|
-
return { entities: paginatedEntities, relations: filteredRelations };
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Tokenize a boolean query into tokens.
|
|
178
|
-
*
|
|
179
|
-
* Handles quoted strings, parentheses, and operators.
|
|
180
|
-
*/
|
|
181
|
-
tokenizeBooleanQuery(query) {
|
|
182
|
-
const tokens = [];
|
|
183
|
-
let current = '';
|
|
184
|
-
let inQuotes = false;
|
|
185
|
-
for (let i = 0; i < query.length; i++) {
|
|
186
|
-
const char = query[i];
|
|
187
|
-
if (char === '"') {
|
|
188
|
-
if (inQuotes) {
|
|
189
|
-
// End of quoted string
|
|
190
|
-
tokens.push(current);
|
|
191
|
-
current = '';
|
|
192
|
-
inQuotes = false;
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
// Start of quoted string
|
|
196
|
-
if (current.trim()) {
|
|
197
|
-
tokens.push(current.trim());
|
|
198
|
-
current = '';
|
|
199
|
-
}
|
|
200
|
-
inQuotes = true;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
else if (!inQuotes && (char === '(' || char === ')')) {
|
|
204
|
-
// Parentheses are separate tokens
|
|
205
|
-
if (current.trim()) {
|
|
206
|
-
tokens.push(current.trim());
|
|
207
|
-
current = '';
|
|
208
|
-
}
|
|
209
|
-
tokens.push(char);
|
|
210
|
-
}
|
|
211
|
-
else if (!inQuotes && /\s/.test(char)) {
|
|
212
|
-
// Whitespace outside quotes
|
|
213
|
-
if (current.trim()) {
|
|
214
|
-
tokens.push(current.trim());
|
|
215
|
-
current = '';
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
current += char;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (current.trim()) {
|
|
223
|
-
tokens.push(current.trim());
|
|
224
|
-
}
|
|
225
|
-
return tokens;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Parse a boolean search query into an AST.
|
|
229
|
-
*
|
|
230
|
-
* Supports: AND, OR, NOT, parentheses, field-specific queries (field:value)
|
|
231
|
-
*/
|
|
232
|
-
parseBooleanQuery(query) {
|
|
233
|
-
const tokens = this.tokenizeBooleanQuery(query);
|
|
234
|
-
let position = 0;
|
|
235
|
-
const peek = () => tokens[position];
|
|
236
|
-
const consume = () => tokens[position++];
|
|
237
|
-
// Parse OR expressions (lowest precedence)
|
|
238
|
-
const parseOr = () => {
|
|
239
|
-
let left = parseAnd();
|
|
240
|
-
while (peek()?.toUpperCase() === 'OR') {
|
|
241
|
-
consume(); // consume 'OR'
|
|
242
|
-
const right = parseAnd();
|
|
243
|
-
left = { type: 'OR', children: [left, right] };
|
|
244
|
-
}
|
|
245
|
-
return left;
|
|
246
|
-
};
|
|
247
|
-
// Parse AND expressions
|
|
248
|
-
const parseAnd = () => {
|
|
249
|
-
let left = parseNot();
|
|
250
|
-
while (peek() && peek()?.toUpperCase() !== 'OR' && peek() !== ')') {
|
|
251
|
-
// Implicit AND if next token is not OR or )
|
|
252
|
-
if (peek()?.toUpperCase() === 'AND') {
|
|
253
|
-
consume(); // consume 'AND'
|
|
254
|
-
}
|
|
255
|
-
const right = parseNot();
|
|
256
|
-
left = { type: 'AND', children: [left, right] };
|
|
257
|
-
}
|
|
258
|
-
return left;
|
|
259
|
-
};
|
|
260
|
-
// Parse NOT expressions
|
|
261
|
-
const parseNot = () => {
|
|
262
|
-
if (peek()?.toUpperCase() === 'NOT') {
|
|
263
|
-
consume(); // consume 'NOT'
|
|
264
|
-
const child = parseNot();
|
|
265
|
-
return { type: 'NOT', child };
|
|
266
|
-
}
|
|
267
|
-
return parsePrimary();
|
|
268
|
-
};
|
|
269
|
-
// Parse primary expressions (terms, field queries, parentheses)
|
|
270
|
-
const parsePrimary = () => {
|
|
271
|
-
const token = peek();
|
|
272
|
-
if (!token) {
|
|
273
|
-
throw new Error('Unexpected end of query');
|
|
274
|
-
}
|
|
275
|
-
// Parentheses
|
|
276
|
-
if (token === '(') {
|
|
277
|
-
consume(); // consume '('
|
|
278
|
-
const node = parseOr();
|
|
279
|
-
if (consume() !== ')') {
|
|
280
|
-
throw new Error('Expected closing parenthesis');
|
|
281
|
-
}
|
|
282
|
-
return node;
|
|
283
|
-
}
|
|
284
|
-
// Field-specific query (field:value)
|
|
285
|
-
if (token.includes(':')) {
|
|
286
|
-
consume();
|
|
287
|
-
const [field, ...valueParts] = token.split(':');
|
|
288
|
-
const value = valueParts.join(':'); // Handle colons in value
|
|
289
|
-
return { type: 'TERM', field: field.toLowerCase(), value: value.toLowerCase() };
|
|
290
|
-
}
|
|
291
|
-
// Regular term
|
|
292
|
-
consume();
|
|
293
|
-
return { type: 'TERM', value: token.toLowerCase() };
|
|
294
|
-
};
|
|
295
|
-
const result = parseOr();
|
|
296
|
-
// Check for unconsumed tokens
|
|
297
|
-
if (position < tokens.length) {
|
|
298
|
-
throw new Error(`Unexpected token: ${tokens[position]}`);
|
|
299
|
-
}
|
|
300
|
-
return result;
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Evaluate a boolean query AST against an entity.
|
|
304
|
-
*/
|
|
305
|
-
evaluateBooleanQuery(node, entity) {
|
|
306
|
-
switch (node.type) {
|
|
307
|
-
case 'AND':
|
|
308
|
-
return node.children.every(child => this.evaluateBooleanQuery(child, entity));
|
|
309
|
-
case 'OR':
|
|
310
|
-
return node.children.some(child => this.evaluateBooleanQuery(child, entity));
|
|
311
|
-
case 'NOT':
|
|
312
|
-
return !this.evaluateBooleanQuery(node.child, entity);
|
|
313
|
-
case 'TERM': {
|
|
314
|
-
const value = node.value;
|
|
315
|
-
// OPTIMIZED: Use pre-computed lowercase cache
|
|
316
|
-
const lowercased = this.storage.getLowercased(entity.name);
|
|
317
|
-
// Field-specific search
|
|
318
|
-
if (node.field) {
|
|
319
|
-
switch (node.field) {
|
|
320
|
-
case 'name':
|
|
321
|
-
return lowercased ? lowercased.name.includes(value) : entity.name.toLowerCase().includes(value);
|
|
322
|
-
case 'type':
|
|
323
|
-
case 'entitytype':
|
|
324
|
-
return lowercased ? lowercased.entityType.includes(value) : entity.entityType.toLowerCase().includes(value);
|
|
325
|
-
case 'observation':
|
|
326
|
-
case 'observations':
|
|
327
|
-
// OPTIMIZED: Use observation index for simple single-word terms (O(1) vs O(n))
|
|
328
|
-
// The index only matches complete words, not substrings, so we can only
|
|
329
|
-
// use it as a quick positive check. If not found in index, fall through
|
|
330
|
-
// to substring matching for compatibility.
|
|
331
|
-
if (this.isSimpleTerm(value) && !value.includes(' ')) {
|
|
332
|
-
const candidateNames = this.storage.getEntitiesByObservationWord(value);
|
|
333
|
-
if (candidateNames.has(entity.name)) {
|
|
334
|
-
return true; // O(1) positive match
|
|
335
|
-
}
|
|
336
|
-
// Not found in index - entity doesn't have this complete word,
|
|
337
|
-
// but might contain it as substring - fall through to check
|
|
338
|
-
}
|
|
339
|
-
// Linear scan for substring matches, phrases, and patterns
|
|
340
|
-
return lowercased
|
|
341
|
-
? lowercased.observations.some(obs => obs.includes(value))
|
|
342
|
-
: entity.observations.some(obs => obs.toLowerCase().includes(value));
|
|
343
|
-
case 'tag':
|
|
344
|
-
case 'tags':
|
|
345
|
-
return lowercased
|
|
346
|
-
? lowercased.tags.some(tag => tag.includes(value))
|
|
347
|
-
: (entity.tags?.some(tag => tag.toLowerCase().includes(value)) || false);
|
|
348
|
-
default:
|
|
349
|
-
// Unknown field, search all text fields
|
|
350
|
-
return this.entityMatchesTerm(entity, value, lowercased);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
// General search across all fields
|
|
354
|
-
return this.entityMatchesTerm(entity, value, lowercased);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Check if a search term is simple (no regex or wildcards).
|
|
360
|
-
* Simple terms can use the O(1) observation index.
|
|
361
|
-
*/
|
|
362
|
-
isSimpleTerm(term) {
|
|
363
|
-
const specialChars = /[.*+?^${}()|\\[\]]/;
|
|
364
|
-
return !specialChars.test(term);
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Check if entity matches a search term in any text field.
|
|
368
|
-
* OPTIMIZED: Uses pre-computed lowercase data when available.
|
|
369
|
-
*/
|
|
370
|
-
entityMatchesTerm(entity, term, lowercased) {
|
|
371
|
-
if (lowercased) {
|
|
372
|
-
return (lowercased.name.includes(term) ||
|
|
373
|
-
lowercased.entityType.includes(term) ||
|
|
374
|
-
lowercased.observations.some(obs => obs.includes(term)) ||
|
|
375
|
-
lowercased.tags.some(tag => tag.includes(term)));
|
|
376
|
-
}
|
|
377
|
-
// Fallback for entities not in cache
|
|
378
|
-
const termLower = term.toLowerCase();
|
|
379
|
-
return (entity.name.toLowerCase().includes(termLower) ||
|
|
380
|
-
entity.entityType.toLowerCase().includes(termLower) ||
|
|
381
|
-
entity.observations.some(obs => obs.toLowerCase().includes(termLower)) ||
|
|
382
|
-
(entity.tags?.some(tag => tag.toLowerCase().includes(termLower)) || false));
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Validate query complexity to prevent resource exhaustion.
|
|
386
|
-
* Checks nesting depth, term count, and operator count against configured limits.
|
|
387
|
-
*/
|
|
388
|
-
validateQueryComplexity(node, depth = 0) {
|
|
389
|
-
// Check nesting depth
|
|
390
|
-
if (depth > QUERY_LIMITS.MAX_DEPTH) {
|
|
391
|
-
throw new ValidationError('Query too complex', [`Query nesting depth ${depth} exceeds maximum of ${QUERY_LIMITS.MAX_DEPTH}`]);
|
|
392
|
-
}
|
|
393
|
-
// Count terms and operators recursively
|
|
394
|
-
const complexity = this.calculateQueryComplexity(node);
|
|
395
|
-
if (complexity.terms > QUERY_LIMITS.MAX_TERMS) {
|
|
396
|
-
throw new ValidationError('Query too complex', [`Query has ${complexity.terms} terms, exceeds maximum of ${QUERY_LIMITS.MAX_TERMS}`]);
|
|
397
|
-
}
|
|
398
|
-
if (complexity.operators > QUERY_LIMITS.MAX_OPERATORS) {
|
|
399
|
-
throw new ValidationError('Query too complex', [`Query has ${complexity.operators} operators, exceeds maximum of ${QUERY_LIMITS.MAX_OPERATORS}`]);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Calculate query complexity metrics.
|
|
404
|
-
*/
|
|
405
|
-
calculateQueryComplexity(node, depth = 0) {
|
|
406
|
-
switch (node.type) {
|
|
407
|
-
case 'AND':
|
|
408
|
-
case 'OR':
|
|
409
|
-
const childResults = node.children.map(child => this.calculateQueryComplexity(child, depth + 1));
|
|
410
|
-
return {
|
|
411
|
-
terms: childResults.reduce((sum, r) => sum + r.terms, 0),
|
|
412
|
-
operators: childResults.reduce((sum, r) => sum + r.operators, 1), // +1 for current operator
|
|
413
|
-
maxDepth: Math.max(depth, ...childResults.map(r => r.maxDepth)),
|
|
414
|
-
};
|
|
415
|
-
case 'NOT':
|
|
416
|
-
const notResult = this.calculateQueryComplexity(node.child, depth + 1);
|
|
417
|
-
return {
|
|
418
|
-
terms: notResult.terms,
|
|
419
|
-
operators: notResult.operators + 1,
|
|
420
|
-
maxDepth: Math.max(depth, notResult.maxDepth),
|
|
421
|
-
};
|
|
422
|
-
case 'TERM':
|
|
423
|
-
return {
|
|
424
|
-
terms: 1,
|
|
425
|
-
operators: 0,
|
|
426
|
-
maxDepth: depth,
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
//# sourceMappingURL=BooleanSearch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BooleanSearch.js","sourceRoot":"","sources":["../../src/search/BooleanSearch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Early Termination Manager
|
|
3
|
-
*
|
|
4
|
-
* Phase 12 Sprint 4: Manages early termination of hybrid search when
|
|
5
|
-
* results are adequate, executing layers in cost-order for efficiency.
|
|
6
|
-
*
|
|
7
|
-
* @module search/EarlyTerminationManager
|
|
8
|
-
*/
|
|
9
|
-
import type { HybridSearchResult, QueryAnalysis, ReadonlyKnowledgeGraph } from '../types/index.js';
|
|
10
|
-
import type { HybridSearchManager } from './HybridSearchManager.js';
|
|
11
|
-
import type { SearchLayer } from './QueryCostEstimator.js';
|
|
12
|
-
import { QueryCostEstimator } from './QueryCostEstimator.js';
|
|
13
|
-
/**
|
|
14
|
-
* Adequacy check result for a set of search results.
|
|
15
|
-
*/
|
|
16
|
-
export interface AdequacyCheck {
|
|
17
|
-
/** Whether results are adequate */
|
|
18
|
-
adequate: boolean;
|
|
19
|
-
/** Adequacy score (0-1) */
|
|
20
|
-
score: number;
|
|
21
|
-
/** Reasons for the adequacy determination */
|
|
22
|
-
reasons: string[];
|
|
23
|
-
/** Layers that contributed to results */
|
|
24
|
-
contributingLayers: SearchLayer[];
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Options for early termination.
|
|
28
|
-
*/
|
|
29
|
-
export interface EarlyTerminationOptions {
|
|
30
|
-
/** Adequacy threshold (0-1, default: 0.7) */
|
|
31
|
-
adequacyThreshold?: number;
|
|
32
|
-
/** Minimum results required (default: 3) */
|
|
33
|
-
minResults?: number;
|
|
34
|
-
/** Maximum results to collect (default: 20) */
|
|
35
|
-
maxResults?: number;
|
|
36
|
-
/** Whether semantic search is available (default: true) */
|
|
37
|
-
semanticAvailable?: boolean;
|
|
38
|
-
/** Query analysis for smarter adequacy checking */
|
|
39
|
-
analysis?: QueryAnalysis;
|
|
40
|
-
/** Minimum diversity score (0-1, default: 0.3) */
|
|
41
|
-
minDiversity?: number;
|
|
42
|
-
/** Minimum average relevance score (0-1, default: 0.4) */
|
|
43
|
-
minRelevance?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Result from early termination search.
|
|
47
|
-
*/
|
|
48
|
-
export interface EarlyTerminationResult {
|
|
49
|
-
/** Final search results */
|
|
50
|
-
results: HybridSearchResult[];
|
|
51
|
-
/** Layers that were executed (in order) */
|
|
52
|
-
executedLayers: SearchLayer[];
|
|
53
|
-
/** Adequacy check details */
|
|
54
|
-
adequacy: AdequacyCheck;
|
|
55
|
-
/** Whether early termination occurred */
|
|
56
|
-
earlyTerminated: boolean;
|
|
57
|
-
/** Total time in milliseconds */
|
|
58
|
-
executionTimeMs: number;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Early Termination Manager
|
|
62
|
-
*
|
|
63
|
-
* Executes search layers in cost-order (fastest first) and terminates
|
|
64
|
-
* early when results are adequate, saving computation time.
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```typescript
|
|
68
|
-
* const manager = new EarlyTerminationManager(hybridSearch);
|
|
69
|
-
* const result = await manager.searchWithEarlyTermination(
|
|
70
|
-
* graph,
|
|
71
|
-
* 'machine learning',
|
|
72
|
-
* { adequacyThreshold: 0.8, minResults: 5 }
|
|
73
|
-
* );
|
|
74
|
-
*
|
|
75
|
-
* if (result.earlyTerminated) {
|
|
76
|
-
* console.log(`Terminated after ${result.executedLayers.length} layers`);
|
|
77
|
-
* }
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
export declare class EarlyTerminationManager {
|
|
81
|
-
private hybridSearch;
|
|
82
|
-
private costEstimator;
|
|
83
|
-
constructor(hybridSearch: HybridSearchManager, costEstimator?: QueryCostEstimator);
|
|
84
|
-
/**
|
|
85
|
-
* Execute search with early termination support.
|
|
86
|
-
*
|
|
87
|
-
* Executes layers in cost-order and terminates early when results
|
|
88
|
-
* meet the adequacy threshold.
|
|
89
|
-
*
|
|
90
|
-
* @param graph - Knowledge graph to search
|
|
91
|
-
* @param query - Search query
|
|
92
|
-
* @param options - Early termination options
|
|
93
|
-
* @returns Search results with termination details
|
|
94
|
-
*/
|
|
95
|
-
searchWithEarlyTermination(graph: ReadonlyKnowledgeGraph, query: string, options?: EarlyTerminationOptions): Promise<EarlyTerminationResult>;
|
|
96
|
-
/**
|
|
97
|
-
* Execute a single layer search.
|
|
98
|
-
* @private
|
|
99
|
-
*/
|
|
100
|
-
private executeLayerSearch;
|
|
101
|
-
/**
|
|
102
|
-
* Get weight configuration for a specific layer.
|
|
103
|
-
* @private
|
|
104
|
-
*/
|
|
105
|
-
private getLayerWeights;
|
|
106
|
-
/**
|
|
107
|
-
* Check if results are adequate based on configured thresholds.
|
|
108
|
-
*
|
|
109
|
-
* @param results - Current search results
|
|
110
|
-
* @param options - Adequacy options
|
|
111
|
-
* @param executedLayers - Layers that have been executed
|
|
112
|
-
* @returns Adequacy check result
|
|
113
|
-
*/
|
|
114
|
-
checkAdequacy(results: HybridSearchResult[], options: EarlyTerminationOptions, executedLayers: SearchLayer[]): AdequacyCheck;
|
|
115
|
-
/**
|
|
116
|
-
* Calculate diversity score from results.
|
|
117
|
-
* @private
|
|
118
|
-
*/
|
|
119
|
-
private calculateDiversityScore;
|
|
120
|
-
/**
|
|
121
|
-
* Get layers that contributed to results.
|
|
122
|
-
* @private
|
|
123
|
-
*/
|
|
124
|
-
private getContributingLayers;
|
|
125
|
-
/**
|
|
126
|
-
* Calculate adequacy score for a set of results.
|
|
127
|
-
*
|
|
128
|
-
* Standalone method for checking result adequacy without full search.
|
|
129
|
-
*
|
|
130
|
-
* @param results - Results to evaluate
|
|
131
|
-
* @param options - Adequacy options
|
|
132
|
-
* @returns Adequacy score (0-1)
|
|
133
|
-
*/
|
|
134
|
-
calculateAdequacyScore(results: HybridSearchResult[], options?: EarlyTerminationOptions): number;
|
|
135
|
-
/**
|
|
136
|
-
* Get the cost estimator for external use.
|
|
137
|
-
*/
|
|
138
|
-
getCostEstimator(): QueryCostEstimator;
|
|
139
|
-
}
|
|
140
|
-
//# sourceMappingURL=EarlyTerminationManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EarlyTerminationManager.d.ts","sourceRoot":"","sources":["../../src/search/EarlyTerminationManager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yCAAyC;IACzC,kBAAkB,EAAE,WAAW,EAAE,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,2BAA2B;IAC3B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,2CAA2C;IAC3C,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,6BAA6B;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,yCAAyC;IACzC,eAAe,EAAE,OAAO,CAAC;IACzB,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB;AAcD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,uBAAuB;IAIhC,OAAO,CAAC,YAAY;IAHtB,OAAO,CAAC,aAAa,CAAqB;gBAGhC,YAAY,EAAE,mBAAmB,EACzC,aAAa,CAAC,EAAE,kBAAkB;IAKpC;;;;;;;;;;OAUG;IACG,0BAA0B,CAC9B,KAAK,EAAE,sBAAsB,EAC7B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC;IA0ElC;;;OAGG;YACW,kBAAkB;IAoBhC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAevB;;;;;;;OAOG;IACH,aAAa,CACX,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,EAAE,uBAAuB,EAChC,cAAc,EAAE,WAAW,EAAE,GAC5B,aAAa;IAyFhB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAqB/B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;;;;;;;OAQG;IACH,sBAAsB,CACpB,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,GAAE,uBAA4B,GACpC,MAAM;IAKT;;OAEG;IACH,gBAAgB,IAAI,kBAAkB;CAGvC"}
|