@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,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Index Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages all indexes for a shard
|
|
5
|
+
*/
|
|
6
|
+
import { ok, err } from 'neverthrow';
|
|
7
|
+
import { IndexError, IndexNotFoundError } from '../errors.js';
|
|
8
|
+
import { BPlusTreeIndex } from './BPlusTreeIndex.js';
|
|
9
|
+
import { FullTextIndex } from './FullTextIndex.js';
|
|
10
|
+
import { GraphIndex } from './GraphIndex.js';
|
|
11
|
+
import { BloomFilter } from './BloomFilter.js';
|
|
12
|
+
/**
|
|
13
|
+
* Index manager for coordinating multiple indexes
|
|
14
|
+
*/
|
|
15
|
+
export class IndexManager {
|
|
16
|
+
indexes = new Map();
|
|
17
|
+
entityIndex;
|
|
18
|
+
bloomFilter;
|
|
19
|
+
graphIndex;
|
|
20
|
+
constructor() {
|
|
21
|
+
// Default indexes
|
|
22
|
+
this.entityIndex = new BPlusTreeIndex();
|
|
23
|
+
this.bloomFilter = new BloomFilter({
|
|
24
|
+
expectedItems: 100000,
|
|
25
|
+
falsePositiveRate: 0.01,
|
|
26
|
+
});
|
|
27
|
+
this.graphIndex = new GraphIndex();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a new index
|
|
31
|
+
*/
|
|
32
|
+
createIndex(config) {
|
|
33
|
+
if (this.indexes.has(config.name)) {
|
|
34
|
+
return err(new IndexError(`Index already exists: ${config.name}`, config.name));
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const index = this.createIndexByType(config);
|
|
38
|
+
this.indexes.set(config.name, { config, index });
|
|
39
|
+
return ok(undefined);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return err(new IndexError(`Failed to create index: ${error instanceof Error ? error.message : String(error)}`, config.name, error instanceof Error ? error : undefined));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create index by type
|
|
47
|
+
*/
|
|
48
|
+
createIndexByType(config) {
|
|
49
|
+
switch (config.type) {
|
|
50
|
+
case 'btree':
|
|
51
|
+
return new BPlusTreeIndex();
|
|
52
|
+
case 'fulltext':
|
|
53
|
+
return new FullTextIndex();
|
|
54
|
+
case 'graph':
|
|
55
|
+
return new GraphIndex();
|
|
56
|
+
case 'bloom':
|
|
57
|
+
return new BloomFilter({
|
|
58
|
+
expectedItems: 100000,
|
|
59
|
+
falsePositiveRate: 0.01,
|
|
60
|
+
});
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Unknown index type: ${config.type}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Drop an index
|
|
67
|
+
*/
|
|
68
|
+
dropIndex(name) {
|
|
69
|
+
if (!this.indexes.has(name)) {
|
|
70
|
+
return err(new IndexNotFoundError(name));
|
|
71
|
+
}
|
|
72
|
+
this.indexes.delete(name);
|
|
73
|
+
return ok(undefined);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Index an entity
|
|
77
|
+
*/
|
|
78
|
+
indexEntity(entity) {
|
|
79
|
+
// Add to main entity index
|
|
80
|
+
this.entityIndex.insert(entity.id, entity);
|
|
81
|
+
// Add to bloom filter for existence check
|
|
82
|
+
this.bloomFilter.add(entity.id);
|
|
83
|
+
// Index in custom indexes
|
|
84
|
+
for (const { config, index } of this.indexes.values()) {
|
|
85
|
+
this.indexEntityInCustomIndex(entity, config, index);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Index entity in a custom index
|
|
90
|
+
*/
|
|
91
|
+
indexEntityInCustomIndex(entity, config, index) {
|
|
92
|
+
switch (config.type) {
|
|
93
|
+
case 'btree': {
|
|
94
|
+
const btree = index;
|
|
95
|
+
const key = this.extractKey(entity, config.fields);
|
|
96
|
+
const existing = btree.get(key) ?? [];
|
|
97
|
+
if (!existing.includes(entity.id)) {
|
|
98
|
+
btree.insert(key, [...existing, entity.id]);
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case 'fulltext': {
|
|
103
|
+
const fulltext = index;
|
|
104
|
+
const content = this.extractTextContent(entity, config.fields);
|
|
105
|
+
fulltext.index({ id: entity.id, content });
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'bloom': {
|
|
109
|
+
const bloom = index;
|
|
110
|
+
const key = this.extractKey(entity, config.fields);
|
|
111
|
+
bloom.add(key);
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Remove entity from indexes
|
|
118
|
+
*/
|
|
119
|
+
removeEntity(entityId) {
|
|
120
|
+
// Remove from main index
|
|
121
|
+
this.entityIndex.delete(entityId);
|
|
122
|
+
// Note: Cannot remove from bloom filter
|
|
123
|
+
// Remove from custom indexes
|
|
124
|
+
for (const { config, index } of this.indexes.values()) {
|
|
125
|
+
this.removeEntityFromCustomIndex(entityId, config, index);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Remove entity from custom index
|
|
130
|
+
*/
|
|
131
|
+
removeEntityFromCustomIndex(entityId, config, index) {
|
|
132
|
+
switch (config.type) {
|
|
133
|
+
case 'fulltext': {
|
|
134
|
+
const fulltext = index;
|
|
135
|
+
fulltext.removeDocument(entityId);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
// B+Tree removal would need to find and remove from value arrays
|
|
139
|
+
// Bloom filter doesn't support removal
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Index a relationship
|
|
144
|
+
*/
|
|
145
|
+
indexRelationship(relationship) {
|
|
146
|
+
const edge = {
|
|
147
|
+
id: relationship.id,
|
|
148
|
+
sourceId: relationship.sourceId,
|
|
149
|
+
targetId: relationship.targetId,
|
|
150
|
+
type: relationship.type,
|
|
151
|
+
weight: relationship.metadata.weight,
|
|
152
|
+
};
|
|
153
|
+
this.graphIndex.addEdge(edge);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Remove a relationship from indexes
|
|
157
|
+
*/
|
|
158
|
+
removeRelationship(relationshipId) {
|
|
159
|
+
this.graphIndex.removeEdge(relationshipId);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Check if entity might exist (using bloom filter)
|
|
163
|
+
*/
|
|
164
|
+
mightExist(entityId) {
|
|
165
|
+
return this.bloomFilter.mightContain(entityId);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get entity by ID
|
|
169
|
+
*/
|
|
170
|
+
getEntity(entityId) {
|
|
171
|
+
return this.entityIndex.get(entityId);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Search by attribute using B+Tree index
|
|
175
|
+
*/
|
|
176
|
+
searchByAttribute(indexName, value) {
|
|
177
|
+
const wrapper = this.indexes.get(indexName);
|
|
178
|
+
if (!wrapper || wrapper.config.type !== 'btree') {
|
|
179
|
+
return err(new IndexNotFoundError(indexName));
|
|
180
|
+
}
|
|
181
|
+
const btree = wrapper.index;
|
|
182
|
+
const result = btree.get(value);
|
|
183
|
+
return ok(result ?? []);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Full-text search
|
|
187
|
+
*/
|
|
188
|
+
searchFullText(indexName, query, limit = 10) {
|
|
189
|
+
const wrapper = this.indexes.get(indexName);
|
|
190
|
+
if (!wrapper || wrapper.config.type !== 'fulltext') {
|
|
191
|
+
return err(new IndexNotFoundError(indexName));
|
|
192
|
+
}
|
|
193
|
+
const fulltext = wrapper.index;
|
|
194
|
+
const results = fulltext.search(query, limit);
|
|
195
|
+
return ok(results.map((r) => r.id));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Get graph index
|
|
199
|
+
*/
|
|
200
|
+
getGraphIndex() {
|
|
201
|
+
return this.graphIndex;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get bloom filter
|
|
205
|
+
*/
|
|
206
|
+
getBloomFilter() {
|
|
207
|
+
return this.bloomFilter;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Extract key from entity for indexing
|
|
211
|
+
*/
|
|
212
|
+
extractKey(entity, fields) {
|
|
213
|
+
return fields
|
|
214
|
+
.map((field) => {
|
|
215
|
+
switch (field) {
|
|
216
|
+
case 'type':
|
|
217
|
+
return entity.type;
|
|
218
|
+
case 'name':
|
|
219
|
+
return entity.name;
|
|
220
|
+
case 'namespace':
|
|
221
|
+
return entity.namespace ?? '';
|
|
222
|
+
default:
|
|
223
|
+
return String(entity.attributes[field] ?? '');
|
|
224
|
+
}
|
|
225
|
+
})
|
|
226
|
+
.join(':');
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Extract text content for full-text indexing
|
|
230
|
+
*/
|
|
231
|
+
extractTextContent(entity, fields) {
|
|
232
|
+
return fields
|
|
233
|
+
.map((field) => {
|
|
234
|
+
switch (field) {
|
|
235
|
+
case 'name':
|
|
236
|
+
return entity.name;
|
|
237
|
+
case 'namespace':
|
|
238
|
+
return entity.namespace ?? '';
|
|
239
|
+
default:
|
|
240
|
+
return String(entity.attributes[field] ?? '');
|
|
241
|
+
}
|
|
242
|
+
})
|
|
243
|
+
.join(' ');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get all index statistics
|
|
247
|
+
*/
|
|
248
|
+
getAllStats() {
|
|
249
|
+
const stats = [
|
|
250
|
+
this.entityIndex.getStats(),
|
|
251
|
+
this.bloomFilter.getStats(),
|
|
252
|
+
this.graphIndex.getStats(),
|
|
253
|
+
];
|
|
254
|
+
for (const { index } of this.indexes.values()) {
|
|
255
|
+
if ('getStats' in index) {
|
|
256
|
+
stats.push(index.getStats());
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return stats;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Clear all indexes
|
|
263
|
+
*/
|
|
264
|
+
clear() {
|
|
265
|
+
this.entityIndex.clear();
|
|
266
|
+
this.bloomFilter.clear();
|
|
267
|
+
this.graphIndex.clear();
|
|
268
|
+
for (const { index } of this.indexes.values()) {
|
|
269
|
+
if ('clear' in index) {
|
|
270
|
+
index.clear();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get entity count
|
|
276
|
+
*/
|
|
277
|
+
get entityCount() {
|
|
278
|
+
return this.entityIndex.size;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get relationship count
|
|
282
|
+
*/
|
|
283
|
+
get relationshipCount() {
|
|
284
|
+
return this.graphIndex.size;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=IndexManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IndexManager.js","sourceRoot":"","sources":["../../src/index/IndexManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Index Module
|
|
3
|
+
*
|
|
4
|
+
* Exports for index functionality
|
|
5
|
+
*/
|
|
6
|
+
export { BPlusTreeIndex } from './BPlusTreeIndex.js';
|
|
7
|
+
export { FullTextIndex } from './FullTextIndex.js';
|
|
8
|
+
export { GraphIndex } from './GraphIndex.js';
|
|
9
|
+
export { BloomFilter } from './BloomFilter.js';
|
|
10
|
+
export { IndexManager } from './IndexManager.js';
|
|
11
|
+
export type { IndexConfig, IndexStats, IndexType, BPlusTreeConfig, RangeOptions, BloomFilterConfig, CompressionType, } from '../types.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,YAAY,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,eAAe,GAChB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Index Module
|
|
3
|
+
*
|
|
4
|
+
* Exports for index functionality
|
|
5
|
+
*/
|
|
6
|
+
export { BPlusTreeIndex } from './BPlusTreeIndex.js';
|
|
7
|
+
export { FullTextIndex } from './FullTextIndex.js';
|
|
8
|
+
export { GraphIndex } from './GraphIndex.js';
|
|
9
|
+
export { BloomFilter } from './BloomFilter.js';
|
|
10
|
+
export { IndexManager } from './IndexManager.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Main Entry Point
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export * from './errors.js';
|
|
6
|
+
export * from './ShardManager.js';
|
|
7
|
+
export * from './IndexManager.js';
|
|
8
|
+
export * from './CacheManager.js';
|
|
9
|
+
export * from './QueryCoordinator.js';
|
|
10
|
+
export * from './SyncController.js';
|
|
11
|
+
export * from './YataScaleManager.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Main Entry Point
|
|
3
|
+
*/
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
export * from './errors.js';
|
|
6
|
+
export * from './ShardManager.js';
|
|
7
|
+
export * from './IndexManager.js';
|
|
8
|
+
export * from './CacheManager.js';
|
|
9
|
+
export * from './QueryCoordinator.js';
|
|
10
|
+
export * from './SyncController.js';
|
|
11
|
+
export * from './YataScaleManager.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Distributed Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes queries across multiple shards
|
|
5
|
+
*/
|
|
6
|
+
import { type Result } from 'neverthrow';
|
|
7
|
+
import type { GraphQuery, QueryResult, QueryPlan, Entity, Relationship } from '../types.js';
|
|
8
|
+
import { QueryExecutionError } from '../errors.js';
|
|
9
|
+
import { WorkerPool } from './WorkerPool.js';
|
|
10
|
+
/**
|
|
11
|
+
* Shard query function
|
|
12
|
+
*/
|
|
13
|
+
export type ShardQueryFn = (shardId: string, query: GraphQuery) => Promise<{
|
|
14
|
+
entities: Entity[];
|
|
15
|
+
relationships: Relationship[];
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Execution context
|
|
19
|
+
*/
|
|
20
|
+
export interface ExecutionContext {
|
|
21
|
+
readonly queryId: string;
|
|
22
|
+
readonly startTime: Date;
|
|
23
|
+
readonly timeoutMs: number;
|
|
24
|
+
readonly shards: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Distributed query executor
|
|
28
|
+
*/
|
|
29
|
+
export declare class DistributedExecutor {
|
|
30
|
+
private readonly workerPool;
|
|
31
|
+
private readonly defaultTimeoutMs;
|
|
32
|
+
constructor(parallelism?: number, defaultTimeoutMs?: number);
|
|
33
|
+
/**
|
|
34
|
+
* Execute query across shards
|
|
35
|
+
*/
|
|
36
|
+
execute(plan: QueryPlan, shards: string[], queryFn: ShardQueryFn): Promise<Result<QueryResult, QueryExecutionError>>;
|
|
37
|
+
/**
|
|
38
|
+
* Execute query in parallel across shards
|
|
39
|
+
*/
|
|
40
|
+
private executeParallel;
|
|
41
|
+
/**
|
|
42
|
+
* Execute query sequentially across shards
|
|
43
|
+
*/
|
|
44
|
+
private executeSequential;
|
|
45
|
+
/**
|
|
46
|
+
* Execute promise with timeout
|
|
47
|
+
*/
|
|
48
|
+
private executeWithTimeout;
|
|
49
|
+
/**
|
|
50
|
+
* Merge results from multiple shards
|
|
51
|
+
*/
|
|
52
|
+
private mergeResults;
|
|
53
|
+
/**
|
|
54
|
+
* Deduplicate entities by ID
|
|
55
|
+
*/
|
|
56
|
+
private deduplicateEntities;
|
|
57
|
+
/**
|
|
58
|
+
* Deduplicate relationships by ID
|
|
59
|
+
*/
|
|
60
|
+
private deduplicateRelationships;
|
|
61
|
+
/**
|
|
62
|
+
* Apply sort order
|
|
63
|
+
*/
|
|
64
|
+
private applySort;
|
|
65
|
+
/**
|
|
66
|
+
* Apply limit
|
|
67
|
+
*/
|
|
68
|
+
private applyLimit;
|
|
69
|
+
/**
|
|
70
|
+
* Get worker pool
|
|
71
|
+
*/
|
|
72
|
+
getWorkerPool(): WorkerPool;
|
|
73
|
+
/**
|
|
74
|
+
* Shutdown executor
|
|
75
|
+
*/
|
|
76
|
+
shutdown(): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=DistributedExecutor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DistributedExecutor.d.ts","sourceRoot":"","sources":["../../src/query/DistributedExecutor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,SAAS,EACT,MAAM,EACN,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAqB,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,UAAU,EAAmB,MAAM,iBAAiB,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,KACd,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAC3B;AAYD;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,WAAW,GAAE,MAAU,EAAE,gBAAgB,GAAE,MAAc;IAKrE;;OAEG;IACG,OAAO,CACX,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IA4BpD;;OAEG;YACW,eAAe;IA8B7B;;OAEG;YACW,iBAAiB;IA+B/B;;OAEG;YACW,kBAAkB;IAchC;;OAEG;IACH,OAAO,CAAC,YAAY;IA0CpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;OAEG;IACH,OAAO,CAAC,SAAS;IAwCjB;;OAEG;IACH,OAAO,CAAC,UAAU;IASlB;;OAEG;IACH,aAAa,IAAI,UAAU;IAI3B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/yata-scale - Distributed Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes queries across multiple shards
|
|
5
|
+
*/
|
|
6
|
+
import { ok, err } from 'neverthrow';
|
|
7
|
+
import { QueryExecutionError, QueryTimeoutError } from '../errors.js';
|
|
8
|
+
import { WorkerPool } from './WorkerPool.js';
|
|
9
|
+
/**
|
|
10
|
+
* Distributed query executor
|
|
11
|
+
*/
|
|
12
|
+
export class DistributedExecutor {
|
|
13
|
+
workerPool;
|
|
14
|
+
defaultTimeoutMs;
|
|
15
|
+
constructor(parallelism = 4, defaultTimeoutMs = 30000) {
|
|
16
|
+
this.workerPool = new WorkerPool(parallelism);
|
|
17
|
+
this.defaultTimeoutMs = defaultTimeoutMs;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Execute query across shards
|
|
21
|
+
*/
|
|
22
|
+
async execute(plan, shards, queryFn) {
|
|
23
|
+
const context = {
|
|
24
|
+
queryId: `query_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
25
|
+
startTime: new Date(),
|
|
26
|
+
timeoutMs: plan.query.timeout ?? this.defaultTimeoutMs,
|
|
27
|
+
shards,
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
if (plan.parallelizable && shards.length > 1) {
|
|
31
|
+
return await this.executeParallel(plan, context, queryFn);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
return await this.executeSequential(plan, context, queryFn);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof QueryTimeoutError) {
|
|
39
|
+
return err(error);
|
|
40
|
+
}
|
|
41
|
+
return err(new QueryExecutionError(`Query execution failed: ${error instanceof Error ? error.message : String(error)}`, context.queryId, error instanceof Error ? error : undefined));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Execute query in parallel across shards
|
|
46
|
+
*/
|
|
47
|
+
async executeParallel(plan, context, queryFn) {
|
|
48
|
+
const tasks = context.shards.map((shardId) => ({
|
|
49
|
+
id: `${context.queryId}_${shardId}`,
|
|
50
|
+
data: { shardId, query: plan.query },
|
|
51
|
+
execute: async (data) => {
|
|
52
|
+
const start = Date.now();
|
|
53
|
+
const result = await queryFn(data.shardId, data.query);
|
|
54
|
+
return {
|
|
55
|
+
shardId: data.shardId,
|
|
56
|
+
entities: result.entities,
|
|
57
|
+
relationships: result.relationships,
|
|
58
|
+
durationMs: Date.now() - start,
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
}));
|
|
62
|
+
// Execute with timeout
|
|
63
|
+
const results = await this.executeWithTimeout(this.workerPool.submitAll(tasks), context.timeoutMs);
|
|
64
|
+
// Merge results
|
|
65
|
+
return this.mergeResults(results, plan, context);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Execute query sequentially across shards
|
|
69
|
+
*/
|
|
70
|
+
async executeSequential(plan, context, queryFn) {
|
|
71
|
+
const results = [];
|
|
72
|
+
for (const shardId of context.shards) {
|
|
73
|
+
const elapsed = Date.now() - context.startTime.getTime();
|
|
74
|
+
if (elapsed >= context.timeoutMs) {
|
|
75
|
+
throw new QueryTimeoutError(context.queryId, context.timeoutMs);
|
|
76
|
+
}
|
|
77
|
+
const start = Date.now();
|
|
78
|
+
const result = await queryFn(shardId, plan.query);
|
|
79
|
+
results.push({
|
|
80
|
+
taskId: `${context.queryId}_${shardId}`,
|
|
81
|
+
result: {
|
|
82
|
+
shardId,
|
|
83
|
+
entities: result.entities,
|
|
84
|
+
relationships: result.relationships,
|
|
85
|
+
durationMs: Date.now() - start,
|
|
86
|
+
},
|
|
87
|
+
durationMs: Date.now() - start,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return this.mergeResults(results, plan, context);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Execute promise with timeout
|
|
94
|
+
*/
|
|
95
|
+
async executeWithTimeout(promise, timeoutMs) {
|
|
96
|
+
return Promise.race([
|
|
97
|
+
promise,
|
|
98
|
+
new Promise((_, reject) => {
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
reject(new QueryTimeoutError('query', timeoutMs));
|
|
101
|
+
}, timeoutMs);
|
|
102
|
+
}),
|
|
103
|
+
]);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Merge results from multiple shards
|
|
107
|
+
*/
|
|
108
|
+
mergeResults(results, plan, context) {
|
|
109
|
+
const entities = [];
|
|
110
|
+
const relationships = [];
|
|
111
|
+
const errors = [];
|
|
112
|
+
for (const result of results) {
|
|
113
|
+
if (result.error) {
|
|
114
|
+
errors.push(result.error);
|
|
115
|
+
}
|
|
116
|
+
else if (result.result) {
|
|
117
|
+
entities.push(...result.result.entities);
|
|
118
|
+
relationships.push(...result.result.relationships);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Deduplicate by ID
|
|
122
|
+
const uniqueEntities = this.deduplicateEntities(entities);
|
|
123
|
+
const uniqueRelationships = this.deduplicateRelationships(relationships);
|
|
124
|
+
// Apply final sort if specified
|
|
125
|
+
const sortedEntities = this.applySort(uniqueEntities, plan.query);
|
|
126
|
+
// Apply final limit if specified
|
|
127
|
+
const limitedEntities = this.applyLimit(sortedEntities, plan.query);
|
|
128
|
+
const totalDuration = Date.now() - context.startTime.getTime();
|
|
129
|
+
return ok({
|
|
130
|
+
entities: limitedEntities,
|
|
131
|
+
relationships: uniqueRelationships,
|
|
132
|
+
totalCount: uniqueEntities.length,
|
|
133
|
+
hasMore: uniqueEntities.length > limitedEntities.length,
|
|
134
|
+
cursor: limitedEntities.length > 0
|
|
135
|
+
? limitedEntities[limitedEntities.length - 1].id
|
|
136
|
+
: undefined,
|
|
137
|
+
executionTimeMs: totalDuration,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Deduplicate entities by ID
|
|
142
|
+
*/
|
|
143
|
+
deduplicateEntities(entities) {
|
|
144
|
+
const seen = new Map();
|
|
145
|
+
for (const entity of entities) {
|
|
146
|
+
// Keep the newest version based on updatedAt
|
|
147
|
+
const existing = seen.get(entity.id);
|
|
148
|
+
if (!existing || entity.metadata.updatedAt > existing.metadata.updatedAt) {
|
|
149
|
+
seen.set(entity.id, entity);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return [...seen.values()];
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Deduplicate relationships by ID
|
|
156
|
+
*/
|
|
157
|
+
deduplicateRelationships(relationships) {
|
|
158
|
+
const seen = new Map();
|
|
159
|
+
for (const rel of relationships) {
|
|
160
|
+
const existing = seen.get(rel.id);
|
|
161
|
+
if (!existing || rel.metadata.updatedAt > existing.metadata.updatedAt) {
|
|
162
|
+
seen.set(rel.id, rel);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return [...seen.values()];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Apply sort order
|
|
169
|
+
*/
|
|
170
|
+
applySort(entities, query) {
|
|
171
|
+
if (!query.orderBy) {
|
|
172
|
+
return entities;
|
|
173
|
+
}
|
|
174
|
+
const field = query.orderBy;
|
|
175
|
+
const direction = query.orderDirection ?? 'asc';
|
|
176
|
+
return [...entities].sort((a, b) => {
|
|
177
|
+
let aVal;
|
|
178
|
+
let bVal;
|
|
179
|
+
// Handle special fields
|
|
180
|
+
if (field === 'name') {
|
|
181
|
+
aVal = a.name;
|
|
182
|
+
bVal = b.name;
|
|
183
|
+
}
|
|
184
|
+
else if (field === 'createdAt') {
|
|
185
|
+
aVal = a.metadata.createdAt;
|
|
186
|
+
bVal = b.metadata.createdAt;
|
|
187
|
+
}
|
|
188
|
+
else if (field === 'updatedAt') {
|
|
189
|
+
aVal = a.metadata.updatedAt;
|
|
190
|
+
bVal = b.metadata.updatedAt;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
aVal = a.attributes[field];
|
|
194
|
+
bVal = b.attributes[field];
|
|
195
|
+
}
|
|
196
|
+
let cmp = 0;
|
|
197
|
+
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
198
|
+
cmp = aVal.localeCompare(bVal);
|
|
199
|
+
}
|
|
200
|
+
else if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
201
|
+
cmp = aVal - bVal;
|
|
202
|
+
}
|
|
203
|
+
else if (aVal instanceof Date && bVal instanceof Date) {
|
|
204
|
+
cmp = aVal.getTime() - bVal.getTime();
|
|
205
|
+
}
|
|
206
|
+
return direction === 'desc' ? -cmp : cmp;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Apply limit
|
|
211
|
+
*/
|
|
212
|
+
applyLimit(entities, query) {
|
|
213
|
+
if (query.limit === undefined) {
|
|
214
|
+
return entities;
|
|
215
|
+
}
|
|
216
|
+
const offset = query.offset ?? 0;
|
|
217
|
+
return entities.slice(offset, offset + query.limit);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get worker pool
|
|
221
|
+
*/
|
|
222
|
+
getWorkerPool() {
|
|
223
|
+
return this.workerPool;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Shutdown executor
|
|
227
|
+
*/
|
|
228
|
+
async shutdown() {
|
|
229
|
+
await this.workerPool.shutdown();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=DistributedExecutor.js.map
|