@nahisaho/yata-scale 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/dist/CacheManager.d.ts +107 -0
- package/dist/CacheManager.d.ts.map +1 -0
- package/dist/CacheManager.js +343 -0
- package/dist/CacheManager.js.map +1 -0
- package/dist/IndexManager.d.ts +103 -0
- package/dist/IndexManager.d.ts.map +1 -0
- package/dist/IndexManager.js +385 -0
- package/dist/IndexManager.js.map +1 -0
- package/dist/MigrationHelper.d.ts +91 -0
- package/dist/MigrationHelper.d.ts.map +1 -0
- package/dist/MigrationHelper.js +220 -0
- package/dist/MigrationHelper.js.map +1 -0
- package/dist/QueryCoordinator.d.ts +76 -0
- package/dist/QueryCoordinator.d.ts.map +1 -0
- package/dist/QueryCoordinator.js +298 -0
- package/dist/QueryCoordinator.js.map +1 -0
- package/dist/ShardManager.d.ts +48 -0
- package/dist/ShardManager.d.ts.map +1 -0
- package/dist/ShardManager.js +193 -0
- package/dist/ShardManager.js.map +1 -0
- package/dist/SyncController.d.ts +102 -0
- package/dist/SyncController.d.ts.map +1 -0
- package/dist/SyncController.js +286 -0
- package/dist/SyncController.js.map +1 -0
- package/dist/YataScaleManager.d.ts +75 -0
- package/dist/YataScaleManager.d.ts.map +1 -0
- package/dist/YataScaleManager.js +265 -0
- package/dist/YataScaleManager.js.map +1 -0
- package/dist/cache/CacheManager.d.ts +116 -0
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +286 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/cache/InvalidationManager.d.ts +91 -0
- package/dist/cache/InvalidationManager.d.ts.map +1 -0
- package/dist/cache/InvalidationManager.js +155 -0
- package/dist/cache/InvalidationManager.js.map +1 -0
- package/dist/cache/L1Cache.d.ts +97 -0
- package/dist/cache/L1Cache.d.ts.map +1 -0
- package/dist/cache/L1Cache.js +225 -0
- package/dist/cache/L1Cache.js.map +1 -0
- package/dist/cache/L2Cache.d.ts +93 -0
- package/dist/cache/L2Cache.d.ts.map +1 -0
- package/dist/cache/L2Cache.js +248 -0
- package/dist/cache/L2Cache.js.map +1 -0
- package/dist/cache/L3Cache.d.ts +101 -0
- package/dist/cache/L3Cache.d.ts.map +1 -0
- package/dist/cache/L3Cache.js +229 -0
- package/dist/cache/L3Cache.js.map +1 -0
- package/dist/cache/index.d.ts +12 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +11 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/errors.d.ts +255 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +515 -0
- package/dist/errors.js.map +1 -0
- package/dist/index/BPlusTreeIndex.d.ts +101 -0
- package/dist/index/BPlusTreeIndex.d.ts.map +1 -0
- package/dist/index/BPlusTreeIndex.js +310 -0
- package/dist/index/BPlusTreeIndex.js.map +1 -0
- package/dist/index/BloomFilter.d.ts +85 -0
- package/dist/index/BloomFilter.d.ts.map +1 -0
- package/dist/index/BloomFilter.js +215 -0
- package/dist/index/BloomFilter.js.map +1 -0
- package/dist/index/FullTextIndex.d.ts +87 -0
- package/dist/index/FullTextIndex.d.ts.map +1 -0
- package/dist/index/FullTextIndex.js +213 -0
- package/dist/index/FullTextIndex.js.map +1 -0
- package/dist/index/GraphIndex.d.ts +116 -0
- package/dist/index/GraphIndex.d.ts.map +1 -0
- package/dist/index/GraphIndex.js +308 -0
- package/dist/index/GraphIndex.js.map +1 -0
- package/dist/index/IndexManager.d.ts +105 -0
- package/dist/index/IndexManager.d.ts.map +1 -0
- package/dist/index/IndexManager.js +287 -0
- package/dist/index/IndexManager.js.map +1 -0
- package/dist/index/index.d.ts +12 -0
- package/dist/index/index.d.ts.map +1 -0
- package/dist/index/index.js +11 -0
- package/dist/index/index.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/query/DistributedExecutor.d.ts +78 -0
- package/dist/query/DistributedExecutor.d.ts.map +1 -0
- package/dist/query/DistributedExecutor.js +232 -0
- package/dist/query/DistributedExecutor.js.map +1 -0
- package/dist/query/QueryCoordinator.d.ts +98 -0
- package/dist/query/QueryCoordinator.d.ts.map +1 -0
- package/dist/query/QueryCoordinator.js +246 -0
- package/dist/query/QueryCoordinator.js.map +1 -0
- package/dist/query/QueryPlanner.d.ts +88 -0
- package/dist/query/QueryPlanner.d.ts.map +1 -0
- package/dist/query/QueryPlanner.js +235 -0
- package/dist/query/QueryPlanner.js.map +1 -0
- package/dist/query/WorkerPool.d.ts +108 -0
- package/dist/query/WorkerPool.d.ts.map +1 -0
- package/dist/query/WorkerPool.js +195 -0
- package/dist/query/WorkerPool.js.map +1 -0
- package/dist/query/index.d.ts +11 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +10 -0
- package/dist/query/index.js.map +1 -0
- package/dist/shard/GraphPartitionStrategy.d.ts +65 -0
- package/dist/shard/GraphPartitionStrategy.d.ts.map +1 -0
- package/dist/shard/GraphPartitionStrategy.js +208 -0
- package/dist/shard/GraphPartitionStrategy.js.map +1 -0
- package/dist/shard/HashPartitionStrategy.d.ts +56 -0
- package/dist/shard/HashPartitionStrategy.d.ts.map +1 -0
- package/dist/shard/HashPartitionStrategy.js +169 -0
- package/dist/shard/HashPartitionStrategy.js.map +1 -0
- package/dist/shard/RangePartitionStrategy.d.ts +63 -0
- package/dist/shard/RangePartitionStrategy.d.ts.map +1 -0
- package/dist/shard/RangePartitionStrategy.js +157 -0
- package/dist/shard/RangePartitionStrategy.js.map +1 -0
- package/dist/shard/Rebalancer.d.ts +70 -0
- package/dist/shard/Rebalancer.d.ts.map +1 -0
- package/dist/shard/Rebalancer.js +184 -0
- package/dist/shard/Rebalancer.js.map +1 -0
- package/dist/shard/ShardManager.d.ts +123 -0
- package/dist/shard/ShardManager.d.ts.map +1 -0
- package/dist/shard/ShardManager.js +353 -0
- package/dist/shard/ShardManager.js.map +1 -0
- package/dist/shard/ShardRouter.d.ts +102 -0
- package/dist/shard/ShardRouter.d.ts.map +1 -0
- package/dist/shard/ShardRouter.js +181 -0
- package/dist/shard/ShardRouter.js.map +1 -0
- package/dist/shard/index.d.ts +13 -0
- package/dist/shard/index.d.ts.map +1 -0
- package/dist/shard/index.js +12 -0
- package/dist/shard/index.js.map +1 -0
- package/dist/sync/ConflictResolver.d.ts +71 -0
- package/dist/sync/ConflictResolver.d.ts.map +1 -0
- package/dist/sync/ConflictResolver.js +214 -0
- package/dist/sync/ConflictResolver.js.map +1 -0
- package/dist/sync/SyncController.d.ts +150 -0
- package/dist/sync/SyncController.d.ts.map +1 -0
- package/dist/sync/SyncController.js +304 -0
- package/dist/sync/SyncController.js.map +1 -0
- package/dist/sync/VectorClock.d.ts +102 -0
- package/dist/sync/VectorClock.d.ts.map +1 -0
- package/dist/sync/VectorClock.js +189 -0
- package/dist/sync/VectorClock.js.map +1 -0
- package/dist/sync/WALManager.d.ts +120 -0
- package/dist/sync/WALManager.d.ts.map +1 -0
- package/dist/sync/WALManager.js +240 -0
- package/dist/sync/WALManager.js.map +1 -0
- package/dist/sync/index.d.ts +11 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +10 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/types.d.ts +323 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - B+Tree Index
|
|
3
|
+
*
|
|
4
|
+
* B+Tree implementation for efficient range queries
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* B+Tree index for efficient key-value storage with range queries
|
|
8
|
+
*/
|
|
9
|
+
export class BPlusTreeIndex {
|
|
10
|
+
root;
|
|
11
|
+
order;
|
|
12
|
+
entryCount = 0;
|
|
13
|
+
compare;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
const fanout = config?.fanout ?? 128;
|
|
16
|
+
this.order = Math.floor(fanout / 2);
|
|
17
|
+
this.root = this.createLeafNode();
|
|
18
|
+
this.compare = (a, b) => {
|
|
19
|
+
if (typeof a === 'string' && typeof b === 'string') {
|
|
20
|
+
return a.localeCompare(b);
|
|
21
|
+
}
|
|
22
|
+
return a - b;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a new leaf node
|
|
27
|
+
*/
|
|
28
|
+
createLeafNode() {
|
|
29
|
+
return {
|
|
30
|
+
keys: [],
|
|
31
|
+
children: [],
|
|
32
|
+
isLeaf: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a new internal node
|
|
37
|
+
*/
|
|
38
|
+
createInternalNode() {
|
|
39
|
+
return {
|
|
40
|
+
keys: [],
|
|
41
|
+
children: [],
|
|
42
|
+
isLeaf: false,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Insert a key-value pair
|
|
47
|
+
*/
|
|
48
|
+
insert(key, value) {
|
|
49
|
+
const result = this.insertInNode(this.root, key, value);
|
|
50
|
+
if (result) {
|
|
51
|
+
// Root was split, create new root
|
|
52
|
+
const newRoot = this.createInternalNode();
|
|
53
|
+
newRoot.keys.push(result.key);
|
|
54
|
+
newRoot.children.push(this.root, result.node);
|
|
55
|
+
this.root = newRoot;
|
|
56
|
+
}
|
|
57
|
+
this.entryCount++;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Insert into a node, return split result if node was split
|
|
61
|
+
*/
|
|
62
|
+
insertInNode(node, key, value) {
|
|
63
|
+
if (node.isLeaf) {
|
|
64
|
+
return this.insertInLeaf(node, key, value);
|
|
65
|
+
}
|
|
66
|
+
// Find child to insert into
|
|
67
|
+
let childIndex = this.findChildIndex(node, key);
|
|
68
|
+
const child = node.children[childIndex];
|
|
69
|
+
const result = this.insertInNode(child, key, value);
|
|
70
|
+
if (!result) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
// Child was split, insert new key/child
|
|
74
|
+
return this.insertInInternal(node, result.key, result.node, childIndex);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Insert into a leaf node
|
|
78
|
+
*/
|
|
79
|
+
insertInLeaf(node, key, value) {
|
|
80
|
+
// Find insertion position
|
|
81
|
+
let pos = 0;
|
|
82
|
+
while (pos < node.keys.length && this.compare(node.keys[pos], key) < 0) {
|
|
83
|
+
pos++;
|
|
84
|
+
}
|
|
85
|
+
// Check for duplicate key - update value
|
|
86
|
+
if (pos < node.keys.length && this.compare(node.keys[pos], key) === 0) {
|
|
87
|
+
node.children[pos][0] = value;
|
|
88
|
+
this.entryCount--; // Compensate for the increment in insert()
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
// Insert key and value
|
|
92
|
+
node.keys.splice(pos, 0, key);
|
|
93
|
+
node.children.splice(pos, 0, [value]);
|
|
94
|
+
// Check if split needed
|
|
95
|
+
if (node.keys.length > this.order * 2) {
|
|
96
|
+
return this.splitLeaf(node);
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Insert into an internal node
|
|
102
|
+
*/
|
|
103
|
+
insertInInternal(node, key, child, afterIndex) {
|
|
104
|
+
// Insert key and child
|
|
105
|
+
node.keys.splice(afterIndex, 0, key);
|
|
106
|
+
node.children.splice(afterIndex + 1, 0, child);
|
|
107
|
+
// Check if split needed
|
|
108
|
+
if (node.keys.length > this.order * 2) {
|
|
109
|
+
return this.splitInternal(node);
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Split a leaf node
|
|
115
|
+
*/
|
|
116
|
+
splitLeaf(node) {
|
|
117
|
+
const midIndex = Math.floor(node.keys.length / 2);
|
|
118
|
+
const newNode = this.createLeafNode();
|
|
119
|
+
newNode.keys = node.keys.splice(midIndex);
|
|
120
|
+
newNode.children = node.children.splice(midIndex);
|
|
121
|
+
// Link leaves
|
|
122
|
+
newNode.next = node.next;
|
|
123
|
+
node.next = newNode;
|
|
124
|
+
return {
|
|
125
|
+
key: newNode.keys[0],
|
|
126
|
+
node: newNode,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Split an internal node
|
|
131
|
+
*/
|
|
132
|
+
splitInternal(node) {
|
|
133
|
+
const midIndex = Math.floor(node.keys.length / 2);
|
|
134
|
+
const midKey = node.keys[midIndex];
|
|
135
|
+
const newNode = this.createInternalNode();
|
|
136
|
+
newNode.keys = node.keys.splice(midIndex + 1);
|
|
137
|
+
newNode.children = node.children.splice(midIndex + 1);
|
|
138
|
+
node.keys.pop(); // Remove the promoted key
|
|
139
|
+
return {
|
|
140
|
+
key: midKey,
|
|
141
|
+
node: newNode,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Find child index for a key
|
|
146
|
+
*/
|
|
147
|
+
findChildIndex(node, key) {
|
|
148
|
+
let i = 0;
|
|
149
|
+
while (i < node.keys.length && this.compare(key, node.keys[i]) >= 0) {
|
|
150
|
+
i++;
|
|
151
|
+
}
|
|
152
|
+
return i;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get a value by key
|
|
156
|
+
*/
|
|
157
|
+
get(key) {
|
|
158
|
+
const leaf = this.findLeaf(key);
|
|
159
|
+
const index = leaf.keys.findIndex((k) => this.compare(k, key) === 0);
|
|
160
|
+
if (index === -1) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
return leaf.children[index][0];
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Delete a key
|
|
167
|
+
*/
|
|
168
|
+
delete(key) {
|
|
169
|
+
const leaf = this.findLeaf(key);
|
|
170
|
+
const index = leaf.keys.findIndex((k) => this.compare(k, key) === 0);
|
|
171
|
+
if (index === -1) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
leaf.keys.splice(index, 1);
|
|
175
|
+
leaf.children.splice(index, 1);
|
|
176
|
+
this.entryCount--;
|
|
177
|
+
// Note: Full B+Tree deletion with rebalancing is complex
|
|
178
|
+
// This simplified version doesn't rebalance
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Find the leaf node for a key
|
|
183
|
+
*/
|
|
184
|
+
findLeaf(key) {
|
|
185
|
+
let node = this.root;
|
|
186
|
+
while (!node.isLeaf) {
|
|
187
|
+
const childIndex = this.findChildIndex(node, key);
|
|
188
|
+
node = node.children[childIndex];
|
|
189
|
+
}
|
|
190
|
+
return node;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Range query
|
|
194
|
+
*/
|
|
195
|
+
*range(start, end, options) {
|
|
196
|
+
const inclusive = options?.inclusive ?? true;
|
|
197
|
+
const limit = options?.limit;
|
|
198
|
+
const reverse = options?.reverse ?? false;
|
|
199
|
+
if (reverse) {
|
|
200
|
+
// Reverse iteration is more complex, collect and reverse
|
|
201
|
+
const results = [];
|
|
202
|
+
for (const entry of this.rangeForward(start, end, inclusive, limit)) {
|
|
203
|
+
results.push(entry);
|
|
204
|
+
}
|
|
205
|
+
for (let i = results.length - 1; i >= 0; i--) {
|
|
206
|
+
yield results[i];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
yield* this.rangeForward(start, end, inclusive, limit);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Forward range iteration
|
|
215
|
+
*/
|
|
216
|
+
*rangeForward(start, end, inclusive, limit) {
|
|
217
|
+
let leaf = this.findLeaf(start);
|
|
218
|
+
let count = 0;
|
|
219
|
+
while (leaf) {
|
|
220
|
+
for (let i = 0; i < leaf.keys.length; i++) {
|
|
221
|
+
const key = leaf.keys[i];
|
|
222
|
+
// Skip keys before start
|
|
223
|
+
const startCmp = this.compare(key, start);
|
|
224
|
+
if (startCmp < 0 || (startCmp === 0 && !inclusive)) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
// Stop at keys after end
|
|
228
|
+
const endCmp = this.compare(key, end);
|
|
229
|
+
if (endCmp > 0 || (endCmp === 0 && !inclusive)) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
yield [key, leaf.children[i][0]];
|
|
233
|
+
count++;
|
|
234
|
+
if (limit !== undefined && count >= limit) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
leaf = leaf.next;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Get all entries
|
|
243
|
+
*/
|
|
244
|
+
*entries() {
|
|
245
|
+
let leaf = this.root;
|
|
246
|
+
// Find leftmost leaf
|
|
247
|
+
while (!leaf.isLeaf) {
|
|
248
|
+
leaf = leaf.children[0];
|
|
249
|
+
}
|
|
250
|
+
while (leaf) {
|
|
251
|
+
for (let i = 0; i < leaf.keys.length; i++) {
|
|
252
|
+
yield [leaf.keys[i], leaf.children[i][0]];
|
|
253
|
+
}
|
|
254
|
+
leaf = leaf.next;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Clear all entries
|
|
259
|
+
*/
|
|
260
|
+
clear() {
|
|
261
|
+
this.root = this.createLeafNode();
|
|
262
|
+
this.entryCount = 0;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get entry count
|
|
266
|
+
*/
|
|
267
|
+
get size() {
|
|
268
|
+
return this.entryCount;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Check if empty
|
|
272
|
+
*/
|
|
273
|
+
get isEmpty() {
|
|
274
|
+
return this.entryCount === 0;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get index statistics
|
|
278
|
+
*/
|
|
279
|
+
getStats() {
|
|
280
|
+
return {
|
|
281
|
+
name: 'btree',
|
|
282
|
+
type: 'btree',
|
|
283
|
+
entryCount: this.entryCount,
|
|
284
|
+
sizeBytes: this.estimateSize(),
|
|
285
|
+
depth: this.getDepth(),
|
|
286
|
+
hitRate: 0, // Would need to track hits/misses
|
|
287
|
+
lastUpdated: new Date(),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Estimate memory size
|
|
292
|
+
*/
|
|
293
|
+
estimateSize() {
|
|
294
|
+
// Rough estimate: 100 bytes per entry
|
|
295
|
+
return this.entryCount * 100;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Get tree depth
|
|
299
|
+
*/
|
|
300
|
+
getDepth() {
|
|
301
|
+
let depth = 0;
|
|
302
|
+
let node = this.root;
|
|
303
|
+
while (!node.isLeaf) {
|
|
304
|
+
depth++;
|
|
305
|
+
node = node.children[0];
|
|
306
|
+
}
|
|
307
|
+
return depth + 1;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=BPlusTreeIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BPlusTreeIndex.js","sourceRoot":"","sources":["../../src/index/BPlusTreeIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Bloom Filter
|
|
3
|
+
*
|
|
4
|
+
* Space-efficient probabilistic data structure for membership testing
|
|
5
|
+
*/
|
|
6
|
+
import type { BloomFilterConfig, IndexStats } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Bloom filter for efficient membership testing
|
|
9
|
+
*/
|
|
10
|
+
export declare class BloomFilter {
|
|
11
|
+
private bitArray;
|
|
12
|
+
private readonly size;
|
|
13
|
+
private readonly hashCount;
|
|
14
|
+
private itemCount;
|
|
15
|
+
constructor(config: BloomFilterConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Calculate optimal bit array size
|
|
18
|
+
*/
|
|
19
|
+
private calculateSize;
|
|
20
|
+
/**
|
|
21
|
+
* Calculate optimal number of hash functions
|
|
22
|
+
*/
|
|
23
|
+
private calculateHashCount;
|
|
24
|
+
/**
|
|
25
|
+
* Add an item to the filter
|
|
26
|
+
*/
|
|
27
|
+
add(item: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Check if an item might be in the filter
|
|
30
|
+
*/
|
|
31
|
+
mightContain(item: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Hash function using MurmurHash3-like algorithm with seed
|
|
34
|
+
*/
|
|
35
|
+
private hash;
|
|
36
|
+
/**
|
|
37
|
+
* Set a bit in the array
|
|
38
|
+
*/
|
|
39
|
+
private setBit;
|
|
40
|
+
/**
|
|
41
|
+
* Get a bit from the array
|
|
42
|
+
*/
|
|
43
|
+
private getBit;
|
|
44
|
+
/**
|
|
45
|
+
* Clear the filter
|
|
46
|
+
*/
|
|
47
|
+
clear(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get current false positive rate estimate
|
|
50
|
+
*/
|
|
51
|
+
getFalsePositiveRate(): number;
|
|
52
|
+
/**
|
|
53
|
+
* Get fill ratio (percentage of bits set)
|
|
54
|
+
*/
|
|
55
|
+
getFillRatio(): number;
|
|
56
|
+
/**
|
|
57
|
+
* Merge another bloom filter into this one
|
|
58
|
+
*/
|
|
59
|
+
merge(other: BloomFilter): void;
|
|
60
|
+
/**
|
|
61
|
+
* Create a copy of this filter
|
|
62
|
+
*/
|
|
63
|
+
clone(): BloomFilter;
|
|
64
|
+
/**
|
|
65
|
+
* Serialize to buffer
|
|
66
|
+
*/
|
|
67
|
+
serialize(): Uint8Array;
|
|
68
|
+
/**
|
|
69
|
+
* Deserialize from buffer
|
|
70
|
+
*/
|
|
71
|
+
static deserialize(buffer: Uint8Array): BloomFilter;
|
|
72
|
+
/**
|
|
73
|
+
* Get item count
|
|
74
|
+
*/
|
|
75
|
+
get count(): number;
|
|
76
|
+
/**
|
|
77
|
+
* Get bit array size in bytes
|
|
78
|
+
*/
|
|
79
|
+
get sizeBytes(): number;
|
|
80
|
+
/**
|
|
81
|
+
* Get index statistics
|
|
82
|
+
*/
|
|
83
|
+
getStats(): IndexStats;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=BloomFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BloomFilter.d.ts","sourceRoot":"","sources":["../../src/index/BloomFilter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjE;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,SAAS,CAAa;gBAElB,MAAM,EAAE,iBAAiB;IAMrC;;OAEG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IASvB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAWnC;;OAEG;IACH,OAAO,CAAC,IAAI;IA2BZ;;OAEG;IACH,OAAO,CAAC,MAAM;IAMd;;OAEG;IACH,OAAO,CAAC,MAAM;IAMd;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,oBAAoB,IAAI,MAAM;IAM9B;;OAEG;IACH,YAAY,IAAI,MAAM;IAYtB;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAa/B;;OAEG;IACH,KAAK,IAAI,WAAW;IAepB;;OAEG;IACH,SAAS,IAAI,UAAU;IAgBvB;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW;IAoBnD;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;OAEG;IACH,QAAQ,IAAI,UAAU;CAUvB"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Bloom Filter
|
|
3
|
+
*
|
|
4
|
+
* Space-efficient probabilistic data structure for membership testing
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Bloom filter for efficient membership testing
|
|
8
|
+
*/
|
|
9
|
+
export class BloomFilter {
|
|
10
|
+
bitArray;
|
|
11
|
+
size;
|
|
12
|
+
hashCount;
|
|
13
|
+
itemCount = 0;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.size = this.calculateSize(config.expectedItems, config.falsePositiveRate);
|
|
16
|
+
this.hashCount = this.calculateHashCount(this.size, config.expectedItems);
|
|
17
|
+
this.bitArray = new Uint8Array(Math.ceil(this.size / 8));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Calculate optimal bit array size
|
|
21
|
+
*/
|
|
22
|
+
calculateSize(n, p) {
|
|
23
|
+
// m = -n * ln(p) / (ln(2)^2)
|
|
24
|
+
return Math.ceil((-n * Math.log(p)) / (Math.log(2) ** 2));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Calculate optimal number of hash functions
|
|
28
|
+
*/
|
|
29
|
+
calculateHashCount(m, n) {
|
|
30
|
+
// k = (m/n) * ln(2)
|
|
31
|
+
return Math.ceil((m / n) * Math.log(2));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Add an item to the filter
|
|
35
|
+
*/
|
|
36
|
+
add(item) {
|
|
37
|
+
for (let i = 0; i < this.hashCount; i++) {
|
|
38
|
+
const hash = this.hash(item, i);
|
|
39
|
+
const index = hash % this.size;
|
|
40
|
+
this.setBit(index);
|
|
41
|
+
}
|
|
42
|
+
this.itemCount++;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if an item might be in the filter
|
|
46
|
+
*/
|
|
47
|
+
mightContain(item) {
|
|
48
|
+
for (let i = 0; i < this.hashCount; i++) {
|
|
49
|
+
const hash = this.hash(item, i);
|
|
50
|
+
const index = hash % this.size;
|
|
51
|
+
if (!this.getBit(index)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Hash function using MurmurHash3-like algorithm with seed
|
|
59
|
+
*/
|
|
60
|
+
hash(item, seed) {
|
|
61
|
+
let h1 = seed;
|
|
62
|
+
const c1 = 0xcc9e2d51;
|
|
63
|
+
const c2 = 0x1b873593;
|
|
64
|
+
for (let i = 0; i < item.length; i++) {
|
|
65
|
+
let k1 = item.charCodeAt(i);
|
|
66
|
+
k1 = Math.imul(k1, c1);
|
|
67
|
+
k1 = (k1 << 15) | (k1 >>> 17);
|
|
68
|
+
k1 = Math.imul(k1, c2);
|
|
69
|
+
h1 ^= k1;
|
|
70
|
+
h1 = (h1 << 13) | (h1 >>> 19);
|
|
71
|
+
h1 = Math.imul(h1, 5) + 0xe6546b64;
|
|
72
|
+
}
|
|
73
|
+
h1 ^= item.length;
|
|
74
|
+
h1 ^= h1 >>> 16;
|
|
75
|
+
h1 = Math.imul(h1, 0x85ebca6b);
|
|
76
|
+
h1 ^= h1 >>> 13;
|
|
77
|
+
h1 = Math.imul(h1, 0xc2b2ae35);
|
|
78
|
+
h1 ^= h1 >>> 16;
|
|
79
|
+
return h1 >>> 0;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Set a bit in the array
|
|
83
|
+
*/
|
|
84
|
+
setBit(index) {
|
|
85
|
+
const byteIndex = Math.floor(index / 8);
|
|
86
|
+
const bitIndex = index % 8;
|
|
87
|
+
this.bitArray[byteIndex] |= 1 << bitIndex;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get a bit from the array
|
|
91
|
+
*/
|
|
92
|
+
getBit(index) {
|
|
93
|
+
const byteIndex = Math.floor(index / 8);
|
|
94
|
+
const bitIndex = index % 8;
|
|
95
|
+
return (this.bitArray[byteIndex] & (1 << bitIndex)) !== 0;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Clear the filter
|
|
99
|
+
*/
|
|
100
|
+
clear() {
|
|
101
|
+
this.bitArray.fill(0);
|
|
102
|
+
this.itemCount = 0;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get current false positive rate estimate
|
|
106
|
+
*/
|
|
107
|
+
getFalsePositiveRate() {
|
|
108
|
+
// p = (1 - e^(-kn/m))^k
|
|
109
|
+
const exponent = (-this.hashCount * this.itemCount) / this.size;
|
|
110
|
+
return Math.pow(1 - Math.exp(exponent), this.hashCount);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get fill ratio (percentage of bits set)
|
|
114
|
+
*/
|
|
115
|
+
getFillRatio() {
|
|
116
|
+
let setBits = 0;
|
|
117
|
+
for (let i = 0; i < this.bitArray.length; i++) {
|
|
118
|
+
let byte = this.bitArray[i];
|
|
119
|
+
while (byte) {
|
|
120
|
+
setBits += byte & 1;
|
|
121
|
+
byte >>>= 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return setBits / this.size;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Merge another bloom filter into this one
|
|
128
|
+
*/
|
|
129
|
+
merge(other) {
|
|
130
|
+
if (other.size !== this.size) {
|
|
131
|
+
throw new Error('Cannot merge bloom filters of different sizes');
|
|
132
|
+
}
|
|
133
|
+
for (let i = 0; i < this.bitArray.length; i++) {
|
|
134
|
+
this.bitArray[i] |= other.bitArray[i];
|
|
135
|
+
}
|
|
136
|
+
// Item count is approximate after merge
|
|
137
|
+
this.itemCount += other.itemCount;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Create a copy of this filter
|
|
141
|
+
*/
|
|
142
|
+
clone() {
|
|
143
|
+
const copy = new BloomFilter({
|
|
144
|
+
expectedItems: this.itemCount || 1000,
|
|
145
|
+
falsePositiveRate: 0.01,
|
|
146
|
+
});
|
|
147
|
+
// Replace internals
|
|
148
|
+
copy.size = this.size;
|
|
149
|
+
copy.hashCount = this.hashCount;
|
|
150
|
+
copy.bitArray = new Uint8Array(this.bitArray);
|
|
151
|
+
copy.itemCount = this.itemCount;
|
|
152
|
+
return copy;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Serialize to buffer
|
|
156
|
+
*/
|
|
157
|
+
serialize() {
|
|
158
|
+
// Header: size (4 bytes) + hashCount (4 bytes) + itemCount (4 bytes)
|
|
159
|
+
const header = new ArrayBuffer(12);
|
|
160
|
+
const headerView = new DataView(header);
|
|
161
|
+
headerView.setUint32(0, this.size, true);
|
|
162
|
+
headerView.setUint32(4, this.hashCount, true);
|
|
163
|
+
headerView.setUint32(8, this.itemCount, true);
|
|
164
|
+
// Combine header and bit array
|
|
165
|
+
const result = new Uint8Array(12 + this.bitArray.length);
|
|
166
|
+
result.set(new Uint8Array(header), 0);
|
|
167
|
+
result.set(this.bitArray, 12);
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Deserialize from buffer
|
|
172
|
+
*/
|
|
173
|
+
static deserialize(buffer) {
|
|
174
|
+
const headerView = new DataView(buffer.buffer, buffer.byteOffset, 12);
|
|
175
|
+
const size = headerView.getUint32(0, true);
|
|
176
|
+
const hashCount = headerView.getUint32(4, true);
|
|
177
|
+
const itemCount = headerView.getUint32(8, true);
|
|
178
|
+
const filter = new BloomFilter({
|
|
179
|
+
expectedItems: 1000,
|
|
180
|
+
falsePositiveRate: 0.01,
|
|
181
|
+
});
|
|
182
|
+
// Replace internals
|
|
183
|
+
filter.size = size;
|
|
184
|
+
filter.hashCount = hashCount;
|
|
185
|
+
filter.itemCount = itemCount;
|
|
186
|
+
filter.bitArray = buffer.slice(12);
|
|
187
|
+
return filter;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Get item count
|
|
191
|
+
*/
|
|
192
|
+
get count() {
|
|
193
|
+
return this.itemCount;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get bit array size in bytes
|
|
197
|
+
*/
|
|
198
|
+
get sizeBytes() {
|
|
199
|
+
return this.bitArray.length;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get index statistics
|
|
203
|
+
*/
|
|
204
|
+
getStats() {
|
|
205
|
+
return {
|
|
206
|
+
name: 'bloom',
|
|
207
|
+
type: 'bloom',
|
|
208
|
+
entryCount: this.itemCount,
|
|
209
|
+
sizeBytes: this.bitArray.length,
|
|
210
|
+
hitRate: 1 - this.getFalsePositiveRate(),
|
|
211
|
+
lastUpdated: new Date(),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=BloomFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BloomFilter.js","sourceRoot":"","sources":["../../src/index/BloomFilter.ts"],"names":[],"mappings":"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"}
|