@topgunbuild/core 0.4.0 → 0.5.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/dist/index.d.mts +3305 -3
- package/dist/index.d.ts +3305 -3
- package/dist/index.js +5500 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5452 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -1161,7 +1161,7 @@ declare function serialize(data: unknown): Uint8Array;
|
|
|
1161
1161
|
*/
|
|
1162
1162
|
declare function deserialize<T = unknown>(data: Uint8Array | ArrayBuffer): T;
|
|
1163
1163
|
|
|
1164
|
-
type PredicateOp = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'regex' | 'and' | 'or' | 'not';
|
|
1164
|
+
type PredicateOp = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'regex' | 'contains' | 'containsAll' | 'containsAny' | 'and' | 'or' | 'not';
|
|
1165
1165
|
interface PredicateNode {
|
|
1166
1166
|
op: PredicateOp;
|
|
1167
1167
|
attribute?: string;
|
|
@@ -1181,6 +1181,30 @@ declare class Predicates {
|
|
|
1181
1181
|
static and(...predicates: PredicateNode[]): PredicateNode;
|
|
1182
1182
|
static or(...predicates: PredicateNode[]): PredicateNode;
|
|
1183
1183
|
static not(predicate: PredicateNode): PredicateNode;
|
|
1184
|
+
/**
|
|
1185
|
+
* Create a 'contains' predicate for text search.
|
|
1186
|
+
* Matches if attribute value contains the search text.
|
|
1187
|
+
*
|
|
1188
|
+
* @param attribute - Attribute name
|
|
1189
|
+
* @param value - Text to search for
|
|
1190
|
+
*/
|
|
1191
|
+
static contains(attribute: string, value: string): PredicateNode;
|
|
1192
|
+
/**
|
|
1193
|
+
* Create a 'containsAll' predicate for text search.
|
|
1194
|
+
* Matches if attribute value contains ALL search values.
|
|
1195
|
+
*
|
|
1196
|
+
* @param attribute - Attribute name
|
|
1197
|
+
* @param values - Text values that must all be present
|
|
1198
|
+
*/
|
|
1199
|
+
static containsAll(attribute: string, values: string[]): PredicateNode;
|
|
1200
|
+
/**
|
|
1201
|
+
* Create a 'containsAny' predicate for text search.
|
|
1202
|
+
* Matches if attribute value contains ANY search value.
|
|
1203
|
+
*
|
|
1204
|
+
* @param attribute - Attribute name
|
|
1205
|
+
* @param values - Text values, any of which can match
|
|
1206
|
+
*/
|
|
1207
|
+
static containsAny(attribute: string, values: string[]): PredicateNode;
|
|
1184
1208
|
}
|
|
1185
1209
|
declare function evaluatePredicate(predicate: PredicateNode, data: any): boolean;
|
|
1186
1210
|
|
|
@@ -2465,7 +2489,7 @@ declare const MessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
2465
2489
|
keyPattern: z.ZodOptional<z.ZodString>;
|
|
2466
2490
|
}, z.core.$strip>>;
|
|
2467
2491
|
}, z.core.$strip>], "type">;
|
|
2468
|
-
type Query = z.infer<typeof QuerySchema>;
|
|
2492
|
+
type Query$1 = z.infer<typeof QuerySchema>;
|
|
2469
2493
|
type ClientOp = z.infer<typeof ClientOpSchema>;
|
|
2470
2494
|
type Message = z.infer<typeof MessageSchema>;
|
|
2471
2495
|
type PingMessage = z.infer<typeof PingMessageSchema>;
|
|
@@ -2962,4 +2986,3282 @@ type ReplicationProtocolMessage = ReplicationMessage | ReplicationBatchMessage |
|
|
|
2962
2986
|
declare const PARTITION_COUNT = 271;
|
|
2963
2987
|
declare const DEFAULT_BACKUP_COUNT = 1;
|
|
2964
2988
|
|
|
2965
|
-
|
|
2989
|
+
/**
|
|
2990
|
+
* Common types for sorted data structures
|
|
2991
|
+
*/
|
|
2992
|
+
/**
|
|
2993
|
+
* Comparator function for ordering keys
|
|
2994
|
+
*/
|
|
2995
|
+
type Comparator<K> = (a: K, b: K) => number;
|
|
2996
|
+
/**
|
|
2997
|
+
* Options for range queries
|
|
2998
|
+
*/
|
|
2999
|
+
interface RangeOptions {
|
|
3000
|
+
/** Include the lower bound in results (default: true) */
|
|
3001
|
+
fromInclusive?: boolean;
|
|
3002
|
+
/** Include the upper bound in results (default: false) */
|
|
3003
|
+
toInclusive?: boolean;
|
|
3004
|
+
}
|
|
3005
|
+
|
|
3006
|
+
/**
|
|
3007
|
+
* Type-safe wrapper over sorted-btree for use in NavigableIndex
|
|
3008
|
+
*
|
|
3009
|
+
* Provides O(log N) operations for:
|
|
3010
|
+
* - set/get/delete
|
|
3011
|
+
* - range queries
|
|
3012
|
+
* - greaterThan/lessThan queries
|
|
3013
|
+
*/
|
|
3014
|
+
|
|
3015
|
+
/**
|
|
3016
|
+
* A sorted map implementation backed by a B+ tree.
|
|
3017
|
+
* Provides efficient range queries and ordered iteration.
|
|
3018
|
+
*
|
|
3019
|
+
* @template K - Key type (must be comparable)
|
|
3020
|
+
* @template V - Value type
|
|
3021
|
+
*/
|
|
3022
|
+
declare class SortedMap<K, V> {
|
|
3023
|
+
private readonly tree;
|
|
3024
|
+
private readonly comparator;
|
|
3025
|
+
constructor(comparator?: Comparator<K>);
|
|
3026
|
+
/**
|
|
3027
|
+
* Set a key-value pair. Updates existing key if present.
|
|
3028
|
+
* Time complexity: O(log N)
|
|
3029
|
+
*/
|
|
3030
|
+
set(key: K, value: V): this;
|
|
3031
|
+
/**
|
|
3032
|
+
* Get the value for a key.
|
|
3033
|
+
* Time complexity: O(log N)
|
|
3034
|
+
*/
|
|
3035
|
+
get(key: K): V | undefined;
|
|
3036
|
+
/**
|
|
3037
|
+
* Delete a key from the map.
|
|
3038
|
+
* Time complexity: O(log N)
|
|
3039
|
+
* @returns true if the key existed and was deleted
|
|
3040
|
+
*/
|
|
3041
|
+
delete(key: K): boolean;
|
|
3042
|
+
/**
|
|
3043
|
+
* Check if a key exists in the map.
|
|
3044
|
+
* Time complexity: O(log N)
|
|
3045
|
+
*/
|
|
3046
|
+
has(key: K): boolean;
|
|
3047
|
+
/**
|
|
3048
|
+
* Get the number of entries in the map.
|
|
3049
|
+
*/
|
|
3050
|
+
get size(): number;
|
|
3051
|
+
/**
|
|
3052
|
+
* Check if the map is empty.
|
|
3053
|
+
*/
|
|
3054
|
+
get isEmpty(): boolean;
|
|
3055
|
+
/**
|
|
3056
|
+
* Get the minimum key in the map.
|
|
3057
|
+
* Time complexity: O(log N)
|
|
3058
|
+
*/
|
|
3059
|
+
minKey(): K | undefined;
|
|
3060
|
+
/**
|
|
3061
|
+
* Get the maximum key in the map.
|
|
3062
|
+
* Time complexity: O(log N)
|
|
3063
|
+
*/
|
|
3064
|
+
maxKey(): K | undefined;
|
|
3065
|
+
/**
|
|
3066
|
+
* Iterate over entries in a range [from, to).
|
|
3067
|
+
* Time complexity: O(log N + K) where K is the number of results
|
|
3068
|
+
*
|
|
3069
|
+
* @param from - Lower bound
|
|
3070
|
+
* @param to - Upper bound
|
|
3071
|
+
* @param options - Range options for inclusive/exclusive bounds
|
|
3072
|
+
*/
|
|
3073
|
+
range(from: K, to: K, options?: RangeOptions): IterableIterator<[K, V]>;
|
|
3074
|
+
/**
|
|
3075
|
+
* Iterate over entries where key > value (or >= if inclusive).
|
|
3076
|
+
* Time complexity: O(log N + K) where K is the number of results
|
|
3077
|
+
*
|
|
3078
|
+
* @param key - Lower bound
|
|
3079
|
+
* @param inclusive - Include the bound in results (default: false)
|
|
3080
|
+
*/
|
|
3081
|
+
greaterThan(key: K, inclusive?: boolean): IterableIterator<[K, V]>;
|
|
3082
|
+
/**
|
|
3083
|
+
* Iterate over entries where key < value (or <= if inclusive).
|
|
3084
|
+
* Time complexity: O(log N + K) where K is the number of results
|
|
3085
|
+
*
|
|
3086
|
+
* Note: This method iterates from the beginning of the tree.
|
|
3087
|
+
* The O(log N) component is for finding the upper bound,
|
|
3088
|
+
* and O(K) is for yielding K results.
|
|
3089
|
+
*
|
|
3090
|
+
* @param key - Upper bound
|
|
3091
|
+
* @param inclusive - Include the bound in results (default: false)
|
|
3092
|
+
*/
|
|
3093
|
+
lessThan(key: K, inclusive?: boolean): IterableIterator<[K, V]>;
|
|
3094
|
+
/**
|
|
3095
|
+
* Iterate over all entries in sorted order.
|
|
3096
|
+
* Time complexity: O(N)
|
|
3097
|
+
*/
|
|
3098
|
+
entries(): IterableIterator<[K, V]>;
|
|
3099
|
+
/**
|
|
3100
|
+
* Iterate over all keys in sorted order.
|
|
3101
|
+
* Time complexity: O(N)
|
|
3102
|
+
*/
|
|
3103
|
+
keys(): IterableIterator<K>;
|
|
3104
|
+
/**
|
|
3105
|
+
* Iterate over all values in sorted order.
|
|
3106
|
+
* Time complexity: O(N)
|
|
3107
|
+
*/
|
|
3108
|
+
values(): IterableIterator<V>;
|
|
3109
|
+
/**
|
|
3110
|
+
* Iterate over entries in reverse sorted order.
|
|
3111
|
+
* Time complexity: O(N)
|
|
3112
|
+
*/
|
|
3113
|
+
entriesReversed(): IterableIterator<[K, V]>;
|
|
3114
|
+
/**
|
|
3115
|
+
* Remove all entries from the map.
|
|
3116
|
+
*/
|
|
3117
|
+
clear(): void;
|
|
3118
|
+
/**
|
|
3119
|
+
* Execute a callback for each entry in sorted order.
|
|
3120
|
+
*/
|
|
3121
|
+
forEach(callback: (value: V, key: K, map: this) => void): void;
|
|
3122
|
+
/**
|
|
3123
|
+
* Create a new SortedMap from entries.
|
|
3124
|
+
*/
|
|
3125
|
+
static from<K, V>(entries: Iterable<[K, V]>, comparator?: Comparator<K>): SortedMap<K, V>;
|
|
3126
|
+
/**
|
|
3127
|
+
* Get or set a value using a factory function.
|
|
3128
|
+
* If the key doesn't exist, the factory is called to create the value.
|
|
3129
|
+
*/
|
|
3130
|
+
getOrSet(key: K, factory: () => V): V;
|
|
3131
|
+
/**
|
|
3132
|
+
* Update a value if the key exists.
|
|
3133
|
+
* @returns true if the key existed and was updated
|
|
3134
|
+
*/
|
|
3135
|
+
update(key: K, updater: (value: V) => V): boolean;
|
|
3136
|
+
/**
|
|
3137
|
+
* Get the entry at a specific index (0-based).
|
|
3138
|
+
* Time complexity: O(N) - requires linear scan from the beginning.
|
|
3139
|
+
* Note: B+ trees do not support O(log N) index-based access.
|
|
3140
|
+
*/
|
|
3141
|
+
at(index: number): [K, V] | undefined;
|
|
3142
|
+
/**
|
|
3143
|
+
* Find the greatest key less than the given key.
|
|
3144
|
+
* Time complexity: O(log N)
|
|
3145
|
+
*/
|
|
3146
|
+
lowerKey(key: K): K | undefined;
|
|
3147
|
+
/**
|
|
3148
|
+
* Find the greatest key less than or equal to the given key.
|
|
3149
|
+
* Time complexity: O(log N)
|
|
3150
|
+
*/
|
|
3151
|
+
floorKey(key: K): K | undefined;
|
|
3152
|
+
/**
|
|
3153
|
+
* Find the least key greater than the given key.
|
|
3154
|
+
* Time complexity: O(log N)
|
|
3155
|
+
*/
|
|
3156
|
+
higherKey(key: K): K | undefined;
|
|
3157
|
+
/**
|
|
3158
|
+
* Find the least key greater than or equal to the given key.
|
|
3159
|
+
* Time complexity: O(log N)
|
|
3160
|
+
*/
|
|
3161
|
+
ceilingKey(key: K): K | undefined;
|
|
3162
|
+
/**
|
|
3163
|
+
* Make the map iterable.
|
|
3164
|
+
*/
|
|
3165
|
+
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
/**
|
|
3169
|
+
* Attribute System for Query Engine
|
|
3170
|
+
*
|
|
3171
|
+
* Attributes extract value(s) from records for indexing and querying.
|
|
3172
|
+
* Inspired by CQEngine Attribute<O, A>.
|
|
3173
|
+
*
|
|
3174
|
+
* @module query/Attribute
|
|
3175
|
+
*/
|
|
3176
|
+
/**
|
|
3177
|
+
* Attribute extracts value(s) from a record.
|
|
3178
|
+
* V = Record value type, A = Attribute value type
|
|
3179
|
+
*/
|
|
3180
|
+
interface Attribute<V, A> {
|
|
3181
|
+
/** Unique attribute name */
|
|
3182
|
+
readonly name: string;
|
|
3183
|
+
/** Attribute value type */
|
|
3184
|
+
readonly type: 'simple' | 'multi';
|
|
3185
|
+
/**
|
|
3186
|
+
* Extract value from record.
|
|
3187
|
+
* Returns undefined if attribute doesn't exist.
|
|
3188
|
+
*/
|
|
3189
|
+
getValue(record: V): A | undefined;
|
|
3190
|
+
/**
|
|
3191
|
+
* For multi-value attributes, returns all values.
|
|
3192
|
+
* For simple attributes, returns single-element array.
|
|
3193
|
+
*/
|
|
3194
|
+
getValues(record: V): A[];
|
|
3195
|
+
}
|
|
3196
|
+
/**
|
|
3197
|
+
* Attribute that returns exactly one value per record.
|
|
3198
|
+
*/
|
|
3199
|
+
declare class SimpleAttribute<V, A> implements Attribute<V, A> {
|
|
3200
|
+
readonly name: string;
|
|
3201
|
+
private readonly extractor;
|
|
3202
|
+
readonly type: "simple";
|
|
3203
|
+
constructor(name: string, extractor: (record: V) => A | undefined);
|
|
3204
|
+
getValue(record: V): A | undefined;
|
|
3205
|
+
getValues(record: V): A[];
|
|
3206
|
+
}
|
|
3207
|
+
/**
|
|
3208
|
+
* Factory function for SimpleAttribute.
|
|
3209
|
+
*/
|
|
3210
|
+
declare function simpleAttribute<V, A>(name: string, extractor: (record: V) => A | undefined): SimpleAttribute<V, A>;
|
|
3211
|
+
/**
|
|
3212
|
+
* Attribute that returns zero or more values per record.
|
|
3213
|
+
* Example: tags, categories, roles.
|
|
3214
|
+
*/
|
|
3215
|
+
declare class MultiValueAttribute<V, A> implements Attribute<V, A> {
|
|
3216
|
+
readonly name: string;
|
|
3217
|
+
private readonly extractor;
|
|
3218
|
+
readonly type: "multi";
|
|
3219
|
+
constructor(name: string, extractor: (record: V) => A[]);
|
|
3220
|
+
getValue(record: V): A | undefined;
|
|
3221
|
+
getValues(record: V): A[];
|
|
3222
|
+
}
|
|
3223
|
+
/**
|
|
3224
|
+
* Factory function for MultiValueAttribute.
|
|
3225
|
+
*/
|
|
3226
|
+
declare function multiAttribute<V, A>(name: string, extractor: (record: V) => A[]): MultiValueAttribute<V, A>;
|
|
3227
|
+
|
|
3228
|
+
/**
|
|
3229
|
+
* ResultSet Interface
|
|
3230
|
+
*
|
|
3231
|
+
* Lazy result set from index queries.
|
|
3232
|
+
* Inspired by CQEngine ResultSet<O>.
|
|
3233
|
+
*
|
|
3234
|
+
* @module query/resultset/ResultSet
|
|
3235
|
+
*/
|
|
3236
|
+
/**
|
|
3237
|
+
* Lazy result set from index query.
|
|
3238
|
+
* K = record key type
|
|
3239
|
+
*/
|
|
3240
|
+
interface ResultSet<K> {
|
|
3241
|
+
/**
|
|
3242
|
+
* Iterate over matching keys.
|
|
3243
|
+
* Lazy evaluation where possible.
|
|
3244
|
+
*/
|
|
3245
|
+
[Symbol.iterator](): Iterator<K>;
|
|
3246
|
+
/**
|
|
3247
|
+
* Cost of retrieving these results.
|
|
3248
|
+
* Used by QueryOptimizer for index selection.
|
|
3249
|
+
*/
|
|
3250
|
+
getRetrievalCost(): number;
|
|
3251
|
+
/**
|
|
3252
|
+
* Estimated cost of merging/processing these results.
|
|
3253
|
+
* Usually based on result count.
|
|
3254
|
+
*/
|
|
3255
|
+
getMergeCost(): number;
|
|
3256
|
+
/**
|
|
3257
|
+
* Check if result set contains key.
|
|
3258
|
+
*/
|
|
3259
|
+
contains(key: K): boolean;
|
|
3260
|
+
/**
|
|
3261
|
+
* Get result count.
|
|
3262
|
+
* May require iteration for lazy result sets.
|
|
3263
|
+
*/
|
|
3264
|
+
size(): number;
|
|
3265
|
+
/**
|
|
3266
|
+
* Materialize to array.
|
|
3267
|
+
*/
|
|
3268
|
+
toArray(): K[];
|
|
3269
|
+
/**
|
|
3270
|
+
* Check if empty.
|
|
3271
|
+
*/
|
|
3272
|
+
isEmpty(): boolean;
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
/**
|
|
3276
|
+
* Base Index Interface
|
|
3277
|
+
*
|
|
3278
|
+
* Defines the contract for all index types in the Query Engine.
|
|
3279
|
+
* Inspired by CQEngine Index hierarchy.
|
|
3280
|
+
*
|
|
3281
|
+
* @module query/indexes/types
|
|
3282
|
+
*/
|
|
3283
|
+
|
|
3284
|
+
/**
|
|
3285
|
+
* Base interface for all indexes.
|
|
3286
|
+
* K = record key type, V = record value type, A = attribute value type
|
|
3287
|
+
*/
|
|
3288
|
+
interface Index<K, V, A = unknown> {
|
|
3289
|
+
/** Attribute this index is built on */
|
|
3290
|
+
readonly attribute: Attribute<V, A>;
|
|
3291
|
+
/** Index type identifier */
|
|
3292
|
+
readonly type: 'hash' | 'navigable' | 'compound' | 'standing' | 'inverted';
|
|
3293
|
+
/**
|
|
3294
|
+
* Cost of retrieving results from this index.
|
|
3295
|
+
* Lower is better. Used by QueryOptimizer.
|
|
3296
|
+
* CQEngine values: Standing=10, Compound=20, Hash=30, Navigable=40
|
|
3297
|
+
*/
|
|
3298
|
+
getRetrievalCost(): number;
|
|
3299
|
+
/**
|
|
3300
|
+
* Check if this index supports the given query type.
|
|
3301
|
+
*/
|
|
3302
|
+
supportsQuery(queryType: string): boolean;
|
|
3303
|
+
/**
|
|
3304
|
+
* Retrieve candidate keys matching the query.
|
|
3305
|
+
*/
|
|
3306
|
+
retrieve(query: IndexQuery<A>): ResultSet<K>;
|
|
3307
|
+
/**
|
|
3308
|
+
* Add a record to the index.
|
|
3309
|
+
*/
|
|
3310
|
+
add(key: K, record: V): void;
|
|
3311
|
+
/**
|
|
3312
|
+
* Remove a record from the index.
|
|
3313
|
+
*/
|
|
3314
|
+
remove(key: K, record: V): void;
|
|
3315
|
+
/**
|
|
3316
|
+
* Update a record in the index.
|
|
3317
|
+
*/
|
|
3318
|
+
update(key: K, oldRecord: V, newRecord: V): void;
|
|
3319
|
+
/**
|
|
3320
|
+
* Clear all entries from the index.
|
|
3321
|
+
*/
|
|
3322
|
+
clear(): void;
|
|
3323
|
+
/**
|
|
3324
|
+
* Get statistics about the index.
|
|
3325
|
+
*/
|
|
3326
|
+
getStats(): IndexStats;
|
|
3327
|
+
}
|
|
3328
|
+
/**
|
|
3329
|
+
* Query parameters for index retrieval.
|
|
3330
|
+
*/
|
|
3331
|
+
interface IndexQuery<A> {
|
|
3332
|
+
/** Query type */
|
|
3333
|
+
type: 'equal' | 'in' | 'has' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'contains' | 'containsAll' | 'containsAny';
|
|
3334
|
+
/** Value for equality queries */
|
|
3335
|
+
value?: A;
|
|
3336
|
+
/** Values for 'in' queries */
|
|
3337
|
+
values?: A[];
|
|
3338
|
+
/** Lower bound for range queries */
|
|
3339
|
+
from?: A;
|
|
3340
|
+
/** Upper bound for range queries */
|
|
3341
|
+
to?: A;
|
|
3342
|
+
/** Include lower bound (default: true) */
|
|
3343
|
+
fromInclusive?: boolean;
|
|
3344
|
+
/** Include upper bound (default: false) */
|
|
3345
|
+
toInclusive?: boolean;
|
|
3346
|
+
}
|
|
3347
|
+
/**
|
|
3348
|
+
* Statistics about an index.
|
|
3349
|
+
*/
|
|
3350
|
+
interface IndexStats {
|
|
3351
|
+
/** Number of distinct attribute values indexed */
|
|
3352
|
+
distinctValues: number;
|
|
3353
|
+
/** Total number of record references */
|
|
3354
|
+
totalEntries: number;
|
|
3355
|
+
/** Average entries per distinct value */
|
|
3356
|
+
avgEntriesPerValue: number;
|
|
3357
|
+
}
|
|
3358
|
+
|
|
3359
|
+
/**
|
|
3360
|
+
* HashIndex Implementation
|
|
3361
|
+
*
|
|
3362
|
+
* Hash-based index for O(1) equality lookups.
|
|
3363
|
+
* Supports: equal, in, has queries.
|
|
3364
|
+
*
|
|
3365
|
+
* Structure: Map<AttributeValue, Set<RecordKey>>
|
|
3366
|
+
*
|
|
3367
|
+
* CQEngine Reference: HashIndex.java (retrieval cost: 30)
|
|
3368
|
+
*
|
|
3369
|
+
* @module query/indexes/HashIndex
|
|
3370
|
+
*/
|
|
3371
|
+
|
|
3372
|
+
/**
|
|
3373
|
+
* Hash-based index for O(1) equality lookups.
|
|
3374
|
+
*
|
|
3375
|
+
* K = record key type, V = record value type, A = attribute value type
|
|
3376
|
+
*/
|
|
3377
|
+
declare class HashIndex<K, V, A> implements Index<K, V, A> {
|
|
3378
|
+
readonly attribute: Attribute<V, A>;
|
|
3379
|
+
readonly type: "hash";
|
|
3380
|
+
/** Map from attribute value to set of record keys */
|
|
3381
|
+
private data;
|
|
3382
|
+
/** Set of all keys with non-null attribute value */
|
|
3383
|
+
private allKeys;
|
|
3384
|
+
private static readonly RETRIEVAL_COST;
|
|
3385
|
+
private static readonly SUPPORTED_QUERIES;
|
|
3386
|
+
constructor(attribute: Attribute<V, A>);
|
|
3387
|
+
getRetrievalCost(): number;
|
|
3388
|
+
supportsQuery(queryType: string): boolean;
|
|
3389
|
+
retrieve(query: IndexQuery<A>): ResultSet<K>;
|
|
3390
|
+
private retrieveEqual;
|
|
3391
|
+
private retrieveIn;
|
|
3392
|
+
private retrieveHas;
|
|
3393
|
+
add(key: K, record: V): void;
|
|
3394
|
+
remove(key: K, record: V): void;
|
|
3395
|
+
update(key: K, oldRecord: V, newRecord: V): void;
|
|
3396
|
+
clear(): void;
|
|
3397
|
+
getStats(): IndexStats;
|
|
3398
|
+
private arraysEqual;
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
/**
|
|
3402
|
+
* NavigableIndex Implementation
|
|
3403
|
+
*
|
|
3404
|
+
* Sorted index for O(log N) range queries.
|
|
3405
|
+
* Supports: equal, in, has, gt, gte, lt, lte, between queries.
|
|
3406
|
+
*
|
|
3407
|
+
* Structure: SortedMap<AttributeValue, Set<RecordKey>>
|
|
3408
|
+
*
|
|
3409
|
+
* CQEngine Reference: NavigableIndex.java (retrieval cost: 40)
|
|
3410
|
+
*
|
|
3411
|
+
* @module query/indexes/NavigableIndex
|
|
3412
|
+
*/
|
|
3413
|
+
|
|
3414
|
+
/**
|
|
3415
|
+
* Sorted index for O(log N) range queries.
|
|
3416
|
+
*
|
|
3417
|
+
* K = record key type, V = record value type, A = attribute value type (must be orderable)
|
|
3418
|
+
*/
|
|
3419
|
+
declare class NavigableIndex<K, V, A extends string | number> implements Index<K, V, A> {
|
|
3420
|
+
readonly attribute: Attribute<V, A>;
|
|
3421
|
+
readonly type: "navigable";
|
|
3422
|
+
/** Sorted map from attribute value to set of record keys */
|
|
3423
|
+
private data;
|
|
3424
|
+
/** Set of all keys with non-null attribute value */
|
|
3425
|
+
private allKeys;
|
|
3426
|
+
/** Retrieval cost as per CQEngine cost model */
|
|
3427
|
+
private static readonly RETRIEVAL_COST;
|
|
3428
|
+
/** Supported query types */
|
|
3429
|
+
private static readonly SUPPORTED_QUERIES;
|
|
3430
|
+
/**
|
|
3431
|
+
* Create a NavigableIndex.
|
|
3432
|
+
*
|
|
3433
|
+
* @param attribute - Attribute to index
|
|
3434
|
+
* @param comparator - Optional custom comparator for ordering
|
|
3435
|
+
*/
|
|
3436
|
+
constructor(attribute: Attribute<V, A>, comparator?: Comparator<A>);
|
|
3437
|
+
getRetrievalCost(): number;
|
|
3438
|
+
supportsQuery(queryType: string): boolean;
|
|
3439
|
+
retrieve(query: IndexQuery<A>): ResultSet<K>;
|
|
3440
|
+
private retrieveEqual;
|
|
3441
|
+
private retrieveIn;
|
|
3442
|
+
private retrieveHas;
|
|
3443
|
+
private retrieveGreaterThan;
|
|
3444
|
+
private retrieveLessThan;
|
|
3445
|
+
private retrieveBetween;
|
|
3446
|
+
private iterateGreaterThan;
|
|
3447
|
+
private iterateLessThan;
|
|
3448
|
+
private iterateBetween;
|
|
3449
|
+
/**
|
|
3450
|
+
* Estimate size for gt/gte queries.
|
|
3451
|
+
* Uses rough estimate: assume uniform distribution, return half.
|
|
3452
|
+
*/
|
|
3453
|
+
private estimateGreaterThanSize;
|
|
3454
|
+
/**
|
|
3455
|
+
* Estimate size for lt/lte queries.
|
|
3456
|
+
* Uses rough estimate: assume uniform distribution, return half.
|
|
3457
|
+
*/
|
|
3458
|
+
private estimateLessThanSize;
|
|
3459
|
+
/**
|
|
3460
|
+
* Estimate size for between queries.
|
|
3461
|
+
* Uses rough estimate: assume uniform distribution, return quarter.
|
|
3462
|
+
*/
|
|
3463
|
+
private estimateBetweenSize;
|
|
3464
|
+
add(key: K, record: V): void;
|
|
3465
|
+
remove(key: K, record: V): void;
|
|
3466
|
+
update(key: K, oldRecord: V, newRecord: V): void;
|
|
3467
|
+
clear(): void;
|
|
3468
|
+
getStats(): IndexStats;
|
|
3469
|
+
private arraysEqual;
|
|
3470
|
+
/**
|
|
3471
|
+
* Get the minimum indexed value.
|
|
3472
|
+
* Useful for debugging and range estimation.
|
|
3473
|
+
*/
|
|
3474
|
+
getMinValue(): A | undefined;
|
|
3475
|
+
/**
|
|
3476
|
+
* Get the maximum indexed value.
|
|
3477
|
+
* Useful for debugging and range estimation.
|
|
3478
|
+
*/
|
|
3479
|
+
getMaxValue(): A | undefined;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
/**
|
|
3483
|
+
* Fallback index that performs full scan.
|
|
3484
|
+
* Used when no suitable index exists for a query.
|
|
3485
|
+
*
|
|
3486
|
+
* K = record key type, V = record value type
|
|
3487
|
+
*/
|
|
3488
|
+
declare class FallbackIndex<K, V> implements Index<K, V, unknown> {
|
|
3489
|
+
private readonly getAllKeys;
|
|
3490
|
+
private readonly getRecord;
|
|
3491
|
+
private readonly matchesPredicate;
|
|
3492
|
+
readonly type: "hash";
|
|
3493
|
+
/** Wildcard attribute for fallback */
|
|
3494
|
+
readonly attribute: SimpleAttribute<V, unknown>;
|
|
3495
|
+
/** Maximum retrieval cost ensures this is only used as fallback */
|
|
3496
|
+
private static readonly RETRIEVAL_COST;
|
|
3497
|
+
/**
|
|
3498
|
+
* Create a FallbackIndex.
|
|
3499
|
+
*
|
|
3500
|
+
* @param getAllKeys - Function to get all keys in the collection
|
|
3501
|
+
* @param getRecord - Function to get a record by key
|
|
3502
|
+
* @param matchesPredicate - Function to check if a record matches a query
|
|
3503
|
+
*/
|
|
3504
|
+
constructor(getAllKeys: () => Iterable<K>, getRecord: (key: K) => V | undefined, matchesPredicate: (record: V, query: IndexQuery<unknown>) => boolean);
|
|
3505
|
+
getRetrievalCost(): number;
|
|
3506
|
+
/**
|
|
3507
|
+
* Supports any query type via full scan.
|
|
3508
|
+
*/
|
|
3509
|
+
supportsQuery(): boolean;
|
|
3510
|
+
/**
|
|
3511
|
+
* Retrieve by performing full scan and applying predicate.
|
|
3512
|
+
*/
|
|
3513
|
+
retrieve(query: IndexQuery<unknown>): ResultSet<K>;
|
|
3514
|
+
add(): void;
|
|
3515
|
+
remove(): void;
|
|
3516
|
+
update(): void;
|
|
3517
|
+
clear(): void;
|
|
3518
|
+
getStats(): IndexStats;
|
|
3519
|
+
}
|
|
3520
|
+
/**
|
|
3521
|
+
* Factory to create predicate matcher from query.
|
|
3522
|
+
* Used by FallbackIndex to evaluate queries against records.
|
|
3523
|
+
*
|
|
3524
|
+
* @param getAttribute - Function to get attribute value from record
|
|
3525
|
+
*/
|
|
3526
|
+
declare function createPredicateMatcher<V>(getAttribute: (record: V, attrName: string) => unknown): (record: V, query: IndexQuery<unknown>) => boolean;
|
|
3527
|
+
|
|
3528
|
+
/**
|
|
3529
|
+
* Query Types and Plan Types for Query Engine
|
|
3530
|
+
*
|
|
3531
|
+
* Defines query node types for the cost-based optimizer
|
|
3532
|
+
* and execution plan types.
|
|
3533
|
+
*
|
|
3534
|
+
* @module query/QueryTypes
|
|
3535
|
+
*/
|
|
3536
|
+
|
|
3537
|
+
/**
|
|
3538
|
+
* Base query node interface.
|
|
3539
|
+
* Compatible with existing PredicateNode from predicate.ts
|
|
3540
|
+
*/
|
|
3541
|
+
interface QueryNode {
|
|
3542
|
+
type: string;
|
|
3543
|
+
}
|
|
3544
|
+
/**
|
|
3545
|
+
* Simple query node for attribute-based conditions.
|
|
3546
|
+
*/
|
|
3547
|
+
interface SimpleQueryNode extends QueryNode {
|
|
3548
|
+
type: 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'like' | 'regex' | 'in' | 'has' | 'contains' | 'containsAll' | 'containsAny';
|
|
3549
|
+
attribute: string;
|
|
3550
|
+
value?: unknown;
|
|
3551
|
+
values?: unknown[];
|
|
3552
|
+
/** For 'between' queries: lower bound */
|
|
3553
|
+
from?: unknown;
|
|
3554
|
+
/** For 'between' queries: upper bound */
|
|
3555
|
+
to?: unknown;
|
|
3556
|
+
/** For 'between' queries: include lower bound (default: true) */
|
|
3557
|
+
fromInclusive?: boolean;
|
|
3558
|
+
/** For 'between' queries: include upper bound (default: false) */
|
|
3559
|
+
toInclusive?: boolean;
|
|
3560
|
+
}
|
|
3561
|
+
/**
|
|
3562
|
+
* Logical query node for combining conditions.
|
|
3563
|
+
*/
|
|
3564
|
+
interface LogicalQueryNode {
|
|
3565
|
+
type: 'and' | 'or' | 'not';
|
|
3566
|
+
children?: Query[];
|
|
3567
|
+
child?: Query;
|
|
3568
|
+
}
|
|
3569
|
+
/**
|
|
3570
|
+
* Union type for all query types.
|
|
3571
|
+
*/
|
|
3572
|
+
type Query = SimpleQueryNode | LogicalQueryNode;
|
|
3573
|
+
/**
|
|
3574
|
+
* Query execution options for sort/limit/offset.
|
|
3575
|
+
*/
|
|
3576
|
+
interface QueryOptions {
|
|
3577
|
+
/** Sort by field(s): field name -> direction */
|
|
3578
|
+
sort?: Record<string, 'asc' | 'desc'>;
|
|
3579
|
+
/** Maximum number of results to return */
|
|
3580
|
+
limit?: number;
|
|
3581
|
+
/** Number of results to skip */
|
|
3582
|
+
offset?: number;
|
|
3583
|
+
}
|
|
3584
|
+
/**
|
|
3585
|
+
* Execution plan step.
|
|
3586
|
+
* Represents a single operation in the query execution plan.
|
|
3587
|
+
*/
|
|
3588
|
+
type PlanStep = IndexScanStep | FullScanStep | IntersectionStep | UnionStep | FilterStep | NotStep;
|
|
3589
|
+
/**
|
|
3590
|
+
* Index scan step - retrieves from an index.
|
|
3591
|
+
*/
|
|
3592
|
+
interface IndexScanStep {
|
|
3593
|
+
type: 'index-scan';
|
|
3594
|
+
index: Index<unknown, unknown, unknown>;
|
|
3595
|
+
query: IndexQuery<unknown>;
|
|
3596
|
+
}
|
|
3597
|
+
/**
|
|
3598
|
+
* Full scan step - scans all records.
|
|
3599
|
+
*/
|
|
3600
|
+
interface FullScanStep {
|
|
3601
|
+
type: 'full-scan';
|
|
3602
|
+
predicate: Query;
|
|
3603
|
+
}
|
|
3604
|
+
/**
|
|
3605
|
+
* Intersection step - AND of multiple result sets.
|
|
3606
|
+
*/
|
|
3607
|
+
interface IntersectionStep {
|
|
3608
|
+
type: 'intersection';
|
|
3609
|
+
steps: PlanStep[];
|
|
3610
|
+
}
|
|
3611
|
+
/**
|
|
3612
|
+
* Union step - OR of multiple result sets.
|
|
3613
|
+
*/
|
|
3614
|
+
interface UnionStep {
|
|
3615
|
+
type: 'union';
|
|
3616
|
+
steps: PlanStep[];
|
|
3617
|
+
}
|
|
3618
|
+
/**
|
|
3619
|
+
* Filter step - applies predicate to source results.
|
|
3620
|
+
*/
|
|
3621
|
+
interface FilterStep {
|
|
3622
|
+
type: 'filter';
|
|
3623
|
+
source: PlanStep;
|
|
3624
|
+
predicate: Query;
|
|
3625
|
+
}
|
|
3626
|
+
/**
|
|
3627
|
+
* NOT step - negation (all keys minus matching keys).
|
|
3628
|
+
*/
|
|
3629
|
+
interface NotStep {
|
|
3630
|
+
type: 'not';
|
|
3631
|
+
source: PlanStep;
|
|
3632
|
+
allKeys: () => Set<unknown>;
|
|
3633
|
+
}
|
|
3634
|
+
/**
|
|
3635
|
+
* Complete query execution plan.
|
|
3636
|
+
*/
|
|
3637
|
+
interface QueryPlan {
|
|
3638
|
+
/** Root execution step */
|
|
3639
|
+
root: PlanStep;
|
|
3640
|
+
/** Estimated execution cost */
|
|
3641
|
+
estimatedCost: number;
|
|
3642
|
+
/** Whether any index is used */
|
|
3643
|
+
usesIndexes: boolean;
|
|
3644
|
+
/** Whether sort can use index order */
|
|
3645
|
+
indexedSort?: boolean;
|
|
3646
|
+
/** Sort configuration */
|
|
3647
|
+
sort?: {
|
|
3648
|
+
field: string;
|
|
3649
|
+
direction: 'asc' | 'desc';
|
|
3650
|
+
};
|
|
3651
|
+
/** Limit configuration */
|
|
3652
|
+
limit?: number;
|
|
3653
|
+
/** Offset configuration */
|
|
3654
|
+
offset?: number;
|
|
3655
|
+
}
|
|
3656
|
+
/**
|
|
3657
|
+
* Check if a query is a simple query node.
|
|
3658
|
+
*/
|
|
3659
|
+
declare function isSimpleQuery(query: Query): query is SimpleQueryNode;
|
|
3660
|
+
/**
|
|
3661
|
+
* Check if a query is a logical query node.
|
|
3662
|
+
*/
|
|
3663
|
+
declare function isLogicalQuery(query: Query): query is LogicalQueryNode;
|
|
3664
|
+
|
|
3665
|
+
/**
|
|
3666
|
+
* StandingQueryIndex Implementation
|
|
3667
|
+
*
|
|
3668
|
+
* Pre-computed index for a specific query.
|
|
3669
|
+
* Maintains result set incrementally as data changes.
|
|
3670
|
+
*
|
|
3671
|
+
* Lowest retrieval cost (10) - O(1) query execution.
|
|
3672
|
+
* Critical for Live Queries in TopGun where the same query
|
|
3673
|
+
* is executed repeatedly on every data change.
|
|
3674
|
+
*
|
|
3675
|
+
* CQEngine Reference: StandingQueryIndex.java (retrieval cost: 10)
|
|
3676
|
+
*
|
|
3677
|
+
* @module query/indexes/StandingQueryIndex
|
|
3678
|
+
*/
|
|
3679
|
+
|
|
3680
|
+
/**
|
|
3681
|
+
* Change type for standing query updates.
|
|
3682
|
+
*/
|
|
3683
|
+
type StandingQueryChange = 'added' | 'removed' | 'updated' | 'unchanged';
|
|
3684
|
+
/**
|
|
3685
|
+
* Options for creating a StandingQueryIndex.
|
|
3686
|
+
*/
|
|
3687
|
+
interface StandingQueryIndexOptions<K, V> {
|
|
3688
|
+
/** Query this index answers */
|
|
3689
|
+
query: Query;
|
|
3690
|
+
/** Function to get record by key (optional, for validation) */
|
|
3691
|
+
getRecord?: (key: K) => V | undefined;
|
|
3692
|
+
}
|
|
3693
|
+
/**
|
|
3694
|
+
* Pre-computed index for a specific query.
|
|
3695
|
+
* Maintains result set incrementally as data changes.
|
|
3696
|
+
*
|
|
3697
|
+
* K = record key type, V = record value type
|
|
3698
|
+
*/
|
|
3699
|
+
declare class StandingQueryIndex<K, V> implements Index<K, V, unknown> {
|
|
3700
|
+
readonly type: "standing";
|
|
3701
|
+
/**
|
|
3702
|
+
* Wildcard attribute - StandingQueryIndex doesn't index by attribute,
|
|
3703
|
+
* it indexes by query match.
|
|
3704
|
+
*/
|
|
3705
|
+
readonly attribute: Attribute<V, unknown>;
|
|
3706
|
+
/** Pre-computed result set */
|
|
3707
|
+
private results;
|
|
3708
|
+
/** Query this index answers */
|
|
3709
|
+
private readonly query;
|
|
3710
|
+
/** Record accessor (optional) */
|
|
3711
|
+
private readonly getRecord?;
|
|
3712
|
+
/** Retrieval cost - lowest of all index types */
|
|
3713
|
+
private static readonly RETRIEVAL_COST;
|
|
3714
|
+
constructor(options: StandingQueryIndexOptions<K, V>);
|
|
3715
|
+
/**
|
|
3716
|
+
* Get the query this index answers.
|
|
3717
|
+
*/
|
|
3718
|
+
getQuery(): Query;
|
|
3719
|
+
/**
|
|
3720
|
+
* Check if this index answers the given query.
|
|
3721
|
+
*/
|
|
3722
|
+
answersQuery(query: Query): boolean;
|
|
3723
|
+
getRetrievalCost(): number;
|
|
3724
|
+
supportsQuery(_queryType: string): boolean;
|
|
3725
|
+
retrieve(_query: IndexQuery<unknown>): ResultSet<K>;
|
|
3726
|
+
/**
|
|
3727
|
+
* Get current result set (for live query updates).
|
|
3728
|
+
* Returns a copy to avoid external mutation.
|
|
3729
|
+
*/
|
|
3730
|
+
getResults(): Set<K>;
|
|
3731
|
+
/**
|
|
3732
|
+
* Get result count.
|
|
3733
|
+
*/
|
|
3734
|
+
getResultCount(): number;
|
|
3735
|
+
/**
|
|
3736
|
+
* Check if key is in results.
|
|
3737
|
+
*/
|
|
3738
|
+
contains(key: K): boolean;
|
|
3739
|
+
add(key: K, record: V): void;
|
|
3740
|
+
remove(key: K, _record: V): void;
|
|
3741
|
+
update(key: K, oldRecord: V, newRecord: V): void;
|
|
3742
|
+
/**
|
|
3743
|
+
* Determine what changed for a record update.
|
|
3744
|
+
* Returns the type of change relative to the query results.
|
|
3745
|
+
*
|
|
3746
|
+
* @param key - Record key
|
|
3747
|
+
* @param oldRecord - Previous record value (undefined for new records)
|
|
3748
|
+
* @param newRecord - New record value (undefined for deleted records)
|
|
3749
|
+
* @returns Change type: 'added', 'removed', 'updated', or 'unchanged'
|
|
3750
|
+
*/
|
|
3751
|
+
determineChange(_key: K, oldRecord: V | undefined, newRecord: V | undefined): StandingQueryChange;
|
|
3752
|
+
clear(): void;
|
|
3753
|
+
getStats(): IndexStats;
|
|
3754
|
+
/**
|
|
3755
|
+
* Build index from existing data.
|
|
3756
|
+
*
|
|
3757
|
+
* @param entries - Iterable of [key, record] pairs
|
|
3758
|
+
*/
|
|
3759
|
+
buildFromData(entries: Iterable<[K, V]>): void;
|
|
3760
|
+
/**
|
|
3761
|
+
* Evaluate a record against the query predicate.
|
|
3762
|
+
*
|
|
3763
|
+
* @param record - Record to evaluate
|
|
3764
|
+
* @returns true if record matches the query
|
|
3765
|
+
*/
|
|
3766
|
+
private evaluateRecord;
|
|
3767
|
+
/**
|
|
3768
|
+
* Evaluate a query node against a record.
|
|
3769
|
+
* Implements predicate evaluation logic.
|
|
3770
|
+
*/
|
|
3771
|
+
private evaluateQuery;
|
|
3772
|
+
/**
|
|
3773
|
+
* Evaluate a simple query (attribute-based condition).
|
|
3774
|
+
*/
|
|
3775
|
+
private evaluateSimpleQuery;
|
|
3776
|
+
/**
|
|
3777
|
+
* Evaluate a logical query (AND/OR/NOT).
|
|
3778
|
+
*/
|
|
3779
|
+
private evaluateLogicalQuery;
|
|
3780
|
+
/**
|
|
3781
|
+
* Get attribute value from record using dot notation.
|
|
3782
|
+
*/
|
|
3783
|
+
private getAttributeValue;
|
|
3784
|
+
/**
|
|
3785
|
+
* Match a value against a LIKE pattern.
|
|
3786
|
+
* Supports % as wildcard for any characters.
|
|
3787
|
+
*/
|
|
3788
|
+
private matchLike;
|
|
3789
|
+
/**
|
|
3790
|
+
* Deep equality check for queries.
|
|
3791
|
+
*/
|
|
3792
|
+
private queriesEqual;
|
|
3793
|
+
}
|
|
3794
|
+
|
|
3795
|
+
/**
|
|
3796
|
+
* Tokenizer Interface and Implementations
|
|
3797
|
+
*
|
|
3798
|
+
* Provides text tokenization for InvertedIndex full-text search.
|
|
3799
|
+
* Tokenizers split text into searchable tokens.
|
|
3800
|
+
*
|
|
3801
|
+
* @module query/tokenization/Tokenizer
|
|
3802
|
+
*/
|
|
3803
|
+
/**
|
|
3804
|
+
* Interface for text tokenizers.
|
|
3805
|
+
* Tokenizers split text into an array of tokens (words, n-grams, etc.)
|
|
3806
|
+
*/
|
|
3807
|
+
interface Tokenizer {
|
|
3808
|
+
/**
|
|
3809
|
+
* Split text into tokens.
|
|
3810
|
+
*
|
|
3811
|
+
* @param text - Text to tokenize
|
|
3812
|
+
* @returns Array of tokens
|
|
3813
|
+
*/
|
|
3814
|
+
tokenize(text: string): string[];
|
|
3815
|
+
}
|
|
3816
|
+
/**
|
|
3817
|
+
* Tokenizer that splits on whitespace.
|
|
3818
|
+
* Simplest tokenizer - splits on any whitespace characters.
|
|
3819
|
+
*
|
|
3820
|
+
* Example: "hello world" → ["hello", "world"]
|
|
3821
|
+
*/
|
|
3822
|
+
declare class WhitespaceTokenizer implements Tokenizer {
|
|
3823
|
+
tokenize(text: string): string[];
|
|
3824
|
+
}
|
|
3825
|
+
/**
|
|
3826
|
+
* Tokenizer that splits on word boundaries.
|
|
3827
|
+
* Splits on non-word characters (anything not [a-zA-Z0-9_]).
|
|
3828
|
+
*
|
|
3829
|
+
* Example: "hello-world! test123" → ["hello", "world", "test123"]
|
|
3830
|
+
*/
|
|
3831
|
+
declare class WordBoundaryTokenizer implements Tokenizer {
|
|
3832
|
+
tokenize(text: string): string[];
|
|
3833
|
+
}
|
|
3834
|
+
/**
|
|
3835
|
+
* N-gram tokenizer for substring matching.
|
|
3836
|
+
* Creates overlapping character sequences of length n.
|
|
3837
|
+
*
|
|
3838
|
+
* Example (n=3): "hello" → ["hel", "ell", "llo"]
|
|
3839
|
+
*
|
|
3840
|
+
* Use cases:
|
|
3841
|
+
* - Fuzzy search (typo tolerance)
|
|
3842
|
+
* - Substring matching (contains anywhere)
|
|
3843
|
+
* - Partial word matching
|
|
3844
|
+
*/
|
|
3845
|
+
declare class NGramTokenizer implements Tokenizer {
|
|
3846
|
+
private readonly n;
|
|
3847
|
+
/**
|
|
3848
|
+
* Create an N-gram tokenizer.
|
|
3849
|
+
*
|
|
3850
|
+
* @param n - Length of each n-gram (default: 3)
|
|
3851
|
+
*/
|
|
3852
|
+
constructor(n?: number);
|
|
3853
|
+
tokenize(text: string): string[];
|
|
3854
|
+
/**
|
|
3855
|
+
* Get the n-gram size.
|
|
3856
|
+
*/
|
|
3857
|
+
get size(): number;
|
|
3858
|
+
}
|
|
3859
|
+
|
|
3860
|
+
/**
|
|
3861
|
+
* Token Filter Interface and Implementations
|
|
3862
|
+
*
|
|
3863
|
+
* Token filters transform or filter tokens produced by tokenizers.
|
|
3864
|
+
* Common uses: lowercase normalization, stop word removal, length filtering.
|
|
3865
|
+
*
|
|
3866
|
+
* @module query/tokenization/TokenFilter
|
|
3867
|
+
*/
|
|
3868
|
+
/**
|
|
3869
|
+
* Interface for token filters.
|
|
3870
|
+
* Filters transform an array of tokens into another array of tokens.
|
|
3871
|
+
*/
|
|
3872
|
+
interface TokenFilter {
|
|
3873
|
+
/**
|
|
3874
|
+
* Apply filter to tokens.
|
|
3875
|
+
*
|
|
3876
|
+
* @param tokens - Input tokens
|
|
3877
|
+
* @returns Filtered tokens
|
|
3878
|
+
*/
|
|
3879
|
+
apply(tokens: string[]): string[];
|
|
3880
|
+
}
|
|
3881
|
+
/**
|
|
3882
|
+
* Filter that converts all tokens to lowercase.
|
|
3883
|
+
* Essential for case-insensitive search.
|
|
3884
|
+
*
|
|
3885
|
+
* Example: ["Hello", "WORLD"] → ["hello", "world"]
|
|
3886
|
+
*/
|
|
3887
|
+
declare class LowercaseFilter implements TokenFilter {
|
|
3888
|
+
apply(tokens: string[]): string[];
|
|
3889
|
+
}
|
|
3890
|
+
/**
|
|
3891
|
+
* Default English stop words.
|
|
3892
|
+
* Common words that don't add search value.
|
|
3893
|
+
*/
|
|
3894
|
+
declare const DEFAULT_STOP_WORDS: string[];
|
|
3895
|
+
/**
|
|
3896
|
+
* Filter that removes stop words.
|
|
3897
|
+
* Stop words are common words that don't contribute to search relevance.
|
|
3898
|
+
*
|
|
3899
|
+
* Example: ["the", "quick", "brown", "fox"] → ["quick", "brown", "fox"]
|
|
3900
|
+
*/
|
|
3901
|
+
declare class StopWordFilter implements TokenFilter {
|
|
3902
|
+
private readonly stopWords;
|
|
3903
|
+
/**
|
|
3904
|
+
* Create a stop word filter.
|
|
3905
|
+
*
|
|
3906
|
+
* @param stopWords - Array of stop words to remove (default: English stop words)
|
|
3907
|
+
*/
|
|
3908
|
+
constructor(stopWords?: string[]);
|
|
3909
|
+
apply(tokens: string[]): string[];
|
|
3910
|
+
/**
|
|
3911
|
+
* Get the set of stop words.
|
|
3912
|
+
*/
|
|
3913
|
+
getStopWords(): Set<string>;
|
|
3914
|
+
}
|
|
3915
|
+
/**
|
|
3916
|
+
* Filter that removes tokens shorter than a minimum length.
|
|
3917
|
+
* Useful for filtering out single characters or very short tokens.
|
|
3918
|
+
*
|
|
3919
|
+
* Example (minLength=3): ["a", "is", "the", "quick"] → ["the", "quick"]
|
|
3920
|
+
*/
|
|
3921
|
+
declare class MinLengthFilter implements TokenFilter {
|
|
3922
|
+
private readonly minLength;
|
|
3923
|
+
/**
|
|
3924
|
+
* Create a minimum length filter.
|
|
3925
|
+
*
|
|
3926
|
+
* @param minLength - Minimum token length (default: 2)
|
|
3927
|
+
*/
|
|
3928
|
+
constructor(minLength?: number);
|
|
3929
|
+
apply(tokens: string[]): string[];
|
|
3930
|
+
/**
|
|
3931
|
+
* Get the minimum length setting.
|
|
3932
|
+
*/
|
|
3933
|
+
getMinLength(): number;
|
|
3934
|
+
}
|
|
3935
|
+
/**
|
|
3936
|
+
* Filter that removes tokens longer than a maximum length.
|
|
3937
|
+
* Useful for preventing very long tokens from being indexed.
|
|
3938
|
+
*
|
|
3939
|
+
* Example (maxLength=10): ["short", "verylongword"] → ["short"]
|
|
3940
|
+
*/
|
|
3941
|
+
declare class MaxLengthFilter implements TokenFilter {
|
|
3942
|
+
private readonly maxLength;
|
|
3943
|
+
/**
|
|
3944
|
+
* Create a maximum length filter.
|
|
3945
|
+
*
|
|
3946
|
+
* @param maxLength - Maximum token length (default: 50)
|
|
3947
|
+
*/
|
|
3948
|
+
constructor(maxLength?: number);
|
|
3949
|
+
apply(tokens: string[]): string[];
|
|
3950
|
+
/**
|
|
3951
|
+
* Get the maximum length setting.
|
|
3952
|
+
*/
|
|
3953
|
+
getMaxLength(): number;
|
|
3954
|
+
}
|
|
3955
|
+
/**
|
|
3956
|
+
* Filter that trims whitespace from tokens.
|
|
3957
|
+
* Ensures clean tokens without leading/trailing spaces.
|
|
3958
|
+
*/
|
|
3959
|
+
declare class TrimFilter implements TokenFilter {
|
|
3960
|
+
apply(tokens: string[]): string[];
|
|
3961
|
+
}
|
|
3962
|
+
/**
|
|
3963
|
+
* Filter that removes duplicate tokens.
|
|
3964
|
+
* Useful for reducing index size when tokens repeat.
|
|
3965
|
+
*
|
|
3966
|
+
* Example: ["hello", "world", "hello"] → ["hello", "world"]
|
|
3967
|
+
*/
|
|
3968
|
+
declare class UniqueFilter implements TokenFilter {
|
|
3969
|
+
apply(tokens: string[]): string[];
|
|
3970
|
+
}
|
|
3971
|
+
|
|
3972
|
+
/**
|
|
3973
|
+
* Tokenization Pipeline
|
|
3974
|
+
*
|
|
3975
|
+
* Chains a tokenizer with multiple filters for text processing.
|
|
3976
|
+
* Provides factory methods for common configurations.
|
|
3977
|
+
*
|
|
3978
|
+
* @module query/tokenization/TokenizationPipeline
|
|
3979
|
+
*/
|
|
3980
|
+
|
|
3981
|
+
/**
|
|
3982
|
+
* Pipeline configuration options.
|
|
3983
|
+
*/
|
|
3984
|
+
interface TokenizationPipelineOptions {
|
|
3985
|
+
/** Tokenizer to use */
|
|
3986
|
+
tokenizer: Tokenizer;
|
|
3987
|
+
/** Filters to apply (in order) */
|
|
3988
|
+
filters?: TokenFilter[];
|
|
3989
|
+
}
|
|
3990
|
+
/**
|
|
3991
|
+
* Tokenization pipeline that chains a tokenizer with filters.
|
|
3992
|
+
*
|
|
3993
|
+
* Processing order:
|
|
3994
|
+
* 1. Tokenizer splits text into tokens
|
|
3995
|
+
* 2. Each filter transforms the token array in sequence
|
|
3996
|
+
*
|
|
3997
|
+
* Example:
|
|
3998
|
+
* ```typescript
|
|
3999
|
+
* const pipeline = TokenizationPipeline.simple();
|
|
4000
|
+
* pipeline.process("Hello World!"); // ["hello", "world"]
|
|
4001
|
+
* ```
|
|
4002
|
+
*/
|
|
4003
|
+
declare class TokenizationPipeline {
|
|
4004
|
+
private readonly tokenizer;
|
|
4005
|
+
private readonly filters;
|
|
4006
|
+
/**
|
|
4007
|
+
* Create a tokenization pipeline.
|
|
4008
|
+
*
|
|
4009
|
+
* @param options - Pipeline configuration
|
|
4010
|
+
*/
|
|
4011
|
+
constructor(options: TokenizationPipelineOptions);
|
|
4012
|
+
/**
|
|
4013
|
+
* Process text through the pipeline.
|
|
4014
|
+
*
|
|
4015
|
+
* @param text - Text to process
|
|
4016
|
+
* @returns Array of processed tokens
|
|
4017
|
+
*/
|
|
4018
|
+
process(text: string): string[];
|
|
4019
|
+
/**
|
|
4020
|
+
* Get the tokenizer.
|
|
4021
|
+
*/
|
|
4022
|
+
getTokenizer(): Tokenizer;
|
|
4023
|
+
/**
|
|
4024
|
+
* Get the filters.
|
|
4025
|
+
*/
|
|
4026
|
+
getFilters(): TokenFilter[];
|
|
4027
|
+
/**
|
|
4028
|
+
* Create a simple pipeline with common defaults.
|
|
4029
|
+
* Uses word boundary tokenizer with lowercase and minimum length filters.
|
|
4030
|
+
*
|
|
4031
|
+
* Configuration:
|
|
4032
|
+
* - Tokenizer: WordBoundaryTokenizer
|
|
4033
|
+
* - Filters: LowercaseFilter, MinLengthFilter(2)
|
|
4034
|
+
*
|
|
4035
|
+
* @returns Simple tokenization pipeline
|
|
4036
|
+
*/
|
|
4037
|
+
static simple(): TokenizationPipeline;
|
|
4038
|
+
/**
|
|
4039
|
+
* Create a pipeline optimized for search.
|
|
4040
|
+
* Includes stop word removal for better search relevance.
|
|
4041
|
+
*
|
|
4042
|
+
* Configuration:
|
|
4043
|
+
* - Tokenizer: WordBoundaryTokenizer
|
|
4044
|
+
* - Filters: LowercaseFilter, MinLengthFilter(2), StopWordFilter
|
|
4045
|
+
*
|
|
4046
|
+
* @returns Search-optimized tokenization pipeline
|
|
4047
|
+
*/
|
|
4048
|
+
static search(): TokenizationPipeline;
|
|
4049
|
+
/**
|
|
4050
|
+
* Create a minimal pipeline with just tokenization and lowercase.
|
|
4051
|
+
* No filtering - preserves all tokens.
|
|
4052
|
+
*
|
|
4053
|
+
* Configuration:
|
|
4054
|
+
* - Tokenizer: WordBoundaryTokenizer
|
|
4055
|
+
* - Filters: LowercaseFilter
|
|
4056
|
+
*
|
|
4057
|
+
* @returns Minimal tokenization pipeline
|
|
4058
|
+
*/
|
|
4059
|
+
static minimal(): TokenizationPipeline;
|
|
4060
|
+
/**
|
|
4061
|
+
* Create a custom pipeline from a tokenizer and filters.
|
|
4062
|
+
*
|
|
4063
|
+
* @param tokenizer - Tokenizer to use
|
|
4064
|
+
* @param filters - Filters to apply
|
|
4065
|
+
* @returns Custom tokenization pipeline
|
|
4066
|
+
*/
|
|
4067
|
+
static custom(tokenizer: Tokenizer, filters?: TokenFilter[]): TokenizationPipeline;
|
|
4068
|
+
}
|
|
4069
|
+
|
|
4070
|
+
/**
|
|
4071
|
+
* InvertedIndex Implementation
|
|
4072
|
+
*
|
|
4073
|
+
* Full-text search index using inverted index structure.
|
|
4074
|
+
* Supports: contains, containsAll, containsAny, has queries.
|
|
4075
|
+
*
|
|
4076
|
+
* Structure:
|
|
4077
|
+
* tokenIndex: Map<Token, Set<RecordKey>>
|
|
4078
|
+
* reverseIndex: Map<RecordKey, Set<Token>>
|
|
4079
|
+
*
|
|
4080
|
+
* Retrieval cost: 50 (between NavigableIndex:40 and FallbackIndex)
|
|
4081
|
+
*
|
|
4082
|
+
* @module query/indexes/InvertedIndex
|
|
4083
|
+
*/
|
|
4084
|
+
|
|
4085
|
+
/**
|
|
4086
|
+
* Extended statistics for InvertedIndex.
|
|
4087
|
+
*/
|
|
4088
|
+
interface InvertedIndexStats extends IndexStats {
|
|
4089
|
+
/** Total unique tokens in the index */
|
|
4090
|
+
totalTokens: number;
|
|
4091
|
+
/** Average number of tokens per indexed document */
|
|
4092
|
+
avgTokensPerDocument: number;
|
|
4093
|
+
/** Maximum documents for any single token */
|
|
4094
|
+
maxDocumentsPerToken: number;
|
|
4095
|
+
}
|
|
4096
|
+
/**
|
|
4097
|
+
* Inverted index for full-text search.
|
|
4098
|
+
* Maps tokens to sets of document keys for O(K) query performance.
|
|
4099
|
+
*
|
|
4100
|
+
* K = record key type, V = record value type, A = attribute value type (should be string)
|
|
4101
|
+
*/
|
|
4102
|
+
declare class InvertedIndex<K, V, A extends string = string> implements Index<K, V, A> {
|
|
4103
|
+
readonly attribute: Attribute<V, A>;
|
|
4104
|
+
private readonly pipeline;
|
|
4105
|
+
readonly type: "inverted";
|
|
4106
|
+
/** Token → Set of keys */
|
|
4107
|
+
private tokenIndex;
|
|
4108
|
+
/** Key → Set of tokens (for efficient removal/update) */
|
|
4109
|
+
private reverseIndex;
|
|
4110
|
+
/** All keys with indexed content */
|
|
4111
|
+
private allKeys;
|
|
4112
|
+
private static readonly RETRIEVAL_COST;
|
|
4113
|
+
private static readonly SUPPORTED_QUERIES;
|
|
4114
|
+
/**
|
|
4115
|
+
* Create an InvertedIndex.
|
|
4116
|
+
*
|
|
4117
|
+
* @param attribute - Attribute to index (should return string values)
|
|
4118
|
+
* @param pipeline - Tokenization pipeline (default: simple pipeline)
|
|
4119
|
+
*/
|
|
4120
|
+
constructor(attribute: Attribute<V, A>, pipeline?: TokenizationPipeline);
|
|
4121
|
+
getRetrievalCost(): number;
|
|
4122
|
+
supportsQuery(queryType: string): boolean;
|
|
4123
|
+
retrieve(query: IndexQuery<A>): ResultSet<K>;
|
|
4124
|
+
/**
|
|
4125
|
+
* Retrieve documents containing all tokens from the search text.
|
|
4126
|
+
* Uses AND semantics - document must contain ALL tokens.
|
|
4127
|
+
*/
|
|
4128
|
+
private retrieveContains;
|
|
4129
|
+
/**
|
|
4130
|
+
* Retrieve documents containing ALL specified values.
|
|
4131
|
+
* Each value is tokenized, and ALL resulting tokens must match.
|
|
4132
|
+
*/
|
|
4133
|
+
private retrieveContainsAll;
|
|
4134
|
+
/**
|
|
4135
|
+
* Retrieve documents containing ANY of the specified values.
|
|
4136
|
+
* Uses OR semantics - document can contain any token from any value.
|
|
4137
|
+
*/
|
|
4138
|
+
private retrieveContainsAny;
|
|
4139
|
+
/**
|
|
4140
|
+
* Retrieve all documents with indexed content.
|
|
4141
|
+
*/
|
|
4142
|
+
private retrieveHas;
|
|
4143
|
+
add(key: K, record: V): void;
|
|
4144
|
+
remove(key: K, _record: V): void;
|
|
4145
|
+
update(key: K, oldRecord: V, newRecord: V): void;
|
|
4146
|
+
clear(): void;
|
|
4147
|
+
getStats(): IndexStats;
|
|
4148
|
+
/**
|
|
4149
|
+
* Get extended statistics for full-text index.
|
|
4150
|
+
*/
|
|
4151
|
+
getExtendedStats(): InvertedIndexStats;
|
|
4152
|
+
/**
|
|
4153
|
+
* Get the tokenization pipeline.
|
|
4154
|
+
*/
|
|
4155
|
+
getPipeline(): TokenizationPipeline;
|
|
4156
|
+
/**
|
|
4157
|
+
* Check if a specific token exists in the index.
|
|
4158
|
+
*/
|
|
4159
|
+
hasToken(token: string): boolean;
|
|
4160
|
+
/**
|
|
4161
|
+
* Get the number of documents for a specific token.
|
|
4162
|
+
*/
|
|
4163
|
+
getTokenDocumentCount(token: string): number;
|
|
4164
|
+
private valuesEqual;
|
|
4165
|
+
}
|
|
4166
|
+
|
|
4167
|
+
/**
|
|
4168
|
+
* SetResultSet Implementation
|
|
4169
|
+
*
|
|
4170
|
+
* ResultSet backed by a Set, used for HashIndex results.
|
|
4171
|
+
*
|
|
4172
|
+
* @module query/resultset/SetResultSet
|
|
4173
|
+
*/
|
|
4174
|
+
|
|
4175
|
+
/**
|
|
4176
|
+
* ResultSet backed by a Set.
|
|
4177
|
+
* Provides O(1) contains() check and direct iteration.
|
|
4178
|
+
*/
|
|
4179
|
+
declare class SetResultSet<K> implements ResultSet<K> {
|
|
4180
|
+
private readonly keys;
|
|
4181
|
+
private readonly retrievalCost;
|
|
4182
|
+
constructor(keys: Set<K>, retrievalCost: number);
|
|
4183
|
+
[Symbol.iterator](): Iterator<K>;
|
|
4184
|
+
getRetrievalCost(): number;
|
|
4185
|
+
getMergeCost(): number;
|
|
4186
|
+
contains(key: K): boolean;
|
|
4187
|
+
size(): number;
|
|
4188
|
+
toArray(): K[];
|
|
4189
|
+
isEmpty(): boolean;
|
|
4190
|
+
}
|
|
4191
|
+
|
|
4192
|
+
/**
|
|
4193
|
+
* LazyResultSet Implementation
|
|
4194
|
+
*
|
|
4195
|
+
* Lazily evaluated result set for range queries.
|
|
4196
|
+
* Used when materializing all results upfront would be expensive.
|
|
4197
|
+
*
|
|
4198
|
+
* @module query/resultset/LazyResultSet
|
|
4199
|
+
*/
|
|
4200
|
+
|
|
4201
|
+
/**
|
|
4202
|
+
* Factory function type that creates a generator for lazy iteration.
|
|
4203
|
+
*/
|
|
4204
|
+
type IteratorFactory<K> = () => Generator<K>;
|
|
4205
|
+
/**
|
|
4206
|
+
* Lazily evaluated result set.
|
|
4207
|
+
* Used for range queries where materializing all results upfront is expensive.
|
|
4208
|
+
*
|
|
4209
|
+
* K = record key type
|
|
4210
|
+
*/
|
|
4211
|
+
declare class LazyResultSet<K> implements ResultSet<K> {
|
|
4212
|
+
private readonly iteratorFactory;
|
|
4213
|
+
private readonly retrievalCost;
|
|
4214
|
+
private readonly estimatedSize;
|
|
4215
|
+
/** Cached materialized results */
|
|
4216
|
+
private cached;
|
|
4217
|
+
/**
|
|
4218
|
+
* Create a LazyResultSet.
|
|
4219
|
+
*
|
|
4220
|
+
* @param iteratorFactory - Factory that creates a fresh generator each time
|
|
4221
|
+
* @param retrievalCost - Cost of retrieving results from the index
|
|
4222
|
+
* @param estimatedSize - Estimated result count for merge cost calculation
|
|
4223
|
+
*/
|
|
4224
|
+
constructor(iteratorFactory: IteratorFactory<K>, retrievalCost: number, estimatedSize: number);
|
|
4225
|
+
[Symbol.iterator](): Generator<K>;
|
|
4226
|
+
getRetrievalCost(): number;
|
|
4227
|
+
getMergeCost(): number;
|
|
4228
|
+
contains(key: K): boolean;
|
|
4229
|
+
size(): number;
|
|
4230
|
+
toArray(): K[];
|
|
4231
|
+
isEmpty(): boolean;
|
|
4232
|
+
/**
|
|
4233
|
+
* Check if the result set has been materialized.
|
|
4234
|
+
* Useful for testing lazy evaluation behavior.
|
|
4235
|
+
*/
|
|
4236
|
+
isMaterialized(): boolean;
|
|
4237
|
+
/**
|
|
4238
|
+
* Force materialization of the result set.
|
|
4239
|
+
* Returns the cached array.
|
|
4240
|
+
*/
|
|
4241
|
+
materialize(): K[];
|
|
4242
|
+
/**
|
|
4243
|
+
* Get the estimated size before materialization.
|
|
4244
|
+
*/
|
|
4245
|
+
getEstimatedSize(): number;
|
|
4246
|
+
}
|
|
4247
|
+
|
|
4248
|
+
/**
|
|
4249
|
+
* IntersectionResultSet Implementation
|
|
4250
|
+
*
|
|
4251
|
+
* Intersection of multiple result sets (AND logic).
|
|
4252
|
+
* Implements CQEngine "smallest first" strategy:
|
|
4253
|
+
* iterate the smallest set, check membership in others.
|
|
4254
|
+
*
|
|
4255
|
+
* @module query/resultset/IntersectionResultSet
|
|
4256
|
+
*/
|
|
4257
|
+
|
|
4258
|
+
/**
|
|
4259
|
+
* Intersection of multiple result sets (AND logic).
|
|
4260
|
+
* CQEngine strategy: iterate smallest set, check membership in others.
|
|
4261
|
+
*
|
|
4262
|
+
* K = record key type
|
|
4263
|
+
*/
|
|
4264
|
+
declare class IntersectionResultSet<K> implements ResultSet<K> {
|
|
4265
|
+
/** Cached materialized results */
|
|
4266
|
+
private cached;
|
|
4267
|
+
/** Result sets sorted by merge cost */
|
|
4268
|
+
private sortedResultSets;
|
|
4269
|
+
/**
|
|
4270
|
+
* Create an IntersectionResultSet.
|
|
4271
|
+
*
|
|
4272
|
+
* @param resultSets - Result sets to intersect
|
|
4273
|
+
*/
|
|
4274
|
+
constructor(resultSets: ResultSet<K>[]);
|
|
4275
|
+
/**
|
|
4276
|
+
* Lazy iteration over intersection.
|
|
4277
|
+
* Iterates smallest set, yields only keys present in all sets.
|
|
4278
|
+
*/
|
|
4279
|
+
[Symbol.iterator](): Generator<K>;
|
|
4280
|
+
/**
|
|
4281
|
+
* Retrieval cost is minimum of all (we only iterate smallest).
|
|
4282
|
+
*/
|
|
4283
|
+
getRetrievalCost(): number;
|
|
4284
|
+
/**
|
|
4285
|
+
* Merge cost is estimated as smallest set size (upper bound).
|
|
4286
|
+
*/
|
|
4287
|
+
getMergeCost(): number;
|
|
4288
|
+
/**
|
|
4289
|
+
* Check if key is in all result sets.
|
|
4290
|
+
*/
|
|
4291
|
+
contains(key: K): boolean;
|
|
4292
|
+
/**
|
|
4293
|
+
* Get size by materializing results.
|
|
4294
|
+
*/
|
|
4295
|
+
size(): number;
|
|
4296
|
+
/**
|
|
4297
|
+
* Materialize to array with caching.
|
|
4298
|
+
*/
|
|
4299
|
+
toArray(): K[];
|
|
4300
|
+
/**
|
|
4301
|
+
* Check if empty (tries to avoid full materialization).
|
|
4302
|
+
*/
|
|
4303
|
+
isEmpty(): boolean;
|
|
4304
|
+
/**
|
|
4305
|
+
* Check if results have been materialized.
|
|
4306
|
+
*/
|
|
4307
|
+
isMaterialized(): boolean;
|
|
4308
|
+
}
|
|
4309
|
+
|
|
4310
|
+
/**
|
|
4311
|
+
* UnionResultSet Implementation
|
|
4312
|
+
*
|
|
4313
|
+
* Union of multiple result sets (OR logic).
|
|
4314
|
+
* Deduplicates results using a Set during iteration.
|
|
4315
|
+
*
|
|
4316
|
+
* @module query/resultset/UnionResultSet
|
|
4317
|
+
*/
|
|
4318
|
+
|
|
4319
|
+
/**
|
|
4320
|
+
* Union of multiple result sets (OR logic).
|
|
4321
|
+
* Deduplicates results.
|
|
4322
|
+
*
|
|
4323
|
+
* K = record key type
|
|
4324
|
+
*/
|
|
4325
|
+
declare class UnionResultSet<K> implements ResultSet<K> {
|
|
4326
|
+
private readonly resultSets;
|
|
4327
|
+
/** Cached materialized results */
|
|
4328
|
+
private cached;
|
|
4329
|
+
/**
|
|
4330
|
+
* Create a UnionResultSet.
|
|
4331
|
+
*
|
|
4332
|
+
* @param resultSets - Result sets to union
|
|
4333
|
+
*/
|
|
4334
|
+
constructor(resultSets: ResultSet<K>[]);
|
|
4335
|
+
/**
|
|
4336
|
+
* Lazy iteration over union with deduplication.
|
|
4337
|
+
*/
|
|
4338
|
+
[Symbol.iterator](): Generator<K>;
|
|
4339
|
+
/**
|
|
4340
|
+
* Retrieval cost is sum of all costs.
|
|
4341
|
+
*/
|
|
4342
|
+
getRetrievalCost(): number;
|
|
4343
|
+
/**
|
|
4344
|
+
* Merge cost upper bound: sum of all sizes.
|
|
4345
|
+
*/
|
|
4346
|
+
getMergeCost(): number;
|
|
4347
|
+
/**
|
|
4348
|
+
* Check if key is in any result set.
|
|
4349
|
+
*/
|
|
4350
|
+
contains(key: K): boolean;
|
|
4351
|
+
/**
|
|
4352
|
+
* Get size by materializing results.
|
|
4353
|
+
*/
|
|
4354
|
+
size(): number;
|
|
4355
|
+
/**
|
|
4356
|
+
* Materialize to array with caching.
|
|
4357
|
+
*/
|
|
4358
|
+
toArray(): K[];
|
|
4359
|
+
/**
|
|
4360
|
+
* Check if empty (all sources must be empty).
|
|
4361
|
+
*/
|
|
4362
|
+
isEmpty(): boolean;
|
|
4363
|
+
/**
|
|
4364
|
+
* Check if results have been materialized.
|
|
4365
|
+
*/
|
|
4366
|
+
isMaterialized(): boolean;
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4369
|
+
/**
|
|
4370
|
+
* FilteringResultSet Implementation
|
|
4371
|
+
*
|
|
4372
|
+
* Filters a source result set with a predicate.
|
|
4373
|
+
* Used when an index is available for part of a query,
|
|
4374
|
+
* but additional filtering is needed.
|
|
4375
|
+
*
|
|
4376
|
+
* @module query/resultset/FilteringResultSet
|
|
4377
|
+
*/
|
|
4378
|
+
|
|
4379
|
+
/**
|
|
4380
|
+
* Predicate function for filtering records.
|
|
4381
|
+
*/
|
|
4382
|
+
type PredicateFn<V> = (record: V) => boolean;
|
|
4383
|
+
/**
|
|
4384
|
+
* Filters a source result set with a predicate.
|
|
4385
|
+
*
|
|
4386
|
+
* K = record key type, V = record value type
|
|
4387
|
+
*/
|
|
4388
|
+
declare class FilteringResultSet<K, V> implements ResultSet<K> {
|
|
4389
|
+
private readonly source;
|
|
4390
|
+
private readonly getRecord;
|
|
4391
|
+
private readonly predicate;
|
|
4392
|
+
/** Cached materialized results */
|
|
4393
|
+
private cached;
|
|
4394
|
+
/**
|
|
4395
|
+
* Create a FilteringResultSet.
|
|
4396
|
+
*
|
|
4397
|
+
* @param source - Source result set to filter
|
|
4398
|
+
* @param getRecord - Function to get record by key
|
|
4399
|
+
* @param predicate - Predicate function to filter records
|
|
4400
|
+
*/
|
|
4401
|
+
constructor(source: ResultSet<K>, getRecord: (key: K) => V | undefined, predicate: PredicateFn<V>);
|
|
4402
|
+
/**
|
|
4403
|
+
* Lazy iteration with filtering.
|
|
4404
|
+
*/
|
|
4405
|
+
[Symbol.iterator](): Generator<K>;
|
|
4406
|
+
/**
|
|
4407
|
+
* Retrieval cost: source cost + filter overhead.
|
|
4408
|
+
*/
|
|
4409
|
+
getRetrievalCost(): number;
|
|
4410
|
+
/**
|
|
4411
|
+
* Merge cost: estimate half of source (pessimistic).
|
|
4412
|
+
*/
|
|
4413
|
+
getMergeCost(): number;
|
|
4414
|
+
/**
|
|
4415
|
+
* Check if key is in source and passes predicate.
|
|
4416
|
+
*/
|
|
4417
|
+
contains(key: K): boolean;
|
|
4418
|
+
/**
|
|
4419
|
+
* Get size by materializing results.
|
|
4420
|
+
*/
|
|
4421
|
+
size(): number;
|
|
4422
|
+
/**
|
|
4423
|
+
* Materialize to array with caching.
|
|
4424
|
+
*/
|
|
4425
|
+
toArray(): K[];
|
|
4426
|
+
/**
|
|
4427
|
+
* Check if empty (tries to find at least one match).
|
|
4428
|
+
*/
|
|
4429
|
+
isEmpty(): boolean;
|
|
4430
|
+
/**
|
|
4431
|
+
* Check if results have been materialized.
|
|
4432
|
+
*/
|
|
4433
|
+
isMaterialized(): boolean;
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
/**
|
|
4437
|
+
* SortedResultSet Implementation
|
|
4438
|
+
*
|
|
4439
|
+
* ResultSet with sorting support.
|
|
4440
|
+
* If source is from NavigableIndex on sort field, results are already sorted.
|
|
4441
|
+
* Otherwise, performs in-memory sort.
|
|
4442
|
+
*
|
|
4443
|
+
* @module query/resultset/SortedResultSet
|
|
4444
|
+
*/
|
|
4445
|
+
|
|
4446
|
+
/**
|
|
4447
|
+
* Comparator function for sorting.
|
|
4448
|
+
*/
|
|
4449
|
+
type CompareFn<V> = (a: V, b: V) => number;
|
|
4450
|
+
/**
|
|
4451
|
+
* ResultSet with sorting support.
|
|
4452
|
+
*
|
|
4453
|
+
* K = record key type, V = record value type
|
|
4454
|
+
*/
|
|
4455
|
+
declare class SortedResultSet<K, V> implements ResultSet<K> {
|
|
4456
|
+
private readonly source;
|
|
4457
|
+
private readonly getRecord;
|
|
4458
|
+
private readonly sortField;
|
|
4459
|
+
private readonly direction;
|
|
4460
|
+
private readonly isPreSorted;
|
|
4461
|
+
/** Cached sorted results */
|
|
4462
|
+
private cached;
|
|
4463
|
+
/**
|
|
4464
|
+
* Create a SortedResultSet.
|
|
4465
|
+
*
|
|
4466
|
+
* @param source - Source result set
|
|
4467
|
+
* @param getRecord - Function to get record by key
|
|
4468
|
+
* @param sortField - Field to sort by
|
|
4469
|
+
* @param direction - Sort direction ('asc' or 'desc')
|
|
4470
|
+
* @param isPreSorted - Whether source is already sorted (from NavigableIndex)
|
|
4471
|
+
*/
|
|
4472
|
+
constructor(source: ResultSet<K>, getRecord: (key: K) => V | undefined, sortField: string, direction: 'asc' | 'desc', isPreSorted?: boolean);
|
|
4473
|
+
/**
|
|
4474
|
+
* Lazy iteration with sorting.
|
|
4475
|
+
*/
|
|
4476
|
+
[Symbol.iterator](): Generator<K>;
|
|
4477
|
+
/**
|
|
4478
|
+
* Materialize to sorted array with caching.
|
|
4479
|
+
*/
|
|
4480
|
+
toArray(): K[];
|
|
4481
|
+
/**
|
|
4482
|
+
* Retrieval cost: source cost + sort overhead.
|
|
4483
|
+
* Pre-sorted has minimal overhead.
|
|
4484
|
+
*/
|
|
4485
|
+
getRetrievalCost(): number;
|
|
4486
|
+
/**
|
|
4487
|
+
* Merge cost: same as source (sorting doesn't change size).
|
|
4488
|
+
*/
|
|
4489
|
+
getMergeCost(): number;
|
|
4490
|
+
/**
|
|
4491
|
+
* Check if key is in source.
|
|
4492
|
+
*/
|
|
4493
|
+
contains(key: K): boolean;
|
|
4494
|
+
/**
|
|
4495
|
+
* Get size (same as source).
|
|
4496
|
+
*/
|
|
4497
|
+
size(): number;
|
|
4498
|
+
/**
|
|
4499
|
+
* Check if empty.
|
|
4500
|
+
*/
|
|
4501
|
+
isEmpty(): boolean;
|
|
4502
|
+
/**
|
|
4503
|
+
* Check if results have been materialized.
|
|
4504
|
+
*/
|
|
4505
|
+
isMaterialized(): boolean;
|
|
4506
|
+
/**
|
|
4507
|
+
* Check if this result set is pre-sorted.
|
|
4508
|
+
*/
|
|
4509
|
+
isIndexSorted(): boolean;
|
|
4510
|
+
/**
|
|
4511
|
+
* Get sort field.
|
|
4512
|
+
*/
|
|
4513
|
+
getSortField(): string;
|
|
4514
|
+
/**
|
|
4515
|
+
* Get sort direction.
|
|
4516
|
+
*/
|
|
4517
|
+
getSortDirection(): 'asc' | 'desc';
|
|
4518
|
+
}
|
|
4519
|
+
/**
|
|
4520
|
+
* Create a comparator function for a field.
|
|
4521
|
+
*
|
|
4522
|
+
* @param field - Field name to compare
|
|
4523
|
+
* @param direction - Sort direction
|
|
4524
|
+
*/
|
|
4525
|
+
declare function createFieldComparator<V>(field: string, direction: 'asc' | 'desc'): CompareFn<V>;
|
|
4526
|
+
|
|
4527
|
+
/**
|
|
4528
|
+
* LimitResultSet Implementation
|
|
4529
|
+
*
|
|
4530
|
+
* Applies offset/limit to source ResultSet.
|
|
4531
|
+
* Implements early termination for efficiency.
|
|
4532
|
+
*
|
|
4533
|
+
* @module query/resultset/LimitResultSet
|
|
4534
|
+
*/
|
|
4535
|
+
|
|
4536
|
+
/**
|
|
4537
|
+
* Applies offset/limit to source ResultSet.
|
|
4538
|
+
* Implements early termination for efficiency.
|
|
4539
|
+
*
|
|
4540
|
+
* K = record key type
|
|
4541
|
+
*/
|
|
4542
|
+
declare class LimitResultSet<K> implements ResultSet<K> {
|
|
4543
|
+
private readonly source;
|
|
4544
|
+
private readonly offset;
|
|
4545
|
+
private readonly limit;
|
|
4546
|
+
/** Cached materialized results */
|
|
4547
|
+
private cached;
|
|
4548
|
+
/**
|
|
4549
|
+
* Create a LimitResultSet.
|
|
4550
|
+
*
|
|
4551
|
+
* @param source - Source result set
|
|
4552
|
+
* @param offset - Number of results to skip (default: 0)
|
|
4553
|
+
* @param limit - Maximum number of results (default: Infinity)
|
|
4554
|
+
*/
|
|
4555
|
+
constructor(source: ResultSet<K>, offset?: number, limit?: number);
|
|
4556
|
+
/**
|
|
4557
|
+
* Lazy iteration with offset/limit and early termination.
|
|
4558
|
+
*/
|
|
4559
|
+
[Symbol.iterator](): Generator<K>;
|
|
4560
|
+
/**
|
|
4561
|
+
* Retrieval cost: source cost (limit doesn't change retrieval cost).
|
|
4562
|
+
*/
|
|
4563
|
+
getRetrievalCost(): number;
|
|
4564
|
+
/**
|
|
4565
|
+
* Merge cost: min(source size, offset + limit).
|
|
4566
|
+
*/
|
|
4567
|
+
getMergeCost(): number;
|
|
4568
|
+
/**
|
|
4569
|
+
* Check if key is in result (with offset/limit constraints).
|
|
4570
|
+
* This is expensive as it requires iteration to determine position.
|
|
4571
|
+
*/
|
|
4572
|
+
contains(key: K): boolean;
|
|
4573
|
+
/**
|
|
4574
|
+
* Get size by materializing results.
|
|
4575
|
+
*/
|
|
4576
|
+
size(): number;
|
|
4577
|
+
/**
|
|
4578
|
+
* Materialize to array with caching.
|
|
4579
|
+
*/
|
|
4580
|
+
toArray(): K[];
|
|
4581
|
+
/**
|
|
4582
|
+
* Check if empty.
|
|
4583
|
+
*/
|
|
4584
|
+
isEmpty(): boolean;
|
|
4585
|
+
/**
|
|
4586
|
+
* Check if results have been materialized.
|
|
4587
|
+
*/
|
|
4588
|
+
isMaterialized(): boolean;
|
|
4589
|
+
/**
|
|
4590
|
+
* Get the offset value.
|
|
4591
|
+
*/
|
|
4592
|
+
getOffset(): number;
|
|
4593
|
+
/**
|
|
4594
|
+
* Get the limit value.
|
|
4595
|
+
*/
|
|
4596
|
+
getLimit(): number;
|
|
4597
|
+
}
|
|
4598
|
+
|
|
4599
|
+
/**
|
|
4600
|
+
* IndexRegistry Implementation
|
|
4601
|
+
*
|
|
4602
|
+
* Central registry for managing indexes on a collection.
|
|
4603
|
+
* Provides index lookup, lifecycle management, and bulk operations.
|
|
4604
|
+
*
|
|
4605
|
+
* @module query/IndexRegistry
|
|
4606
|
+
*/
|
|
4607
|
+
|
|
4608
|
+
/**
|
|
4609
|
+
* Registry for managing indexes on a collection.
|
|
4610
|
+
* Provides index lookup and lifecycle management.
|
|
4611
|
+
*
|
|
4612
|
+
* K = record key type, V = record value type
|
|
4613
|
+
*/
|
|
4614
|
+
declare class IndexRegistry<K, V> {
|
|
4615
|
+
/** Indexes grouped by attribute name */
|
|
4616
|
+
private attributeIndexes;
|
|
4617
|
+
/** Fallback index for full scan (optional) */
|
|
4618
|
+
private fallbackIndex;
|
|
4619
|
+
/**
|
|
4620
|
+
* Register an index for an attribute.
|
|
4621
|
+
* Multiple indexes can be registered for the same attribute.
|
|
4622
|
+
*
|
|
4623
|
+
* @param index - Index to register
|
|
4624
|
+
*/
|
|
4625
|
+
addIndex<A>(index: Index<K, V, A>): void;
|
|
4626
|
+
/**
|
|
4627
|
+
* Remove an index from the registry.
|
|
4628
|
+
*
|
|
4629
|
+
* @param index - Index to remove
|
|
4630
|
+
* @returns true if index was found and removed
|
|
4631
|
+
*/
|
|
4632
|
+
removeIndex<A>(index: Index<K, V, A>): boolean;
|
|
4633
|
+
/**
|
|
4634
|
+
* Get all indexes for an attribute.
|
|
4635
|
+
*
|
|
4636
|
+
* @param attributeName - Attribute name
|
|
4637
|
+
* @returns Array of indexes (empty if none)
|
|
4638
|
+
*/
|
|
4639
|
+
getIndexes(attributeName: string): Index<K, V, unknown>[];
|
|
4640
|
+
/**
|
|
4641
|
+
* Get all registered indexes across all attributes.
|
|
4642
|
+
*
|
|
4643
|
+
* @returns Array of all indexes
|
|
4644
|
+
*/
|
|
4645
|
+
getAllIndexes(): Index<K, V, unknown>[];
|
|
4646
|
+
/**
|
|
4647
|
+
* Get all indexed attribute names.
|
|
4648
|
+
*
|
|
4649
|
+
* @returns Array of attribute names
|
|
4650
|
+
*/
|
|
4651
|
+
getIndexedAttributes(): string[];
|
|
4652
|
+
/**
|
|
4653
|
+
* Check if an attribute has any indexes.
|
|
4654
|
+
*
|
|
4655
|
+
* @param attributeName - Attribute name
|
|
4656
|
+
* @returns true if attribute has indexes
|
|
4657
|
+
*/
|
|
4658
|
+
hasIndex(attributeName: string): boolean;
|
|
4659
|
+
/**
|
|
4660
|
+
* Find the best index for a query type on an attribute.
|
|
4661
|
+
* Returns the index with lowest retrieval cost that supports the query type.
|
|
4662
|
+
*
|
|
4663
|
+
* @param attributeName - Attribute name to search on
|
|
4664
|
+
* @param queryType - Query type (e.g., 'equal', 'gt', 'between')
|
|
4665
|
+
* @returns Best matching index or null if none found
|
|
4666
|
+
*/
|
|
4667
|
+
findBestIndex(attributeName: string, queryType: string): Index<K, V, unknown> | null;
|
|
4668
|
+
/**
|
|
4669
|
+
* Find all indexes that support a query type on an attribute.
|
|
4670
|
+
*
|
|
4671
|
+
* @param attributeName - Attribute name
|
|
4672
|
+
* @param queryType - Query type
|
|
4673
|
+
* @returns Array of matching indexes sorted by retrieval cost
|
|
4674
|
+
*/
|
|
4675
|
+
findIndexes(attributeName: string, queryType: string): Index<K, V, unknown>[];
|
|
4676
|
+
/**
|
|
4677
|
+
* Set a fallback index for queries without a suitable index.
|
|
4678
|
+
* Typically a FallbackIndex that performs full scan.
|
|
4679
|
+
*
|
|
4680
|
+
* @param fallback - Fallback index
|
|
4681
|
+
*/
|
|
4682
|
+
setFallbackIndex(fallback: Index<K, V, unknown>): void;
|
|
4683
|
+
/**
|
|
4684
|
+
* Get the fallback index.
|
|
4685
|
+
*
|
|
4686
|
+
* @returns Fallback index or null if not set
|
|
4687
|
+
*/
|
|
4688
|
+
getFallbackIndex(): Index<K, V, unknown> | null;
|
|
4689
|
+
/**
|
|
4690
|
+
* Notify all indexes of a record addition.
|
|
4691
|
+
* Should be called when a new record is added to the collection.
|
|
4692
|
+
*
|
|
4693
|
+
* @param key - Record key
|
|
4694
|
+
* @param record - Record value
|
|
4695
|
+
*/
|
|
4696
|
+
onRecordAdded(key: K, record: V): void;
|
|
4697
|
+
/**
|
|
4698
|
+
* Notify all indexes of a record update.
|
|
4699
|
+
* Should be called when a record's value changes.
|
|
4700
|
+
*
|
|
4701
|
+
* @param key - Record key
|
|
4702
|
+
* @param oldRecord - Previous record value
|
|
4703
|
+
* @param newRecord - New record value
|
|
4704
|
+
*/
|
|
4705
|
+
onRecordUpdated(key: K, oldRecord: V, newRecord: V): void;
|
|
4706
|
+
/**
|
|
4707
|
+
* Notify all indexes of a record removal.
|
|
4708
|
+
* Should be called when a record is removed from the collection.
|
|
4709
|
+
*
|
|
4710
|
+
* @param key - Record key
|
|
4711
|
+
* @param record - Removed record value
|
|
4712
|
+
*/
|
|
4713
|
+
onRecordRemoved(key: K, record: V): void;
|
|
4714
|
+
/**
|
|
4715
|
+
* Clear all indexes.
|
|
4716
|
+
* Does not remove index registrations, only clears their data.
|
|
4717
|
+
*/
|
|
4718
|
+
clear(): void;
|
|
4719
|
+
/**
|
|
4720
|
+
* Get total number of registered indexes.
|
|
4721
|
+
*/
|
|
4722
|
+
get size(): number;
|
|
4723
|
+
/**
|
|
4724
|
+
* Get statistics about the registry.
|
|
4725
|
+
*/
|
|
4726
|
+
getStats(): IndexRegistryStats;
|
|
4727
|
+
}
|
|
4728
|
+
/**
|
|
4729
|
+
* Statistics about the IndexRegistry.
|
|
4730
|
+
*/
|
|
4731
|
+
interface IndexRegistryStats {
|
|
4732
|
+
/** Total number of indexes */
|
|
4733
|
+
totalIndexes: number;
|
|
4734
|
+
/** Number of indexed attributes */
|
|
4735
|
+
indexedAttributes: number;
|
|
4736
|
+
/** Stats for each index */
|
|
4737
|
+
indexes: Array<{
|
|
4738
|
+
attribute: string;
|
|
4739
|
+
type: string;
|
|
4740
|
+
stats: {
|
|
4741
|
+
distinctValues: number;
|
|
4742
|
+
totalEntries: number;
|
|
4743
|
+
avgEntriesPerValue: number;
|
|
4744
|
+
};
|
|
4745
|
+
}>;
|
|
4746
|
+
}
|
|
4747
|
+
|
|
4748
|
+
/**
|
|
4749
|
+
* StandingQueryRegistry Implementation
|
|
4750
|
+
*
|
|
4751
|
+
* Registry for managing StandingQueryIndexes.
|
|
4752
|
+
* Used by Live Query system to maintain pre-computed results.
|
|
4753
|
+
*
|
|
4754
|
+
* Features:
|
|
4755
|
+
* - Reference counting for shared indexes
|
|
4756
|
+
* - Automatic cleanup when all subscribers unsubscribe
|
|
4757
|
+
* - Efficient update propagation to all indexes
|
|
4758
|
+
*
|
|
4759
|
+
* @module query/StandingQueryRegistry
|
|
4760
|
+
*/
|
|
4761
|
+
|
|
4762
|
+
/**
|
|
4763
|
+
* Options for creating a StandingQueryRegistry.
|
|
4764
|
+
*/
|
|
4765
|
+
interface StandingQueryRegistryOptions<K, V> {
|
|
4766
|
+
/** Function to get record by key */
|
|
4767
|
+
getRecord: (key: K) => V | undefined;
|
|
4768
|
+
/** Function to get all entries for building index */
|
|
4769
|
+
getAllEntries: () => Iterable<[K, V]>;
|
|
4770
|
+
}
|
|
4771
|
+
/**
|
|
4772
|
+
* Statistics about the StandingQueryRegistry.
|
|
4773
|
+
*/
|
|
4774
|
+
interface StandingQueryRegistryStats {
|
|
4775
|
+
/** Number of registered indexes */
|
|
4776
|
+
indexCount: number;
|
|
4777
|
+
/** Total reference count across all indexes */
|
|
4778
|
+
totalRefCount: number;
|
|
4779
|
+
/** Total number of results across all indexes */
|
|
4780
|
+
totalResults: number;
|
|
4781
|
+
}
|
|
4782
|
+
/**
|
|
4783
|
+
* Registry for managing StandingQueryIndexes.
|
|
4784
|
+
* Provides reference counting and lifecycle management.
|
|
4785
|
+
*
|
|
4786
|
+
* K = record key type, V = record value type
|
|
4787
|
+
*/
|
|
4788
|
+
declare class StandingQueryRegistry<K, V> {
|
|
4789
|
+
/** Map from query hash to StandingQueryIndex */
|
|
4790
|
+
private indexes;
|
|
4791
|
+
/** Reference count for each query (multiple subscriptions can use same index) */
|
|
4792
|
+
private refCounts;
|
|
4793
|
+
/** Record accessor */
|
|
4794
|
+
private readonly getRecord;
|
|
4795
|
+
/** All entries accessor (for building index) */
|
|
4796
|
+
private readonly getAllEntries;
|
|
4797
|
+
constructor(options: StandingQueryRegistryOptions<K, V>);
|
|
4798
|
+
/**
|
|
4799
|
+
* Register a standing query.
|
|
4800
|
+
* Creates new index or returns existing if query already registered.
|
|
4801
|
+
* Increments reference count.
|
|
4802
|
+
*
|
|
4803
|
+
* @param query - Query to register
|
|
4804
|
+
* @returns StandingQueryIndex for the query
|
|
4805
|
+
*/
|
|
4806
|
+
register(query: Query): StandingQueryIndex<K, V>;
|
|
4807
|
+
/**
|
|
4808
|
+
* Unregister a standing query.
|
|
4809
|
+
* Decrements reference count. Only removes when refcount reaches 0.
|
|
4810
|
+
*
|
|
4811
|
+
* @param query - Query to unregister
|
|
4812
|
+
* @returns true if index was removed, false if still has references
|
|
4813
|
+
*/
|
|
4814
|
+
unregister(query: Query): boolean;
|
|
4815
|
+
/**
|
|
4816
|
+
* Get index for a query if registered.
|
|
4817
|
+
*
|
|
4818
|
+
* @param query - Query to look up
|
|
4819
|
+
* @returns StandingQueryIndex or undefined if not registered
|
|
4820
|
+
*/
|
|
4821
|
+
getIndex(query: Query): StandingQueryIndex<K, V> | undefined;
|
|
4822
|
+
/**
|
|
4823
|
+
* Get index by hash directly.
|
|
4824
|
+
*
|
|
4825
|
+
* @param hash - Query hash
|
|
4826
|
+
* @returns StandingQueryIndex or undefined if not registered
|
|
4827
|
+
*/
|
|
4828
|
+
getIndexByHash(hash: string): StandingQueryIndex<K, V> | undefined;
|
|
4829
|
+
/**
|
|
4830
|
+
* Check if query has a standing index.
|
|
4831
|
+
*
|
|
4832
|
+
* @param query - Query to check
|
|
4833
|
+
* @returns true if index exists
|
|
4834
|
+
*/
|
|
4835
|
+
hasIndex(query: Query): boolean;
|
|
4836
|
+
/**
|
|
4837
|
+
* Get reference count for a query.
|
|
4838
|
+
*
|
|
4839
|
+
* @param query - Query to check
|
|
4840
|
+
* @returns Reference count (0 if not registered)
|
|
4841
|
+
*/
|
|
4842
|
+
getRefCount(query: Query): number;
|
|
4843
|
+
/**
|
|
4844
|
+
* Notify all indexes of record addition.
|
|
4845
|
+
* Returns map of query hash to change type for affected queries.
|
|
4846
|
+
*
|
|
4847
|
+
* @param key - Record key
|
|
4848
|
+
* @param record - New record value
|
|
4849
|
+
* @returns Map of query hash to change type
|
|
4850
|
+
*/
|
|
4851
|
+
onRecordAdded(key: K, record: V): Map<string, StandingQueryChange>;
|
|
4852
|
+
/**
|
|
4853
|
+
* Notify all indexes of record update.
|
|
4854
|
+
* Returns map of query hash to change type for affected queries.
|
|
4855
|
+
*
|
|
4856
|
+
* @param key - Record key
|
|
4857
|
+
* @param oldRecord - Previous record value
|
|
4858
|
+
* @param newRecord - New record value
|
|
4859
|
+
* @returns Map of query hash to change type
|
|
4860
|
+
*/
|
|
4861
|
+
onRecordUpdated(key: K, oldRecord: V, newRecord: V): Map<string, StandingQueryChange>;
|
|
4862
|
+
/**
|
|
4863
|
+
* Notify all indexes of record removal.
|
|
4864
|
+
* Returns map of query hash to change type for affected queries.
|
|
4865
|
+
*
|
|
4866
|
+
* @param key - Record key
|
|
4867
|
+
* @param record - Removed record value
|
|
4868
|
+
* @returns Map of query hash to change type
|
|
4869
|
+
*/
|
|
4870
|
+
onRecordRemoved(key: K, record: V): Map<string, StandingQueryChange>;
|
|
4871
|
+
/**
|
|
4872
|
+
* Get all registered queries.
|
|
4873
|
+
*
|
|
4874
|
+
* @returns Array of registered queries
|
|
4875
|
+
*/
|
|
4876
|
+
getRegisteredQueries(): Query[];
|
|
4877
|
+
/**
|
|
4878
|
+
* Get all query hashes.
|
|
4879
|
+
*
|
|
4880
|
+
* @returns Array of query hashes
|
|
4881
|
+
*/
|
|
4882
|
+
getQueryHashes(): string[];
|
|
4883
|
+
/**
|
|
4884
|
+
* Get statistics about the registry.
|
|
4885
|
+
*
|
|
4886
|
+
* @returns Registry statistics
|
|
4887
|
+
*/
|
|
4888
|
+
getStats(): StandingQueryRegistryStats;
|
|
4889
|
+
/**
|
|
4890
|
+
* Clear all indexes.
|
|
4891
|
+
*/
|
|
4892
|
+
clear(): void;
|
|
4893
|
+
/**
|
|
4894
|
+
* Get number of registered indexes.
|
|
4895
|
+
*/
|
|
4896
|
+
get size(): number;
|
|
4897
|
+
/**
|
|
4898
|
+
* Compute hash for a query.
|
|
4899
|
+
* Used as key in indexes map.
|
|
4900
|
+
*/
|
|
4901
|
+
hashQuery(query: Query): string;
|
|
4902
|
+
}
|
|
4903
|
+
|
|
4904
|
+
/**
|
|
4905
|
+
* QueryOptimizer Implementation
|
|
4906
|
+
*
|
|
4907
|
+
* Cost-based query optimizer for the Query Engine.
|
|
4908
|
+
* Selects optimal index and execution strategy for queries.
|
|
4909
|
+
*
|
|
4910
|
+
* Algorithm based on CQEngine CollectionQueryEngine:
|
|
4911
|
+
* - StandingQueryIndex: Check first (lowest cost = 10)
|
|
4912
|
+
* - AND queries: "smallest first" strategy - sort by merge cost, iterate smallest
|
|
4913
|
+
* - OR queries: Union all results with deduplication
|
|
4914
|
+
* - NOT queries: Get all keys, subtract matching keys
|
|
4915
|
+
*
|
|
4916
|
+
* @module query/QueryOptimizer
|
|
4917
|
+
*/
|
|
4918
|
+
|
|
4919
|
+
/**
|
|
4920
|
+
* Options for creating a QueryOptimizer.
|
|
4921
|
+
*/
|
|
4922
|
+
interface QueryOptimizerOptions<K, V> {
|
|
4923
|
+
/** Index registry for attribute-based indexes */
|
|
4924
|
+
indexRegistry: IndexRegistry<K, V>;
|
|
4925
|
+
/** Standing query registry for pre-computed queries (optional) */
|
|
4926
|
+
standingQueryRegistry?: StandingQueryRegistry<K, V>;
|
|
4927
|
+
}
|
|
4928
|
+
/**
|
|
4929
|
+
* Cost-based query optimizer.
|
|
4930
|
+
* Selects optimal index and execution strategy for queries.
|
|
4931
|
+
*
|
|
4932
|
+
* K = record key type, V = record value type
|
|
4933
|
+
*/
|
|
4934
|
+
declare class QueryOptimizer<K, V> {
|
|
4935
|
+
private readonly indexRegistry;
|
|
4936
|
+
private readonly standingQueryRegistry?;
|
|
4937
|
+
/**
|
|
4938
|
+
* Create a QueryOptimizer.
|
|
4939
|
+
*
|
|
4940
|
+
* @param indexRegistryOrOptions - IndexRegistry or options object
|
|
4941
|
+
* @param standingQueryRegistry - Optional StandingQueryRegistry (deprecated, use options)
|
|
4942
|
+
*/
|
|
4943
|
+
constructor(indexRegistryOrOptions: IndexRegistry<K, V> | QueryOptimizerOptions<K, V>, standingQueryRegistry?: StandingQueryRegistry<K, V>);
|
|
4944
|
+
/**
|
|
4945
|
+
* Optimize a query and return an execution plan.
|
|
4946
|
+
*
|
|
4947
|
+
* Optimization order (by cost):
|
|
4948
|
+
* 1. StandingQueryIndex (cost: 10) - pre-computed results
|
|
4949
|
+
* 2. Other indexes via optimizeNode
|
|
4950
|
+
*
|
|
4951
|
+
* @param query - Query to optimize
|
|
4952
|
+
* @returns Query execution plan
|
|
4953
|
+
*/
|
|
4954
|
+
optimize(query: Query): QueryPlan;
|
|
4955
|
+
/**
|
|
4956
|
+
* Optimize a query with sort/limit/offset options.
|
|
4957
|
+
*
|
|
4958
|
+
* @param query - Query to optimize
|
|
4959
|
+
* @param options - Query options (sort, limit, offset)
|
|
4960
|
+
* @returns Query execution plan with options
|
|
4961
|
+
*/
|
|
4962
|
+
optimizeWithOptions(query: Query, options: QueryOptions): QueryPlan;
|
|
4963
|
+
/**
|
|
4964
|
+
* Optimize a single query node.
|
|
4965
|
+
*/
|
|
4966
|
+
private optimizeNode;
|
|
4967
|
+
/**
|
|
4968
|
+
* Optimize a simple (attribute-based) query.
|
|
4969
|
+
*/
|
|
4970
|
+
private optimizeSimple;
|
|
4971
|
+
/**
|
|
4972
|
+
* Optimize a logical (AND/OR/NOT) query.
|
|
4973
|
+
*/
|
|
4974
|
+
private optimizeLogical;
|
|
4975
|
+
/**
|
|
4976
|
+
* Optimize AND query.
|
|
4977
|
+
* Strategy: Find child with lowest cost, use as base, filter with rest.
|
|
4978
|
+
*
|
|
4979
|
+
* CQEngine "smallest first" strategy:
|
|
4980
|
+
* 1. Sort children by merge cost
|
|
4981
|
+
* 2. Use intersection if multiple indexes available
|
|
4982
|
+
* 3. Apply remaining predicates as filters
|
|
4983
|
+
*/
|
|
4984
|
+
private optimizeAnd;
|
|
4985
|
+
/**
|
|
4986
|
+
* Optimize OR query.
|
|
4987
|
+
* Strategy: Union of all child results with deduplication.
|
|
4988
|
+
*/
|
|
4989
|
+
private optimizeOr;
|
|
4990
|
+
/**
|
|
4991
|
+
* Optimize NOT query.
|
|
4992
|
+
* Strategy: Get all keys, subtract matching keys.
|
|
4993
|
+
*/
|
|
4994
|
+
private optimizeNot;
|
|
4995
|
+
/**
|
|
4996
|
+
* Map query type to index query type.
|
|
4997
|
+
* Some query types have different names in indexes.
|
|
4998
|
+
*/
|
|
4999
|
+
private mapQueryType;
|
|
5000
|
+
/**
|
|
5001
|
+
* Build an IndexQuery from a SimpleQueryNode.
|
|
5002
|
+
*/
|
|
5003
|
+
private buildIndexQuery;
|
|
5004
|
+
/**
|
|
5005
|
+
* Estimate the execution cost of a plan step.
|
|
5006
|
+
*/
|
|
5007
|
+
private estimateCost;
|
|
5008
|
+
/**
|
|
5009
|
+
* Check if a plan step uses any indexes.
|
|
5010
|
+
*/
|
|
5011
|
+
private usesIndexes;
|
|
5012
|
+
}
|
|
5013
|
+
|
|
5014
|
+
/**
|
|
5015
|
+
* LiveQueryManager Implementation
|
|
5016
|
+
*
|
|
5017
|
+
* Manages live query subscriptions using StandingQueryIndexes.
|
|
5018
|
+
* Provides reactive updates when data changes.
|
|
5019
|
+
*
|
|
5020
|
+
* Features:
|
|
5021
|
+
* - Initial results on subscribe
|
|
5022
|
+
* - Delta updates on record changes
|
|
5023
|
+
* - Shared indexes for identical queries
|
|
5024
|
+
* - Automatic cleanup on unsubscribe
|
|
5025
|
+
*
|
|
5026
|
+
* @module query/LiveQueryManager
|
|
5027
|
+
*/
|
|
5028
|
+
|
|
5029
|
+
/**
|
|
5030
|
+
* Initial results event sent when subscribing.
|
|
5031
|
+
*/
|
|
5032
|
+
interface LiveQueryInitialEvent<K> {
|
|
5033
|
+
type: 'initial';
|
|
5034
|
+
query: Query;
|
|
5035
|
+
results: K[];
|
|
5036
|
+
}
|
|
5037
|
+
/**
|
|
5038
|
+
* Delta event sent when data changes.
|
|
5039
|
+
*/
|
|
5040
|
+
interface LiveQueryDeltaEvent<K, V> {
|
|
5041
|
+
type: 'delta';
|
|
5042
|
+
query: Query;
|
|
5043
|
+
key: K;
|
|
5044
|
+
record: V;
|
|
5045
|
+
change: StandingQueryChange;
|
|
5046
|
+
operation: 'added' | 'updated' | 'removed';
|
|
5047
|
+
newResultCount: number;
|
|
5048
|
+
}
|
|
5049
|
+
/**
|
|
5050
|
+
* Union type for all live query events.
|
|
5051
|
+
*/
|
|
5052
|
+
type LiveQueryEvent<K, V> = LiveQueryInitialEvent<K> | LiveQueryDeltaEvent<K, V>;
|
|
5053
|
+
/**
|
|
5054
|
+
* Callback for live query events.
|
|
5055
|
+
*/
|
|
5056
|
+
type LiveQueryCallback<K, V> = (event: LiveQueryEvent<K, V>) => void;
|
|
5057
|
+
/**
|
|
5058
|
+
* Options for creating a LiveQueryManager.
|
|
5059
|
+
*/
|
|
5060
|
+
interface LiveQueryManagerOptions<K, V> {
|
|
5061
|
+
/** Function to get record by key */
|
|
5062
|
+
getRecord: (key: K) => V | undefined;
|
|
5063
|
+
/** Function to get all entries for building index */
|
|
5064
|
+
getAllEntries: () => Iterable<[K, V]>;
|
|
5065
|
+
}
|
|
5066
|
+
/**
|
|
5067
|
+
* Manages live query subscriptions using StandingQueryIndexes.
|
|
5068
|
+
* Provides reactive updates when data changes.
|
|
5069
|
+
*
|
|
5070
|
+
* K = record key type, V = record value type
|
|
5071
|
+
*/
|
|
5072
|
+
declare class LiveQueryManager<K, V> {
|
|
5073
|
+
private registry;
|
|
5074
|
+
/** Subscription callbacks by query hash */
|
|
5075
|
+
private subscriptions;
|
|
5076
|
+
constructor(options: LiveQueryManagerOptions<K, V>);
|
|
5077
|
+
/**
|
|
5078
|
+
* Subscribe to a live query.
|
|
5079
|
+
* Sends initial results immediately, then delta updates on changes.
|
|
5080
|
+
*
|
|
5081
|
+
* @param query - Query to subscribe to
|
|
5082
|
+
* @param callback - Callback for query events
|
|
5083
|
+
* @returns Unsubscribe function
|
|
5084
|
+
*/
|
|
5085
|
+
subscribe(query: Query, callback: LiveQueryCallback<K, V>): () => void;
|
|
5086
|
+
/**
|
|
5087
|
+
* Get current results for a query (snapshot).
|
|
5088
|
+
* Does not subscribe to updates.
|
|
5089
|
+
*
|
|
5090
|
+
* @param query - Query to execute
|
|
5091
|
+
* @returns Array of matching keys
|
|
5092
|
+
*/
|
|
5093
|
+
getResults(query: Query): K[];
|
|
5094
|
+
/**
|
|
5095
|
+
* Check if a query has active subscriptions.
|
|
5096
|
+
*
|
|
5097
|
+
* @param query - Query to check
|
|
5098
|
+
* @returns true if query has subscribers
|
|
5099
|
+
*/
|
|
5100
|
+
hasSubscribers(query: Query): boolean;
|
|
5101
|
+
/**
|
|
5102
|
+
* Get subscriber count for a query.
|
|
5103
|
+
*
|
|
5104
|
+
* @param query - Query to check
|
|
5105
|
+
* @returns Number of subscribers
|
|
5106
|
+
*/
|
|
5107
|
+
getSubscriberCount(query: Query): number;
|
|
5108
|
+
/**
|
|
5109
|
+
* Notify of record addition.
|
|
5110
|
+
* Triggers subscription callbacks for affected queries.
|
|
5111
|
+
*
|
|
5112
|
+
* @param key - Record key
|
|
5113
|
+
* @param record - New record value
|
|
5114
|
+
*/
|
|
5115
|
+
onRecordAdded(key: K, record: V): void;
|
|
5116
|
+
/**
|
|
5117
|
+
* Notify of record update.
|
|
5118
|
+
* Triggers subscription callbacks for affected queries.
|
|
5119
|
+
*
|
|
5120
|
+
* @param key - Record key
|
|
5121
|
+
* @param oldRecord - Previous record value
|
|
5122
|
+
* @param newRecord - New record value
|
|
5123
|
+
*/
|
|
5124
|
+
onRecordUpdated(key: K, oldRecord: V, newRecord: V): void;
|
|
5125
|
+
/**
|
|
5126
|
+
* Notify of record removal.
|
|
5127
|
+
* Triggers subscription callbacks for affected queries.
|
|
5128
|
+
*
|
|
5129
|
+
* @param key - Record key
|
|
5130
|
+
* @param record - Removed record value
|
|
5131
|
+
*/
|
|
5132
|
+
onRecordRemoved(key: K, record: V): void;
|
|
5133
|
+
/**
|
|
5134
|
+
* Notify subscribers of changes.
|
|
5135
|
+
*/
|
|
5136
|
+
private notifySubscribers;
|
|
5137
|
+
/**
|
|
5138
|
+
* Get the underlying registry for direct access.
|
|
5139
|
+
* Useful for testing and debugging.
|
|
5140
|
+
*
|
|
5141
|
+
* @returns StandingQueryRegistry instance
|
|
5142
|
+
*/
|
|
5143
|
+
getRegistry(): StandingQueryRegistry<K, V>;
|
|
5144
|
+
/**
|
|
5145
|
+
* Get all active query hashes.
|
|
5146
|
+
*
|
|
5147
|
+
* @returns Array of query hashes with active subscriptions
|
|
5148
|
+
*/
|
|
5149
|
+
getActiveQueries(): string[];
|
|
5150
|
+
/**
|
|
5151
|
+
* Get statistics about the manager.
|
|
5152
|
+
*
|
|
5153
|
+
* @returns Statistics object
|
|
5154
|
+
*/
|
|
5155
|
+
getStats(): LiveQueryManagerStats;
|
|
5156
|
+
/**
|
|
5157
|
+
* Clear all subscriptions and indexes.
|
|
5158
|
+
*/
|
|
5159
|
+
clear(): void;
|
|
5160
|
+
}
|
|
5161
|
+
/**
|
|
5162
|
+
* Statistics about the LiveQueryManager.
|
|
5163
|
+
*/
|
|
5164
|
+
interface LiveQueryManagerStats extends StandingQueryRegistryStats {
|
|
5165
|
+
/** Number of active queries with subscribers */
|
|
5166
|
+
activeQueries: number;
|
|
5167
|
+
/** Total number of subscribers across all queries */
|
|
5168
|
+
totalSubscribers: number;
|
|
5169
|
+
}
|
|
5170
|
+
|
|
5171
|
+
/**
|
|
5172
|
+
* Types for Adaptive Indexing System (Phase 8.02)
|
|
5173
|
+
*
|
|
5174
|
+
* Defines interfaces for query pattern tracking, index suggestions,
|
|
5175
|
+
* and auto-indexing configuration.
|
|
5176
|
+
*
|
|
5177
|
+
* @module query/adaptive/types
|
|
5178
|
+
*/
|
|
5179
|
+
/**
|
|
5180
|
+
* Query type for pattern tracking.
|
|
5181
|
+
* Matches the query types from QueryTypes.ts and indexes/types.ts
|
|
5182
|
+
*/
|
|
5183
|
+
type TrackedQueryType = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'in' | 'has' | 'contains' | 'containsAll' | 'containsAny';
|
|
5184
|
+
/**
|
|
5185
|
+
* Statistics for a single attribute + query type combination.
|
|
5186
|
+
*/
|
|
5187
|
+
interface QueryStatistics {
|
|
5188
|
+
/** Attribute name being queried */
|
|
5189
|
+
attribute: string;
|
|
5190
|
+
/** Type of query (eq, gt, between, etc.) */
|
|
5191
|
+
queryType: TrackedQueryType;
|
|
5192
|
+
/** Number of times this pattern was queried */
|
|
5193
|
+
queryCount: number;
|
|
5194
|
+
/** Cumulative execution time in milliseconds */
|
|
5195
|
+
totalCost: number;
|
|
5196
|
+
/** Average execution time per query */
|
|
5197
|
+
averageCost: number;
|
|
5198
|
+
/** Timestamp of last query */
|
|
5199
|
+
lastQueried: number;
|
|
5200
|
+
/** Estimated result size (max observed) */
|
|
5201
|
+
estimatedCardinality: number;
|
|
5202
|
+
/** Whether an index exists for this attribute */
|
|
5203
|
+
hasIndex: boolean;
|
|
5204
|
+
}
|
|
5205
|
+
/**
|
|
5206
|
+
* Index type recommendation.
|
|
5207
|
+
*/
|
|
5208
|
+
type RecommendedIndexType = 'hash' | 'navigable' | 'inverted';
|
|
5209
|
+
/**
|
|
5210
|
+
* Priority level for index suggestions.
|
|
5211
|
+
*/
|
|
5212
|
+
type SuggestionPriority = 'high' | 'medium' | 'low';
|
|
5213
|
+
/**
|
|
5214
|
+
* Index suggestion generated by IndexAdvisor.
|
|
5215
|
+
*/
|
|
5216
|
+
interface IndexSuggestion {
|
|
5217
|
+
/** Attribute to index */
|
|
5218
|
+
attribute: string;
|
|
5219
|
+
/** Recommended index type */
|
|
5220
|
+
indexType: RecommendedIndexType;
|
|
5221
|
+
/** Human-readable explanation */
|
|
5222
|
+
reason: string;
|
|
5223
|
+
/** Expected performance improvement multiplier */
|
|
5224
|
+
estimatedBenefit: number;
|
|
5225
|
+
/** Estimated memory overhead in bytes */
|
|
5226
|
+
estimatedCost: number;
|
|
5227
|
+
/** Priority based on query patterns */
|
|
5228
|
+
priority: SuggestionPriority;
|
|
5229
|
+
/** Query count that triggered this suggestion */
|
|
5230
|
+
queryCount: number;
|
|
5231
|
+
/** Average query cost in milliseconds */
|
|
5232
|
+
averageCost: number;
|
|
5233
|
+
}
|
|
5234
|
+
/**
|
|
5235
|
+
* Options for getting index suggestions.
|
|
5236
|
+
*/
|
|
5237
|
+
interface IndexSuggestionOptions {
|
|
5238
|
+
/** Minimum query count to consider (default: 10) */
|
|
5239
|
+
minQueryCount?: number;
|
|
5240
|
+
/** Minimum average cost in ms to consider (default: 1) */
|
|
5241
|
+
minAverageCost?: number;
|
|
5242
|
+
/** Whether to exclude already indexed attributes (default: true) */
|
|
5243
|
+
excludeExistingIndexes?: boolean;
|
|
5244
|
+
/** Maximum number of suggestions to return (default: unlimited) */
|
|
5245
|
+
maxSuggestions?: number;
|
|
5246
|
+
}
|
|
5247
|
+
/**
|
|
5248
|
+
* Configuration for Index Advisor.
|
|
5249
|
+
*/
|
|
5250
|
+
interface AdvisorConfig {
|
|
5251
|
+
/** Enable advisor mode (default: true) */
|
|
5252
|
+
enabled: boolean;
|
|
5253
|
+
/** Minimum query count before suggesting (default: 10) */
|
|
5254
|
+
minQueryCount?: number;
|
|
5255
|
+
/** Minimum average cost in ms to suggest (default: 1) */
|
|
5256
|
+
minAverageCost?: number;
|
|
5257
|
+
}
|
|
5258
|
+
/**
|
|
5259
|
+
* Callback for index creation events.
|
|
5260
|
+
*/
|
|
5261
|
+
type IndexCreatedCallback = (attribute: string, indexType: RecommendedIndexType) => void;
|
|
5262
|
+
/**
|
|
5263
|
+
* Configuration for Auto-Index Manager.
|
|
5264
|
+
*/
|
|
5265
|
+
interface AutoIndexConfig {
|
|
5266
|
+
/** Enable auto-indexing (default: false) */
|
|
5267
|
+
enabled: boolean;
|
|
5268
|
+
/** Number of queries before auto-creating index (default: 10) */
|
|
5269
|
+
threshold?: number;
|
|
5270
|
+
/** Maximum number of auto-created indexes (default: 20) */
|
|
5271
|
+
maxIndexes?: number;
|
|
5272
|
+
/** Callback when index is automatically created */
|
|
5273
|
+
onIndexCreated?: IndexCreatedCallback;
|
|
5274
|
+
}
|
|
5275
|
+
/**
|
|
5276
|
+
* Default indexing strategy.
|
|
5277
|
+
* - 'none': No automatic indexing (default)
|
|
5278
|
+
* - 'scalar': Index all top-level scalar (primitive) fields
|
|
5279
|
+
* - 'all': Index all fields including nested (not recommended)
|
|
5280
|
+
*/
|
|
5281
|
+
type DefaultIndexingStrategy = 'none' | 'scalar' | 'all';
|
|
5282
|
+
/**
|
|
5283
|
+
* Complete adaptive indexing configuration.
|
|
5284
|
+
*/
|
|
5285
|
+
interface AdaptiveIndexingConfig {
|
|
5286
|
+
/** Index Advisor configuration */
|
|
5287
|
+
advisor?: AdvisorConfig;
|
|
5288
|
+
/** Auto-Index Manager configuration */
|
|
5289
|
+
autoIndex?: AutoIndexConfig;
|
|
5290
|
+
}
|
|
5291
|
+
/**
|
|
5292
|
+
* Extended options for IndexedLWWMap/IndexedORMap.
|
|
5293
|
+
*/
|
|
5294
|
+
interface IndexedMapOptions {
|
|
5295
|
+
/** Adaptive indexing configuration */
|
|
5296
|
+
adaptiveIndexing?: AdaptiveIndexingConfig;
|
|
5297
|
+
/** Default indexing strategy (default: 'none') */
|
|
5298
|
+
defaultIndexing?: DefaultIndexingStrategy;
|
|
5299
|
+
}
|
|
5300
|
+
|
|
5301
|
+
/**
|
|
5302
|
+
* QueryPatternTracker (Phase 8.02.1)
|
|
5303
|
+
*
|
|
5304
|
+
* Collects runtime statistics on query execution patterns.
|
|
5305
|
+
* Used by IndexAdvisor to generate index suggestions.
|
|
5306
|
+
*
|
|
5307
|
+
* Features:
|
|
5308
|
+
* - Tracks query count, cost, and cardinality per attribute
|
|
5309
|
+
* - Low overhead (< 1% of query time)
|
|
5310
|
+
* - Optional sampling for high-throughput scenarios
|
|
5311
|
+
* - Memory-bounded (circular buffer for old stats)
|
|
5312
|
+
*
|
|
5313
|
+
* @module query/adaptive/QueryPatternTracker
|
|
5314
|
+
*/
|
|
5315
|
+
|
|
5316
|
+
/**
|
|
5317
|
+
* Options for QueryPatternTracker.
|
|
5318
|
+
*/
|
|
5319
|
+
interface QueryPatternTrackerOptions {
|
|
5320
|
+
/**
|
|
5321
|
+
* Sampling rate: 1 = track all queries, N = track 1 in N queries.
|
|
5322
|
+
* Higher values reduce overhead but decrease accuracy.
|
|
5323
|
+
* Default: 1 (track all)
|
|
5324
|
+
*/
|
|
5325
|
+
samplingRate?: number;
|
|
5326
|
+
/**
|
|
5327
|
+
* Maximum number of unique attribute+queryType combinations to track.
|
|
5328
|
+
* Prevents unbounded memory growth.
|
|
5329
|
+
* Default: 1000
|
|
5330
|
+
*/
|
|
5331
|
+
maxTrackedPatterns?: number;
|
|
5332
|
+
/**
|
|
5333
|
+
* Time-to-live for statistics in milliseconds.
|
|
5334
|
+
* Statistics older than this are considered stale.
|
|
5335
|
+
* Default: 24 hours
|
|
5336
|
+
*/
|
|
5337
|
+
statsTtl?: number;
|
|
5338
|
+
}
|
|
5339
|
+
/**
|
|
5340
|
+
* QueryPatternTracker collects runtime statistics on query execution.
|
|
5341
|
+
*
|
|
5342
|
+
* @example
|
|
5343
|
+
* ```typescript
|
|
5344
|
+
* const tracker = new QueryPatternTracker();
|
|
5345
|
+
*
|
|
5346
|
+
* // Record queries during execution
|
|
5347
|
+
* tracker.recordQuery('category', 'eq', 5.2, 100, false);
|
|
5348
|
+
* tracker.recordQuery('category', 'eq', 4.8, 100, false);
|
|
5349
|
+
*
|
|
5350
|
+
* // Get statistics
|
|
5351
|
+
* const stats = tracker.getStatistics();
|
|
5352
|
+
* // [{ attribute: 'category', queryType: 'eq', queryCount: 2, averageCost: 5.0, ... }]
|
|
5353
|
+
* ```
|
|
5354
|
+
*/
|
|
5355
|
+
declare class QueryPatternTracker {
|
|
5356
|
+
private stats;
|
|
5357
|
+
private queryCounter;
|
|
5358
|
+
private readonly samplingRate;
|
|
5359
|
+
private readonly maxTrackedPatterns;
|
|
5360
|
+
private readonly statsTtl;
|
|
5361
|
+
constructor(options?: QueryPatternTrackerOptions);
|
|
5362
|
+
/**
|
|
5363
|
+
* Record a query execution for pattern tracking.
|
|
5364
|
+
*
|
|
5365
|
+
* @param attribute - The attribute being queried
|
|
5366
|
+
* @param queryType - The type of query (eq, gt, between, etc.)
|
|
5367
|
+
* @param executionTime - Query execution time in milliseconds
|
|
5368
|
+
* @param resultSize - Number of results returned
|
|
5369
|
+
* @param hasIndex - Whether an index was used
|
|
5370
|
+
*/
|
|
5371
|
+
recordQuery(attribute: string, queryType: TrackedQueryType, executionTime: number, resultSize: number, hasIndex: boolean): void;
|
|
5372
|
+
/**
|
|
5373
|
+
* Get all query statistics.
|
|
5374
|
+
*
|
|
5375
|
+
* @returns Array of query statistics, sorted by query count descending
|
|
5376
|
+
*/
|
|
5377
|
+
getStatistics(): QueryStatistics[];
|
|
5378
|
+
/**
|
|
5379
|
+
* Get statistics for a specific attribute.
|
|
5380
|
+
*
|
|
5381
|
+
* @param attribute - The attribute name
|
|
5382
|
+
* @returns Array of query statistics for this attribute
|
|
5383
|
+
*/
|
|
5384
|
+
getAttributeStats(attribute: string): QueryStatistics[];
|
|
5385
|
+
/**
|
|
5386
|
+
* Get statistics for a specific attribute and query type.
|
|
5387
|
+
*
|
|
5388
|
+
* @param attribute - The attribute name
|
|
5389
|
+
* @param queryType - The query type
|
|
5390
|
+
* @returns Query statistics or undefined
|
|
5391
|
+
*/
|
|
5392
|
+
getStats(attribute: string, queryType: TrackedQueryType): QueryStatistics | undefined;
|
|
5393
|
+
/**
|
|
5394
|
+
* Check if an attribute has been queried.
|
|
5395
|
+
*
|
|
5396
|
+
* @param attribute - The attribute name
|
|
5397
|
+
* @returns True if the attribute has query statistics
|
|
5398
|
+
*/
|
|
5399
|
+
hasStats(attribute: string): boolean;
|
|
5400
|
+
/**
|
|
5401
|
+
* Get the total number of queries recorded.
|
|
5402
|
+
*
|
|
5403
|
+
* @returns Total query count across all patterns
|
|
5404
|
+
*/
|
|
5405
|
+
getTotalQueryCount(): number;
|
|
5406
|
+
/**
|
|
5407
|
+
* Get the number of unique attribute+queryType patterns tracked.
|
|
5408
|
+
*
|
|
5409
|
+
* @returns Number of unique patterns
|
|
5410
|
+
*/
|
|
5411
|
+
getPatternCount(): number;
|
|
5412
|
+
/**
|
|
5413
|
+
* Update index status for an attribute.
|
|
5414
|
+
* Called when an index is added or removed.
|
|
5415
|
+
*
|
|
5416
|
+
* @param attribute - The attribute name
|
|
5417
|
+
* @param hasIndex - Whether an index now exists
|
|
5418
|
+
*/
|
|
5419
|
+
updateIndexStatus(attribute: string, hasIndex: boolean): void;
|
|
5420
|
+
/**
|
|
5421
|
+
* Reset query count for an attribute after index creation.
|
|
5422
|
+
* This prevents immediate re-suggestion of the same index.
|
|
5423
|
+
*
|
|
5424
|
+
* @param attribute - The attribute name
|
|
5425
|
+
*/
|
|
5426
|
+
resetAttributeStats(attribute: string): void;
|
|
5427
|
+
/**
|
|
5428
|
+
* Clear all statistics.
|
|
5429
|
+
*/
|
|
5430
|
+
clear(): void;
|
|
5431
|
+
/**
|
|
5432
|
+
* Get a summary of tracking overhead.
|
|
5433
|
+
*
|
|
5434
|
+
* @returns Tracking overhead info
|
|
5435
|
+
*/
|
|
5436
|
+
getTrackingInfo(): {
|
|
5437
|
+
patternsTracked: number;
|
|
5438
|
+
totalQueries: number;
|
|
5439
|
+
samplingRate: number;
|
|
5440
|
+
memoryEstimate: number;
|
|
5441
|
+
};
|
|
5442
|
+
/**
|
|
5443
|
+
* Evict the oldest (least recently queried) entry.
|
|
5444
|
+
*/
|
|
5445
|
+
private evictOldest;
|
|
5446
|
+
/**
|
|
5447
|
+
* Prune stale statistics older than TTL.
|
|
5448
|
+
*/
|
|
5449
|
+
private pruneStale;
|
|
5450
|
+
}
|
|
5451
|
+
|
|
5452
|
+
/**
|
|
5453
|
+
* IndexAdvisor (Phase 8.02.2)
|
|
5454
|
+
*
|
|
5455
|
+
* Analyzes query patterns and generates index suggestions.
|
|
5456
|
+
* Used in production mode to help developers optimize their indexes.
|
|
5457
|
+
*
|
|
5458
|
+
* Features:
|
|
5459
|
+
* - Cost/benefit analysis for index suggestions
|
|
5460
|
+
* - Automatic index type selection based on query type
|
|
5461
|
+
* - Priority-based ranking of suggestions
|
|
5462
|
+
* - Memory cost estimation
|
|
5463
|
+
*
|
|
5464
|
+
* @module query/adaptive/IndexAdvisor
|
|
5465
|
+
*/
|
|
5466
|
+
|
|
5467
|
+
/**
|
|
5468
|
+
* IndexAdvisor analyzes query patterns and generates index suggestions.
|
|
5469
|
+
*
|
|
5470
|
+
* @example
|
|
5471
|
+
* ```typescript
|
|
5472
|
+
* const tracker = new QueryPatternTracker();
|
|
5473
|
+
* const advisor = new IndexAdvisor(tracker);
|
|
5474
|
+
*
|
|
5475
|
+
* // After application runs...
|
|
5476
|
+
* const suggestions = advisor.getSuggestions();
|
|
5477
|
+
* // [
|
|
5478
|
+
* // {
|
|
5479
|
+
* // attribute: 'category',
|
|
5480
|
+
* // indexType: 'hash',
|
|
5481
|
+
* // reason: 'Queried 1000× with average cost 5.2ms. Expected 500× speedup.',
|
|
5482
|
+
* // priority: 'high'
|
|
5483
|
+
* // }
|
|
5484
|
+
* // ]
|
|
5485
|
+
* ```
|
|
5486
|
+
*/
|
|
5487
|
+
declare class IndexAdvisor {
|
|
5488
|
+
private readonly tracker;
|
|
5489
|
+
constructor(tracker: QueryPatternTracker);
|
|
5490
|
+
/**
|
|
5491
|
+
* Get index suggestions based on query patterns.
|
|
5492
|
+
*
|
|
5493
|
+
* @param options - Suggestion options
|
|
5494
|
+
* @returns Array of index suggestions sorted by priority
|
|
5495
|
+
*/
|
|
5496
|
+
getSuggestions(options?: IndexSuggestionOptions): IndexSuggestion[];
|
|
5497
|
+
/**
|
|
5498
|
+
* Get a suggestion for a specific attribute.
|
|
5499
|
+
*
|
|
5500
|
+
* @param attribute - The attribute name
|
|
5501
|
+
* @returns Index suggestion or null if not recommended
|
|
5502
|
+
*/
|
|
5503
|
+
getSuggestionForAttribute(attribute: string): IndexSuggestion | null;
|
|
5504
|
+
/**
|
|
5505
|
+
* Check if an attribute should be indexed based on patterns.
|
|
5506
|
+
*
|
|
5507
|
+
* @param attribute - The attribute name
|
|
5508
|
+
* @param threshold - Minimum query count threshold
|
|
5509
|
+
* @returns True if attribute should be indexed
|
|
5510
|
+
*/
|
|
5511
|
+
shouldIndex(attribute: string, threshold?: number): boolean;
|
|
5512
|
+
/**
|
|
5513
|
+
* Get recommended index type for a query type.
|
|
5514
|
+
*
|
|
5515
|
+
* @param queryType - The query type
|
|
5516
|
+
* @returns Recommended index type or null if not indexable
|
|
5517
|
+
*/
|
|
5518
|
+
getRecommendedIndexType(queryType: TrackedQueryType): RecommendedIndexType | null;
|
|
5519
|
+
/**
|
|
5520
|
+
* Group statistics by attribute.
|
|
5521
|
+
*/
|
|
5522
|
+
private groupByAttribute;
|
|
5523
|
+
/**
|
|
5524
|
+
* Find the best (most beneficial) pattern for an attribute.
|
|
5525
|
+
*/
|
|
5526
|
+
private findBestPattern;
|
|
5527
|
+
/**
|
|
5528
|
+
* Generate a suggestion for a query pattern.
|
|
5529
|
+
*/
|
|
5530
|
+
private generateSuggestion;
|
|
5531
|
+
/**
|
|
5532
|
+
* Select appropriate index type based on query type.
|
|
5533
|
+
*/
|
|
5534
|
+
private selectIndexType;
|
|
5535
|
+
/**
|
|
5536
|
+
* Count how many query patterns would benefit from an index type.
|
|
5537
|
+
*/
|
|
5538
|
+
private countBenefitingPatterns;
|
|
5539
|
+
/**
|
|
5540
|
+
* Estimate performance benefit of adding an index.
|
|
5541
|
+
*
|
|
5542
|
+
* Heuristic based on:
|
|
5543
|
+
* - Full scan vs indexed: typically 100-1000× speedup
|
|
5544
|
+
* - Query frequency amplifies benefit
|
|
5545
|
+
*/
|
|
5546
|
+
private estimateBenefit;
|
|
5547
|
+
/**
|
|
5548
|
+
* Estimate memory cost of adding an index.
|
|
5549
|
+
*/
|
|
5550
|
+
private estimateMemoryCost;
|
|
5551
|
+
/**
|
|
5552
|
+
* Calculate priority based on query patterns and benefit.
|
|
5553
|
+
*/
|
|
5554
|
+
private calculatePriority;
|
|
5555
|
+
/**
|
|
5556
|
+
* Generate human-readable reason for the suggestion.
|
|
5557
|
+
*/
|
|
5558
|
+
private generateReason;
|
|
5559
|
+
}
|
|
5560
|
+
|
|
5561
|
+
/**
|
|
5562
|
+
* AutoIndexManager (Phase 8.02.3)
|
|
5563
|
+
*
|
|
5564
|
+
* Automatically creates indexes based on query patterns.
|
|
5565
|
+
* Intended for development mode to simplify index management.
|
|
5566
|
+
*
|
|
5567
|
+
* Features:
|
|
5568
|
+
* - Automatic index creation after threshold queries
|
|
5569
|
+
* - Safety limits to prevent memory exhaustion
|
|
5570
|
+
* - Callback notifications for index creation events
|
|
5571
|
+
* - Integration with IndexAdvisor for type selection
|
|
5572
|
+
*
|
|
5573
|
+
* @module query/adaptive/AutoIndexManager
|
|
5574
|
+
*/
|
|
5575
|
+
|
|
5576
|
+
/**
|
|
5577
|
+
* Interface for indexed map operations.
|
|
5578
|
+
* Used to decouple AutoIndexManager from IndexedLWWMap/IndexedORMap.
|
|
5579
|
+
*/
|
|
5580
|
+
interface IndexableMap<K, V> {
|
|
5581
|
+
/** Get all current indexes */
|
|
5582
|
+
getIndexes(): {
|
|
5583
|
+
attribute: {
|
|
5584
|
+
name: string;
|
|
5585
|
+
};
|
|
5586
|
+
type: string;
|
|
5587
|
+
}[];
|
|
5588
|
+
/** Check if attribute has an index */
|
|
5589
|
+
hasIndexOn(attributeName: string): boolean;
|
|
5590
|
+
/** Add a hash index */
|
|
5591
|
+
addHashIndex<A>(attribute: Attribute<V, A>): void;
|
|
5592
|
+
/** Add a navigable index */
|
|
5593
|
+
addNavigableIndex<A extends string | number>(attribute: Attribute<V, A>): void;
|
|
5594
|
+
/** Add an inverted index */
|
|
5595
|
+
addInvertedIndex<A extends string>(attribute: Attribute<V, A>): void;
|
|
5596
|
+
}
|
|
5597
|
+
/**
|
|
5598
|
+
* AutoIndexManager automatically creates indexes based on query patterns.
|
|
5599
|
+
*
|
|
5600
|
+
* @example
|
|
5601
|
+
* ```typescript
|
|
5602
|
+
* const manager = new AutoIndexManager(tracker, advisor, {
|
|
5603
|
+
* enabled: true,
|
|
5604
|
+
* threshold: 10,
|
|
5605
|
+
* maxIndexes: 20,
|
|
5606
|
+
* onIndexCreated: (attr, type) => console.log(`Created ${type} on ${attr}`)
|
|
5607
|
+
* });
|
|
5608
|
+
*
|
|
5609
|
+
* manager.registerAttribute(simpleAttribute('category', p => p.category));
|
|
5610
|
+
* manager.setMap(indexedMap);
|
|
5611
|
+
*
|
|
5612
|
+
* // After 10 queries on 'category', index is auto-created
|
|
5613
|
+
* ```
|
|
5614
|
+
*/
|
|
5615
|
+
declare class AutoIndexManager<K, V> {
|
|
5616
|
+
private readonly tracker;
|
|
5617
|
+
private readonly advisor;
|
|
5618
|
+
private readonly config;
|
|
5619
|
+
private readonly attributeQueryCounts;
|
|
5620
|
+
private readonly registeredAttributes;
|
|
5621
|
+
private readonly createdIndexes;
|
|
5622
|
+
private map;
|
|
5623
|
+
constructor(tracker: QueryPatternTracker, advisor: IndexAdvisor, config: AutoIndexConfig);
|
|
5624
|
+
/**
|
|
5625
|
+
* Set the indexed map to create indexes on.
|
|
5626
|
+
*/
|
|
5627
|
+
setMap(map: IndexableMap<K, V>): void;
|
|
5628
|
+
/**
|
|
5629
|
+
* Register an attribute that can be auto-indexed.
|
|
5630
|
+
*
|
|
5631
|
+
* @param attribute - The attribute to register
|
|
5632
|
+
* @param allowedIndexTypes - Optional list of allowed index types
|
|
5633
|
+
*/
|
|
5634
|
+
registerAttribute<A>(attribute: Attribute<V, A>, allowedIndexTypes?: RecommendedIndexType[]): void;
|
|
5635
|
+
/**
|
|
5636
|
+
* Unregister an attribute.
|
|
5637
|
+
*
|
|
5638
|
+
* @param attributeName - Name of attribute to unregister
|
|
5639
|
+
*/
|
|
5640
|
+
unregisterAttribute(attributeName: string): void;
|
|
5641
|
+
/**
|
|
5642
|
+
* Check if an attribute is registered.
|
|
5643
|
+
*
|
|
5644
|
+
* @param attributeName - Name of attribute to check
|
|
5645
|
+
* @returns True if attribute is registered
|
|
5646
|
+
*/
|
|
5647
|
+
hasAttribute(attributeName: string): boolean;
|
|
5648
|
+
/**
|
|
5649
|
+
* Get a registered attribute.
|
|
5650
|
+
*
|
|
5651
|
+
* @param attributeName - Name of attribute
|
|
5652
|
+
* @returns The attribute or undefined
|
|
5653
|
+
*/
|
|
5654
|
+
getAttribute(attributeName: string): Attribute<V, unknown> | undefined;
|
|
5655
|
+
/**
|
|
5656
|
+
* Get all registered attribute names.
|
|
5657
|
+
*
|
|
5658
|
+
* @returns Array of registered attribute names
|
|
5659
|
+
*/
|
|
5660
|
+
getRegisteredAttributeNames(): string[];
|
|
5661
|
+
/**
|
|
5662
|
+
* Called when a query is executed. Tracks patterns and triggers auto-indexing.
|
|
5663
|
+
*
|
|
5664
|
+
* @param attribute - The attribute being queried
|
|
5665
|
+
* @param queryType - The type of query
|
|
5666
|
+
*/
|
|
5667
|
+
onQueryExecuted(attribute: string, queryType: TrackedQueryType): void;
|
|
5668
|
+
/**
|
|
5669
|
+
* Check if we're at the index limit.
|
|
5670
|
+
*
|
|
5671
|
+
* @returns True if max indexes reached
|
|
5672
|
+
*/
|
|
5673
|
+
isAtLimit(): boolean;
|
|
5674
|
+
/**
|
|
5675
|
+
* Get number of auto-created indexes.
|
|
5676
|
+
*
|
|
5677
|
+
* @returns Number of indexes created by this manager
|
|
5678
|
+
*/
|
|
5679
|
+
getAutoCreatedIndexCount(): number;
|
|
5680
|
+
/**
|
|
5681
|
+
* Get remaining index capacity.
|
|
5682
|
+
*
|
|
5683
|
+
* @returns Number of indexes that can still be created
|
|
5684
|
+
*/
|
|
5685
|
+
getRemainingCapacity(): number;
|
|
5686
|
+
/**
|
|
5687
|
+
* Reset query counts (e.g., after clearing data).
|
|
5688
|
+
*/
|
|
5689
|
+
resetCounts(): void;
|
|
5690
|
+
/**
|
|
5691
|
+
* Get current configuration.
|
|
5692
|
+
*/
|
|
5693
|
+
getConfig(): Readonly<AutoIndexConfig>;
|
|
5694
|
+
/**
|
|
5695
|
+
* Update configuration at runtime.
|
|
5696
|
+
*
|
|
5697
|
+
* @param updates - Partial config updates
|
|
5698
|
+
*/
|
|
5699
|
+
updateConfig(updates: Partial<AutoIndexConfig>): void;
|
|
5700
|
+
/**
|
|
5701
|
+
* Try to create an index for the attribute.
|
|
5702
|
+
*/
|
|
5703
|
+
private tryCreateIndex;
|
|
5704
|
+
/**
|
|
5705
|
+
* Create an index on the map.
|
|
5706
|
+
*/
|
|
5707
|
+
private createIndex;
|
|
5708
|
+
}
|
|
5709
|
+
|
|
5710
|
+
/**
|
|
5711
|
+
* IndexedLWWMap Implementation
|
|
5712
|
+
*
|
|
5713
|
+
* LWWMap with index support for O(1) to O(log N) queries.
|
|
5714
|
+
* Wraps LWWMap with indexing capabilities using the Wrapper Pattern.
|
|
5715
|
+
*
|
|
5716
|
+
* Features:
|
|
5717
|
+
* - Hash and Navigable indexes for efficient queries
|
|
5718
|
+
* - Live queries with StandingQueryIndex
|
|
5719
|
+
* - Automatic index updates on CRDT operations
|
|
5720
|
+
* - Cost-based query optimization
|
|
5721
|
+
* - Adaptive indexing with query pattern tracking (Phase 8.02)
|
|
5722
|
+
*
|
|
5723
|
+
* @module IndexedLWWMap
|
|
5724
|
+
*/
|
|
5725
|
+
|
|
5726
|
+
/**
|
|
5727
|
+
* LWWMap with index support for O(1) to O(log N) queries.
|
|
5728
|
+
*
|
|
5729
|
+
* K = key type (extends string for compatibility)
|
|
5730
|
+
* V = value type
|
|
5731
|
+
*/
|
|
5732
|
+
declare class IndexedLWWMap<K extends string, V> extends LWWMap<K, V> {
|
|
5733
|
+
private indexRegistry;
|
|
5734
|
+
private standingQueryRegistry;
|
|
5735
|
+
private liveQueryManager;
|
|
5736
|
+
private queryOptimizer;
|
|
5737
|
+
private readonly queryTracker;
|
|
5738
|
+
private readonly indexAdvisor;
|
|
5739
|
+
private readonly autoIndexManager;
|
|
5740
|
+
private readonly defaultIndexingStrategy;
|
|
5741
|
+
private readonly options;
|
|
5742
|
+
constructor(hlc: HLC, options?: IndexedMapOptions);
|
|
5743
|
+
/**
|
|
5744
|
+
* Add a hash index on an attribute.
|
|
5745
|
+
*
|
|
5746
|
+
* @param attribute - Attribute to index
|
|
5747
|
+
* @returns Created HashIndex
|
|
5748
|
+
*/
|
|
5749
|
+
addHashIndex<A>(attribute: Attribute<V, A>): HashIndex<K, V, A>;
|
|
5750
|
+
/**
|
|
5751
|
+
* Add a navigable index on an attribute.
|
|
5752
|
+
* Navigable indexes support range queries (gt, gte, lt, lte, between).
|
|
5753
|
+
*
|
|
5754
|
+
* @param attribute - Attribute to index
|
|
5755
|
+
* @param comparator - Optional custom comparator
|
|
5756
|
+
* @returns Created NavigableIndex
|
|
5757
|
+
*/
|
|
5758
|
+
addNavigableIndex<A extends string | number>(attribute: Attribute<V, A>, comparator?: (a: A, b: A) => number): NavigableIndex<K, V, A>;
|
|
5759
|
+
/**
|
|
5760
|
+
* Add an inverted index for full-text search on an attribute.
|
|
5761
|
+
* Inverted indexes support text search queries (contains, containsAll, containsAny).
|
|
5762
|
+
*
|
|
5763
|
+
* @param attribute - Text attribute to index
|
|
5764
|
+
* @param pipeline - Optional custom tokenization pipeline
|
|
5765
|
+
* @returns Created InvertedIndex
|
|
5766
|
+
*
|
|
5767
|
+
* @example
|
|
5768
|
+
* ```typescript
|
|
5769
|
+
* const nameAttr = simpleAttribute<Product, string>('name', p => p.name);
|
|
5770
|
+
* products.addInvertedIndex(nameAttr);
|
|
5771
|
+
*
|
|
5772
|
+
* // Search for products containing "wireless"
|
|
5773
|
+
* products.query({ type: 'contains', attribute: 'name', value: 'wireless' });
|
|
5774
|
+
* ```
|
|
5775
|
+
*/
|
|
5776
|
+
addInvertedIndex<A extends string = string>(attribute: Attribute<V, A>, pipeline?: TokenizationPipeline): InvertedIndex<K, V, A>;
|
|
5777
|
+
/**
|
|
5778
|
+
* Add a custom index.
|
|
5779
|
+
*
|
|
5780
|
+
* @param index - Index to add
|
|
5781
|
+
*/
|
|
5782
|
+
addIndex<A>(index: Index<K, V, A>): void;
|
|
5783
|
+
/**
|
|
5784
|
+
* Remove an index.
|
|
5785
|
+
*
|
|
5786
|
+
* @param index - Index to remove
|
|
5787
|
+
* @returns true if index was found and removed
|
|
5788
|
+
*/
|
|
5789
|
+
removeIndex<A>(index: Index<K, V, A>): boolean;
|
|
5790
|
+
/**
|
|
5791
|
+
* Get all indexes.
|
|
5792
|
+
*
|
|
5793
|
+
* @returns Array of all indexes
|
|
5794
|
+
*/
|
|
5795
|
+
getIndexes(): Index<K, V, unknown>[];
|
|
5796
|
+
/**
|
|
5797
|
+
* Check if an attribute is indexed.
|
|
5798
|
+
*
|
|
5799
|
+
* @param attributeName - Attribute name
|
|
5800
|
+
* @returns true if attribute has indexes
|
|
5801
|
+
*/
|
|
5802
|
+
hasIndexOn(attributeName: string): boolean;
|
|
5803
|
+
/**
|
|
5804
|
+
* Build index from existing data.
|
|
5805
|
+
*/
|
|
5806
|
+
private buildIndex;
|
|
5807
|
+
/**
|
|
5808
|
+
* Execute a query using indexes.
|
|
5809
|
+
* Returns lazy ResultSet of matching keys.
|
|
5810
|
+
*
|
|
5811
|
+
* Also tracks query patterns for adaptive indexing (Phase 8.02).
|
|
5812
|
+
*
|
|
5813
|
+
* @param query - Query to execute
|
|
5814
|
+
* @returns ResultSet of matching keys
|
|
5815
|
+
*/
|
|
5816
|
+
query(query: Query): ResultSet<K>;
|
|
5817
|
+
/**
|
|
5818
|
+
* Execute a query and return materialized results.
|
|
5819
|
+
* Returns array of [key, value] pairs.
|
|
5820
|
+
*
|
|
5821
|
+
* @param query - Query to execute
|
|
5822
|
+
* @returns Array of [key, value] pairs
|
|
5823
|
+
*/
|
|
5824
|
+
queryEntries(query: Query): [K, V][];
|
|
5825
|
+
/**
|
|
5826
|
+
* Execute a query and return matching values.
|
|
5827
|
+
*
|
|
5828
|
+
* @param query - Query to execute
|
|
5829
|
+
* @returns Array of matching values
|
|
5830
|
+
*/
|
|
5831
|
+
queryValues(query: Query): V[];
|
|
5832
|
+
/**
|
|
5833
|
+
* Count matching records without materializing results.
|
|
5834
|
+
*
|
|
5835
|
+
* @param query - Query to execute
|
|
5836
|
+
* @returns Number of matching records
|
|
5837
|
+
*/
|
|
5838
|
+
count(query: Query): number;
|
|
5839
|
+
/**
|
|
5840
|
+
* Execute plan and return result set.
|
|
5841
|
+
*/
|
|
5842
|
+
private executePlan;
|
|
5843
|
+
/**
|
|
5844
|
+
* Perform full scan with predicate evaluation.
|
|
5845
|
+
*/
|
|
5846
|
+
private fullScan;
|
|
5847
|
+
/**
|
|
5848
|
+
* Check if record matches predicate.
|
|
5849
|
+
* Converts Query to PredicateNode format for evaluation.
|
|
5850
|
+
*/
|
|
5851
|
+
private matchesPredicate;
|
|
5852
|
+
/**
|
|
5853
|
+
* Check if record matches IndexQuery (used by FallbackIndex).
|
|
5854
|
+
* This is a simplified matcher for full scan fallback.
|
|
5855
|
+
*/
|
|
5856
|
+
private matchesIndexQuery;
|
|
5857
|
+
/**
|
|
5858
|
+
* Convert Query to PredicateNode format.
|
|
5859
|
+
*/
|
|
5860
|
+
private queryToPredicate;
|
|
5861
|
+
/**
|
|
5862
|
+
* Subscribe to a live query.
|
|
5863
|
+
* Callback receives initial results and delta updates.
|
|
5864
|
+
*
|
|
5865
|
+
* @param query - Query to subscribe to
|
|
5866
|
+
* @param callback - Callback for query events
|
|
5867
|
+
* @returns Unsubscribe function
|
|
5868
|
+
*/
|
|
5869
|
+
subscribeLiveQuery(query: Query, callback: LiveQueryCallback<K, V>): () => void;
|
|
5870
|
+
/**
|
|
5871
|
+
* Get current live query results (snapshot).
|
|
5872
|
+
*
|
|
5873
|
+
* @param query - Query to execute
|
|
5874
|
+
* @returns Array of matching keys
|
|
5875
|
+
*/
|
|
5876
|
+
getLiveQueryResults(query: Query): K[];
|
|
5877
|
+
/**
|
|
5878
|
+
* Check if a query has active subscribers.
|
|
5879
|
+
*
|
|
5880
|
+
* @param query - Query to check
|
|
5881
|
+
* @returns true if query has subscribers
|
|
5882
|
+
*/
|
|
5883
|
+
hasLiveQuerySubscribers(query: Query): boolean;
|
|
5884
|
+
/**
|
|
5885
|
+
* Set a value (with index updates).
|
|
5886
|
+
*/
|
|
5887
|
+
set(key: K, value: V, ttlMs?: number): LWWRecord<V>;
|
|
5888
|
+
/**
|
|
5889
|
+
* Remove a value (with index updates).
|
|
5890
|
+
*/
|
|
5891
|
+
remove(key: K): LWWRecord<V>;
|
|
5892
|
+
/**
|
|
5893
|
+
* Merge a remote record (with index updates).
|
|
5894
|
+
*/
|
|
5895
|
+
merge(key: K, remote: LWWRecord<V>): boolean;
|
|
5896
|
+
/**
|
|
5897
|
+
* Clear all data (and indexes).
|
|
5898
|
+
*/
|
|
5899
|
+
clear(): void;
|
|
5900
|
+
/**
|
|
5901
|
+
* Returns all keys (non-tombstoned, non-expired).
|
|
5902
|
+
*/
|
|
5903
|
+
keys(): Iterable<K>;
|
|
5904
|
+
/**
|
|
5905
|
+
* Get index statistics.
|
|
5906
|
+
*/
|
|
5907
|
+
getIndexStats(): Map<string, IndexStats>;
|
|
5908
|
+
/**
|
|
5909
|
+
* Get index registry statistics.
|
|
5910
|
+
*/
|
|
5911
|
+
getIndexRegistryStats(): IndexRegistryStats;
|
|
5912
|
+
/**
|
|
5913
|
+
* Get query optimizer for plan inspection.
|
|
5914
|
+
*/
|
|
5915
|
+
getQueryOptimizer(): QueryOptimizer<K, V>;
|
|
5916
|
+
/**
|
|
5917
|
+
* Get live query manager for direct access.
|
|
5918
|
+
*/
|
|
5919
|
+
getLiveQueryManager(): LiveQueryManager<K, V>;
|
|
5920
|
+
/**
|
|
5921
|
+
* Get standing query registry for direct access.
|
|
5922
|
+
*/
|
|
5923
|
+
getStandingQueryRegistry(): StandingQueryRegistry<K, V>;
|
|
5924
|
+
/**
|
|
5925
|
+
* Explain query execution plan.
|
|
5926
|
+
*
|
|
5927
|
+
* @param query - Query to explain
|
|
5928
|
+
* @returns Query execution plan
|
|
5929
|
+
*/
|
|
5930
|
+
explainQuery(query: Query): QueryPlan;
|
|
5931
|
+
/**
|
|
5932
|
+
* Register an attribute for auto-indexing.
|
|
5933
|
+
* Required before auto-index can create indexes on this attribute.
|
|
5934
|
+
*
|
|
5935
|
+
* @param attribute - The attribute to register
|
|
5936
|
+
* @param allowedIndexTypes - Optional list of allowed index types
|
|
5937
|
+
*/
|
|
5938
|
+
registerAttribute<A>(attribute: Attribute<V, A>, allowedIndexTypes?: RecommendedIndexType[]): void;
|
|
5939
|
+
/**
|
|
5940
|
+
* Unregister an attribute from auto-indexing.
|
|
5941
|
+
*
|
|
5942
|
+
* @param attributeName - Name of attribute to unregister
|
|
5943
|
+
*/
|
|
5944
|
+
unregisterAttribute(attributeName: string): void;
|
|
5945
|
+
/**
|
|
5946
|
+
* Get index suggestions based on query patterns.
|
|
5947
|
+
* Use this in production to get recommendations for manual index creation.
|
|
5948
|
+
*
|
|
5949
|
+
* @param options - Suggestion options
|
|
5950
|
+
* @returns Array of index suggestions sorted by priority
|
|
5951
|
+
*
|
|
5952
|
+
* @example
|
|
5953
|
+
* ```typescript
|
|
5954
|
+
* const suggestions = products.getIndexSuggestions();
|
|
5955
|
+
* // [{ attribute: 'category', indexType: 'hash', priority: 'high', ... }]
|
|
5956
|
+
* ```
|
|
5957
|
+
*/
|
|
5958
|
+
getIndexSuggestions(options?: IndexSuggestionOptions): IndexSuggestion[];
|
|
5959
|
+
/**
|
|
5960
|
+
* Get query pattern statistics.
|
|
5961
|
+
* Useful for debugging and understanding query patterns.
|
|
5962
|
+
*
|
|
5963
|
+
* @returns Array of query statistics
|
|
5964
|
+
*/
|
|
5965
|
+
getQueryStatistics(): QueryStatistics[];
|
|
5966
|
+
/**
|
|
5967
|
+
* Reset query statistics.
|
|
5968
|
+
* Call this to clear accumulated query patterns.
|
|
5969
|
+
*/
|
|
5970
|
+
resetQueryStatistics(): void;
|
|
5971
|
+
/**
|
|
5972
|
+
* Get query pattern tracker for advanced usage.
|
|
5973
|
+
*/
|
|
5974
|
+
getQueryTracker(): QueryPatternTracker;
|
|
5975
|
+
/**
|
|
5976
|
+
* Get index advisor for advanced usage.
|
|
5977
|
+
*/
|
|
5978
|
+
getIndexAdvisor(): IndexAdvisor;
|
|
5979
|
+
/**
|
|
5980
|
+
* Get auto-index manager (if enabled).
|
|
5981
|
+
*/
|
|
5982
|
+
getAutoIndexManager(): AutoIndexManager<K, V> | null;
|
|
5983
|
+
/**
|
|
5984
|
+
* Check if auto-indexing is enabled.
|
|
5985
|
+
*/
|
|
5986
|
+
isAutoIndexingEnabled(): boolean;
|
|
5987
|
+
/**
|
|
5988
|
+
* Track query pattern for adaptive indexing.
|
|
5989
|
+
*/
|
|
5990
|
+
private trackQueryPattern;
|
|
5991
|
+
/**
|
|
5992
|
+
* Extract attribute name from query.
|
|
5993
|
+
*/
|
|
5994
|
+
private extractAttribute;
|
|
5995
|
+
/**
|
|
5996
|
+
* Extract query type from query.
|
|
5997
|
+
*/
|
|
5998
|
+
private extractQueryType;
|
|
5999
|
+
}
|
|
6000
|
+
|
|
6001
|
+
/**
|
|
6002
|
+
* IndexedORMap Implementation
|
|
6003
|
+
*
|
|
6004
|
+
* ORMap with index support for O(1) to O(log N) queries.
|
|
6005
|
+
* Wraps ORMap with indexing capabilities using the Wrapper Pattern.
|
|
6006
|
+
*
|
|
6007
|
+
* Note: ORMap stores multiple values per key (with tags).
|
|
6008
|
+
* Indexes track unique (key, tag) composite keys.
|
|
6009
|
+
*
|
|
6010
|
+
* Features:
|
|
6011
|
+
* - Hash and Navigable indexes for efficient queries
|
|
6012
|
+
* - Composite key indexing (key:tag)
|
|
6013
|
+
* - Automatic index updates on CRDT operations
|
|
6014
|
+
* - Lazy filtering for tombstones
|
|
6015
|
+
* - Adaptive indexing with query pattern tracking (Phase 8.02)
|
|
6016
|
+
*
|
|
6017
|
+
* @module IndexedORMap
|
|
6018
|
+
*/
|
|
6019
|
+
|
|
6020
|
+
/**
|
|
6021
|
+
* Result of a query on IndexedORMap.
|
|
6022
|
+
*/
|
|
6023
|
+
interface ORMapQueryResult<K, V> {
|
|
6024
|
+
key: K;
|
|
6025
|
+
tag: string;
|
|
6026
|
+
value: V;
|
|
6027
|
+
}
|
|
6028
|
+
/**
|
|
6029
|
+
* ORMap with index support.
|
|
6030
|
+
*
|
|
6031
|
+
* Note: ORMap stores multiple values per key (with tags).
|
|
6032
|
+
* Indexes track unique (key, tag) pairs using composite keys.
|
|
6033
|
+
*
|
|
6034
|
+
* K = key type (extends string for compatibility)
|
|
6035
|
+
* V = value type
|
|
6036
|
+
*/
|
|
6037
|
+
declare class IndexedORMap<K extends string, V> extends ORMap<K, V> {
|
|
6038
|
+
private indexRegistry;
|
|
6039
|
+
private queryOptimizer;
|
|
6040
|
+
private readonly queryTracker;
|
|
6041
|
+
private readonly indexAdvisor;
|
|
6042
|
+
private readonly autoIndexManager;
|
|
6043
|
+
private readonly defaultIndexingStrategy;
|
|
6044
|
+
private readonly options;
|
|
6045
|
+
constructor(hlc: HLC, options?: IndexedMapOptions);
|
|
6046
|
+
/**
|
|
6047
|
+
* Add a hash index on an attribute.
|
|
6048
|
+
*
|
|
6049
|
+
* @param attribute - Attribute to index
|
|
6050
|
+
* @returns Created HashIndex
|
|
6051
|
+
*/
|
|
6052
|
+
addHashIndex<A>(attribute: Attribute<V, A>): HashIndex<string, V, A>;
|
|
6053
|
+
/**
|
|
6054
|
+
* Add a navigable index on an attribute.
|
|
6055
|
+
* Navigable indexes support range queries (gt, gte, lt, lte, between).
|
|
6056
|
+
*
|
|
6057
|
+
* @param attribute - Attribute to index
|
|
6058
|
+
* @param comparator - Optional custom comparator
|
|
6059
|
+
* @returns Created NavigableIndex
|
|
6060
|
+
*/
|
|
6061
|
+
addNavigableIndex<A extends string | number>(attribute: Attribute<V, A>, comparator?: (a: A, b: A) => number): NavigableIndex<string, V, A>;
|
|
6062
|
+
/**
|
|
6063
|
+
* Add an inverted index for full-text search on an attribute.
|
|
6064
|
+
* Inverted indexes support text search queries (contains, containsAll, containsAny).
|
|
6065
|
+
*
|
|
6066
|
+
* @param attribute - Text attribute to index
|
|
6067
|
+
* @param pipeline - Optional custom tokenization pipeline
|
|
6068
|
+
* @returns Created InvertedIndex
|
|
6069
|
+
*/
|
|
6070
|
+
addInvertedIndex<A extends string = string>(attribute: Attribute<V, A>, pipeline?: TokenizationPipeline): InvertedIndex<string, V, A>;
|
|
6071
|
+
/**
|
|
6072
|
+
* Add a custom index.
|
|
6073
|
+
*
|
|
6074
|
+
* @param index - Index to add
|
|
6075
|
+
*/
|
|
6076
|
+
addIndex<A>(index: Index<string, V, A>): void;
|
|
6077
|
+
/**
|
|
6078
|
+
* Remove an index.
|
|
6079
|
+
*
|
|
6080
|
+
* @param index - Index to remove
|
|
6081
|
+
* @returns true if index was found and removed
|
|
6082
|
+
*/
|
|
6083
|
+
removeIndex<A>(index: Index<string, V, A>): boolean;
|
|
6084
|
+
/**
|
|
6085
|
+
* Get all indexes.
|
|
6086
|
+
*
|
|
6087
|
+
* @returns Array of all indexes
|
|
6088
|
+
*/
|
|
6089
|
+
getIndexes(): Index<string, V, unknown>[];
|
|
6090
|
+
/**
|
|
6091
|
+
* Check if an attribute is indexed.
|
|
6092
|
+
*
|
|
6093
|
+
* @param attributeName - Attribute name
|
|
6094
|
+
* @returns true if attribute has indexes
|
|
6095
|
+
*/
|
|
6096
|
+
hasIndexOn(attributeName: string): boolean;
|
|
6097
|
+
/**
|
|
6098
|
+
* Build index from existing data.
|
|
6099
|
+
*/
|
|
6100
|
+
private buildIndexFromExisting;
|
|
6101
|
+
/**
|
|
6102
|
+
* Execute a query across all records.
|
|
6103
|
+
* Returns array of matching results with key, tag, and value.
|
|
6104
|
+
*
|
|
6105
|
+
* Also tracks query patterns for adaptive indexing (Phase 8.02).
|
|
6106
|
+
*
|
|
6107
|
+
* @param query - Query to execute
|
|
6108
|
+
* @returns Array of query results
|
|
6109
|
+
*/
|
|
6110
|
+
query(query: Query): ORMapQueryResult<K, V>[];
|
|
6111
|
+
/**
|
|
6112
|
+
* Execute a query and return matching values only.
|
|
6113
|
+
*
|
|
6114
|
+
* @param query - Query to execute
|
|
6115
|
+
* @returns Array of matching values
|
|
6116
|
+
*/
|
|
6117
|
+
queryValues(query: Query): V[];
|
|
6118
|
+
/**
|
|
6119
|
+
* Count matching records without materializing results.
|
|
6120
|
+
*
|
|
6121
|
+
* @param query - Query to execute
|
|
6122
|
+
* @returns Number of matching records
|
|
6123
|
+
*/
|
|
6124
|
+
count(query: Query): number;
|
|
6125
|
+
/**
|
|
6126
|
+
* Execute plan and return result set.
|
|
6127
|
+
*/
|
|
6128
|
+
private executePlan;
|
|
6129
|
+
/**
|
|
6130
|
+
* Perform full scan with predicate evaluation.
|
|
6131
|
+
*/
|
|
6132
|
+
private fullScan;
|
|
6133
|
+
/**
|
|
6134
|
+
* Add a value (with index updates).
|
|
6135
|
+
*/
|
|
6136
|
+
add(key: K, value: V, ttlMs?: number): ORMapRecord<V>;
|
|
6137
|
+
/**
|
|
6138
|
+
* Remove a value (with index updates).
|
|
6139
|
+
*/
|
|
6140
|
+
remove(key: K, value: V): string[];
|
|
6141
|
+
/**
|
|
6142
|
+
* Apply a record from remote (with index updates).
|
|
6143
|
+
*/
|
|
6144
|
+
apply(key: K, record: ORMapRecord<V>): boolean;
|
|
6145
|
+
/**
|
|
6146
|
+
* Apply a tombstone (with index updates).
|
|
6147
|
+
*/
|
|
6148
|
+
applyTombstone(tag: string): void;
|
|
6149
|
+
/**
|
|
6150
|
+
* Clear all data (and indexes).
|
|
6151
|
+
*/
|
|
6152
|
+
clear(): void;
|
|
6153
|
+
/**
|
|
6154
|
+
* Create composite key from map key and tag.
|
|
6155
|
+
* Uses '||' as separator since HLC tags contain ':'
|
|
6156
|
+
*/
|
|
6157
|
+
private createCompositeKey;
|
|
6158
|
+
/**
|
|
6159
|
+
* Parse composite key into [key, tag].
|
|
6160
|
+
* Expects '||' separator.
|
|
6161
|
+
*/
|
|
6162
|
+
private parseCompositeKey;
|
|
6163
|
+
/**
|
|
6164
|
+
* Get all composite keys from the map.
|
|
6165
|
+
*/
|
|
6166
|
+
private getAllCompositeKeys;
|
|
6167
|
+
/**
|
|
6168
|
+
* Get record by composite key.
|
|
6169
|
+
*/
|
|
6170
|
+
private getRecordByCompositeKey;
|
|
6171
|
+
/**
|
|
6172
|
+
* Check if record matches predicate.
|
|
6173
|
+
*/
|
|
6174
|
+
private matchesPredicate;
|
|
6175
|
+
/**
|
|
6176
|
+
* Check if record matches IndexQuery (used by FallbackIndex).
|
|
6177
|
+
* This is a simplified matcher for full scan fallback.
|
|
6178
|
+
*/
|
|
6179
|
+
private matchesIndexQuery;
|
|
6180
|
+
/**
|
|
6181
|
+
* Convert Query to PredicateNode format.
|
|
6182
|
+
*/
|
|
6183
|
+
private queryToPredicate;
|
|
6184
|
+
/**
|
|
6185
|
+
* Get index statistics.
|
|
6186
|
+
*/
|
|
6187
|
+
getIndexStats(): Map<string, IndexStats>;
|
|
6188
|
+
/**
|
|
6189
|
+
* Get index registry statistics.
|
|
6190
|
+
*/
|
|
6191
|
+
getIndexRegistryStats(): IndexRegistryStats;
|
|
6192
|
+
/**
|
|
6193
|
+
* Get query optimizer for plan inspection.
|
|
6194
|
+
*/
|
|
6195
|
+
getQueryOptimizer(): QueryOptimizer<string, V>;
|
|
6196
|
+
/**
|
|
6197
|
+
* Explain query execution plan.
|
|
6198
|
+
*
|
|
6199
|
+
* @param query - Query to explain
|
|
6200
|
+
* @returns Query execution plan
|
|
6201
|
+
*/
|
|
6202
|
+
explainQuery(query: Query): QueryPlan;
|
|
6203
|
+
/**
|
|
6204
|
+
* Register an attribute for auto-indexing.
|
|
6205
|
+
* Required before auto-index can create indexes on this attribute.
|
|
6206
|
+
*
|
|
6207
|
+
* @param attribute - The attribute to register
|
|
6208
|
+
* @param allowedIndexTypes - Optional list of allowed index types
|
|
6209
|
+
*/
|
|
6210
|
+
registerAttribute<A>(attribute: Attribute<V, A>, allowedIndexTypes?: RecommendedIndexType[]): void;
|
|
6211
|
+
/**
|
|
6212
|
+
* Unregister an attribute from auto-indexing.
|
|
6213
|
+
*
|
|
6214
|
+
* @param attributeName - Name of attribute to unregister
|
|
6215
|
+
*/
|
|
6216
|
+
unregisterAttribute(attributeName: string): void;
|
|
6217
|
+
/**
|
|
6218
|
+
* Get index suggestions based on query patterns.
|
|
6219
|
+
* Use this in production to get recommendations for manual index creation.
|
|
6220
|
+
*
|
|
6221
|
+
* @param options - Suggestion options
|
|
6222
|
+
* @returns Array of index suggestions sorted by priority
|
|
6223
|
+
*/
|
|
6224
|
+
getIndexSuggestions(options?: IndexSuggestionOptions): IndexSuggestion[];
|
|
6225
|
+
/**
|
|
6226
|
+
* Get query pattern statistics.
|
|
6227
|
+
* Useful for debugging and understanding query patterns.
|
|
6228
|
+
*
|
|
6229
|
+
* @returns Array of query statistics
|
|
6230
|
+
*/
|
|
6231
|
+
getQueryStatistics(): QueryStatistics[];
|
|
6232
|
+
/**
|
|
6233
|
+
* Reset query statistics.
|
|
6234
|
+
* Call this to clear accumulated query patterns.
|
|
6235
|
+
*/
|
|
6236
|
+
resetQueryStatistics(): void;
|
|
6237
|
+
/**
|
|
6238
|
+
* Get query pattern tracker for advanced usage.
|
|
6239
|
+
*/
|
|
6240
|
+
getQueryTracker(): QueryPatternTracker;
|
|
6241
|
+
/**
|
|
6242
|
+
* Get index advisor for advanced usage.
|
|
6243
|
+
*/
|
|
6244
|
+
getIndexAdvisor(): IndexAdvisor;
|
|
6245
|
+
/**
|
|
6246
|
+
* Get auto-index manager (if enabled).
|
|
6247
|
+
*/
|
|
6248
|
+
getAutoIndexManager(): AutoIndexManager<string, V> | null;
|
|
6249
|
+
/**
|
|
6250
|
+
* Check if auto-indexing is enabled.
|
|
6251
|
+
*/
|
|
6252
|
+
isAutoIndexingEnabled(): boolean;
|
|
6253
|
+
/**
|
|
6254
|
+
* Track query pattern for adaptive indexing.
|
|
6255
|
+
*/
|
|
6256
|
+
private trackQueryPattern;
|
|
6257
|
+
/**
|
|
6258
|
+
* Extract attribute name from query.
|
|
6259
|
+
*/
|
|
6260
|
+
private extractAttribute;
|
|
6261
|
+
/**
|
|
6262
|
+
* Extract query type from query.
|
|
6263
|
+
*/
|
|
6264
|
+
private extractQueryType;
|
|
6265
|
+
}
|
|
6266
|
+
|
|
6267
|
+
export { type Attribute, AuthMessageSchema, type BatchMessage, BatchMessageSchema, BuiltInProcessors, BuiltInResolvers, type CircuitBreakerConfig, type ClientOp, ClientOpMessageSchema, ClientOpSchema, type ClusterClientConfig, type ClusterEvents, type ReadOptions as ClusterReadOptions, type WriteOptions as ClusterWriteOptions, type CompareFn, type ConflictResolver, type ConflictResolverDef, ConflictResolverDefSchema, type ConflictResolverFn, ConflictResolverSchema, type ConnectionPoolConfig, type ConnectionState, ConsistencyLevel, CounterRequestSchema, CounterResponseSchema, CounterSyncSchema, CounterUpdateSchema, DEFAULT_BACKUP_COUNT, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONNECTION_POOL_CONFIG, DEFAULT_EVENT_JOURNAL_CONFIG, DEFAULT_MIGRATION_CONFIG, DEFAULT_PARTITION_ROUTER_CONFIG, DEFAULT_PROCESSOR_RATE_LIMITS, DEFAULT_REPLICATION_CONFIG, DEFAULT_RESOLVER_RATE_LIMITS, DEFAULT_STOP_WORDS, DEFAULT_WRITE_CONCERN_TIMEOUT, type EntryProcessBatchRequest, EntryProcessBatchRequestSchema, type EntryProcessBatchResponse, EntryProcessBatchResponseSchema, type EntryProcessKeyResult, EntryProcessKeyResultSchema, type EntryProcessRequest, EntryProcessRequestSchema, type EntryProcessResponse, EntryProcessResponseSchema, type EntryProcessorDef, EntryProcessorDefSchema, type EntryProcessorFn, type EntryProcessorResult, EntryProcessorSchema, type EventJournal, type EventJournalConfig, EventJournalImpl, FORBIDDEN_PATTERNS, FallbackIndex, type FilterStep, FilteringResultSet, type FullScanStep, HLC, HashIndex, type Index, type IndexQuery, IndexRegistry, type IndexRegistryStats, type IndexScanStep, type IndexStats, IndexedLWWMap, IndexedORMap, IntersectionResultSet, type IntersectionStep, InvertedIndex, type InvertedIndexStats, type IteratorFactory, type JournalEvent, type JournalEventData, JournalEventDataSchema, type JournalEventInput, type JournalEventListener, type JournalEventMessage, JournalEventMessageSchema, type JournalEventType, JournalEventTypeSchema, type JournalReadRequest, JournalReadRequestSchema, type JournalReadResponse, JournalReadResponseSchema, type JournalSubscribeRequest, JournalSubscribeRequestSchema, type JournalUnsubscribeRequest, JournalUnsubscribeRequestSchema, LWWMap, type LWWRecord, LWWRecordSchema, LazyResultSet, LimitResultSet, type ListResolversRequest, ListResolversRequestSchema, type ListResolversResponse, ListResolversResponseSchema, type LiveQueryCallback, type LiveQueryDeltaEvent, type LiveQueryEvent, type LiveQueryInitialEvent, LiveQueryManager, type LiveQueryManagerOptions, type LiveQueryManagerStats, LockReleaseSchema, LockRequestSchema, type LogicalQueryNode, LowercaseFilter, MaxLengthFilter, type MergeContext, type MergeKeyResult, type MergeRejectedMessage, MergeRejectedMessageSchema, type MergeRejection, type MergeResult, MerkleReqBucketMessageSchema, MerkleTree, type Message, MessageSchema, type MigrationChunkAckMessage, type MigrationChunkMessage, type MigrationCompleteMessage, type MigrationConfig, type MigrationMessage, type MigrationMetrics, type MigrationStartMessage, type MigrationStatus, type MigrationVerifyMessage, MinLengthFilter, MultiValueAttribute, NGramTokenizer, NavigableIndex, type NodeHealth, type NodeInfo, type NodeStatus, type NotOwnerError, type NotStep, ORMap, ORMapDiffRequestSchema, ORMapDiffResponseSchema, type ORMapMerkleNode, ORMapMerkleReqBucketSchema, ORMapMerkleTree, ORMapPushDiffSchema, type ORMapQueryResult, type ORMapRecord, ORMapRecordSchema, type ORMapSnapshot, ORMapSyncInitSchema, ORMapSyncRespBucketsSchema, ORMapSyncRespLeafSchema, ORMapSyncRespRootSchema, type OpAckMessage, OpAckMessageSchema, OpBatchMessageSchema, type OpRejectedMessage, OpRejectedMessageSchema, type OpResult, OpResultSchema, PARTITION_COUNT, type PNCounter, type PNCounterConfig, PNCounterImpl, type PNCounterState, type PNCounterStateObject, PNCounterStateObjectSchema, type PartitionChange, type PartitionInfo, type PartitionMap, type PartitionMapDeltaMessage, type PartitionMapMessage, type PartitionMapRequestMessage, PartitionMapRequestSchema, type PartitionMigration, type PartitionRouterConfig, PartitionState, type PendingWrite, type PermissionPolicy, type PermissionType, type PingMessage, PingMessageSchema, type PlanStep, type PongMessage, PongMessageSchema, type PredicateFn, type PredicateNode, PredicateNodeSchema, type PredicateOp, PredicateOpSchema, Predicates, type Principal, type ProcessorRateLimitConfig, type Query$1 as Query, type Query as QueryExpression, type QueryNode, QueryOptimizer, type QueryOptimizerOptions, type QueryOptions, type QueryPlan, QuerySchema, QuerySubMessageSchema, QueryUnsubMessageSchema, RESOLVER_FORBIDDEN_PATTERNS, type RegisterResolverRequest, RegisterResolverRequestSchema, type RegisterResolverResponse, RegisterResolverResponseSchema, type ReplicationAckMessage, type ReplicationBatchAckMessage, type ReplicationBatchMessage, type ReplicationConfig, type ReplicationHealth, type ReplicationLag, type ReplicationMessage, type ReplicationProtocolMessage, type ReplicationResult, type ReplicationTask, type ResolverRateLimitConfig, type ResultSet, Ringbuffer, type RoutingError, SetResultSet, SimpleAttribute, type SimpleQueryNode, SortedMap, SortedResultSet, type StaleMapError, type StandingQueryChange, StandingQueryIndex, type StandingQueryIndexOptions, StandingQueryRegistry, type StandingQueryRegistryOptions, type StandingQueryRegistryStats, StopWordFilter, SyncInitMessageSchema, SyncRespBucketsMessageSchema, SyncRespLeafMessageSchema, SyncRespRootMessageSchema, type Timestamp, TimestampSchema, type TokenFilter, TokenizationPipeline, type TokenizationPipelineOptions, type Tokenizer, TopicMessageEventSchema, TopicPubSchema, TopicSubSchema, TopicUnsubSchema, TrimFilter, UnionResultSet, type UnionStep, UniqueFilter, type UnregisterResolverRequest, UnregisterResolverRequestSchema, type UnregisterResolverResponse, UnregisterResolverResponseSchema, WRITE_CONCERN_ORDER, WhitespaceTokenizer, WordBoundaryTokenizer, WriteConcern, WriteConcernSchema, type WriteConcernValue, type WriteOptions$1 as WriteOptions, type WriteResult, combineHashes, compareHLCTimestamps, compareTimestamps, createFieldComparator, createPredicateMatcher, deepMerge, deserialize, disableNativeHash, evaluatePredicate, getHighestWriteConcernLevel, hashORMapEntry, hashORMapRecord, hashString, isLogicalQuery, isSimpleQuery, isUsingNativeHash, isWriteConcernAchieved, multiAttribute, resetNativeHash, serialize, simpleAttribute, timestampToString, validateProcessorCode, validateResolverCode };
|