serializable-bptree 9.0.0 → 9.0.1
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/cjs/index.cjs +198 -58
- package/dist/esm/index.mjs +198 -58
- package/dist/types/BPTreePureAsync.d.ts +4 -0
- package/dist/types/BPTreePureSync.d.ts +1 -0
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -5014,32 +5014,73 @@ var BPTreePureSync = class {
|
|
|
5014
5014
|
createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5015
5015
|
const id = strategy.id(leaf);
|
|
5016
5016
|
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5017
|
-
|
|
5017
|
+
return node;
|
|
5018
|
+
},
|
|
5019
|
+
updateNode() {
|
|
5020
|
+
},
|
|
5021
|
+
deleteNode() {
|
|
5022
|
+
},
|
|
5023
|
+
readHead() {
|
|
5024
|
+
return strategy.readHead();
|
|
5025
|
+
},
|
|
5026
|
+
writeHead() {
|
|
5027
|
+
}
|
|
5028
|
+
};
|
|
5029
|
+
}
|
|
5030
|
+
_createBufferedOps() {
|
|
5031
|
+
const strategy = this.strategy;
|
|
5032
|
+
const writeBuffer = /* @__PURE__ */ new Map();
|
|
5033
|
+
const deleteBuffer = /* @__PURE__ */ new Set();
|
|
5034
|
+
let headBuffer = null;
|
|
5035
|
+
const ops = {
|
|
5036
|
+
getNode(id) {
|
|
5037
|
+
const buffered = writeBuffer.get(id);
|
|
5038
|
+
if (buffered) return buffered;
|
|
5039
|
+
return strategy.read(id);
|
|
5040
|
+
},
|
|
5041
|
+
createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5042
|
+
const id = strategy.id(leaf);
|
|
5043
|
+
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5044
|
+
writeBuffer.set(id, node);
|
|
5018
5045
|
return node;
|
|
5019
5046
|
},
|
|
5020
5047
|
updateNode(node) {
|
|
5021
|
-
|
|
5048
|
+
writeBuffer.set(node.id, node);
|
|
5022
5049
|
},
|
|
5023
5050
|
deleteNode(node) {
|
|
5024
|
-
|
|
5051
|
+
deleteBuffer.add(node.id);
|
|
5052
|
+
writeBuffer.delete(node.id);
|
|
5025
5053
|
},
|
|
5026
5054
|
readHead() {
|
|
5055
|
+
if (headBuffer) return headBuffer;
|
|
5027
5056
|
return strategy.readHead();
|
|
5028
5057
|
},
|
|
5029
5058
|
writeHead(head) {
|
|
5030
|
-
|
|
5059
|
+
headBuffer = head;
|
|
5031
5060
|
}
|
|
5032
5061
|
};
|
|
5062
|
+
function flush() {
|
|
5063
|
+
for (const id of deleteBuffer) {
|
|
5064
|
+
strategy.delete(id);
|
|
5065
|
+
}
|
|
5066
|
+
for (const [id, node] of writeBuffer) {
|
|
5067
|
+
strategy.write(id, node);
|
|
5068
|
+
}
|
|
5069
|
+
if (headBuffer) {
|
|
5070
|
+
strategy.writeHead(headBuffer);
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
return { ops, flush };
|
|
5033
5074
|
}
|
|
5034
5075
|
init() {
|
|
5035
|
-
|
|
5076
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5036
5077
|
this._ctx = {
|
|
5037
5078
|
rootId: "",
|
|
5038
5079
|
order: this.strategy.order,
|
|
5039
5080
|
headData: () => this.strategy.head.data
|
|
5040
5081
|
};
|
|
5041
5082
|
initOp(
|
|
5042
|
-
|
|
5083
|
+
ops,
|
|
5043
5084
|
this._ctx,
|
|
5044
5085
|
this.strategy.order,
|
|
5045
5086
|
this.strategy.head,
|
|
@@ -5047,6 +5088,8 @@ var BPTreePureSync = class {
|
|
|
5047
5088
|
this.strategy.head = head;
|
|
5048
5089
|
}
|
|
5049
5090
|
);
|
|
5091
|
+
flush();
|
|
5092
|
+
this._ops = this._createOps();
|
|
5050
5093
|
}
|
|
5051
5094
|
/**
|
|
5052
5095
|
* Returns the ID of the root node.
|
|
@@ -5120,16 +5163,24 @@ var BPTreePureSync = class {
|
|
|
5120
5163
|
}
|
|
5121
5164
|
// ─── Mutation ────────────────────────────────────────────────────
|
|
5122
5165
|
insert(key, value) {
|
|
5123
|
-
|
|
5166
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5167
|
+
insertOp(ops, this._ctx, key, value, this.comparator);
|
|
5168
|
+
flush();
|
|
5124
5169
|
}
|
|
5125
5170
|
delete(key, value) {
|
|
5126
|
-
|
|
5171
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5172
|
+
deleteOp(ops, this._ctx, key, this.comparator, value);
|
|
5173
|
+
flush();
|
|
5127
5174
|
}
|
|
5128
5175
|
batchInsert(entries) {
|
|
5129
|
-
|
|
5176
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5177
|
+
batchInsertOp(ops, this._ctx, entries, this.comparator);
|
|
5178
|
+
flush();
|
|
5130
5179
|
}
|
|
5131
5180
|
bulkLoad(entries) {
|
|
5132
|
-
|
|
5181
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5182
|
+
bulkLoadOp(ops, this._ctx, entries, this.comparator);
|
|
5183
|
+
flush();
|
|
5133
5184
|
}
|
|
5134
5185
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
5135
5186
|
getHeadData() {
|
|
@@ -5140,15 +5191,17 @@ var BPTreePureSync = class {
|
|
|
5140
5191
|
return head.data;
|
|
5141
5192
|
}
|
|
5142
5193
|
setHeadData(data) {
|
|
5143
|
-
const
|
|
5194
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5195
|
+
const head = ops.readHead();
|
|
5144
5196
|
if (head === null) {
|
|
5145
5197
|
throw new Error("Head not found");
|
|
5146
5198
|
}
|
|
5147
|
-
|
|
5199
|
+
ops.writeHead({
|
|
5148
5200
|
root: head.root,
|
|
5149
5201
|
order: head.order,
|
|
5150
5202
|
data
|
|
5151
5203
|
});
|
|
5204
|
+
flush();
|
|
5152
5205
|
}
|
|
5153
5206
|
// ─── Static utilities ────────────────────────────────────────────
|
|
5154
5207
|
static ChooseDriver = BPTreeTransaction.ChooseDriver;
|
|
@@ -5159,6 +5212,7 @@ var BPTreePureAsync = class {
|
|
|
5159
5212
|
strategy;
|
|
5160
5213
|
comparator;
|
|
5161
5214
|
option;
|
|
5215
|
+
lock = new Ryoiki2();
|
|
5162
5216
|
_cachedRegexp = /* @__PURE__ */ new Map();
|
|
5163
5217
|
_ctx;
|
|
5164
5218
|
_ops;
|
|
@@ -5184,39 +5238,93 @@ var BPTreePureAsync = class {
|
|
|
5184
5238
|
async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5185
5239
|
const id = await strategy.id(leaf);
|
|
5186
5240
|
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5187
|
-
|
|
5241
|
+
return node;
|
|
5242
|
+
},
|
|
5243
|
+
async updateNode() {
|
|
5244
|
+
},
|
|
5245
|
+
async deleteNode() {
|
|
5246
|
+
},
|
|
5247
|
+
async readHead() {
|
|
5248
|
+
return await strategy.readHead();
|
|
5249
|
+
},
|
|
5250
|
+
async writeHead() {
|
|
5251
|
+
}
|
|
5252
|
+
};
|
|
5253
|
+
}
|
|
5254
|
+
_createBufferedOps() {
|
|
5255
|
+
const strategy = this.strategy;
|
|
5256
|
+
const writeBuffer = /* @__PURE__ */ new Map();
|
|
5257
|
+
const deleteBuffer = /* @__PURE__ */ new Set();
|
|
5258
|
+
let headBuffer = null;
|
|
5259
|
+
const ops = {
|
|
5260
|
+
async getNode(id) {
|
|
5261
|
+
const buffered = writeBuffer.get(id);
|
|
5262
|
+
if (buffered) return buffered;
|
|
5263
|
+
return await strategy.read(id);
|
|
5264
|
+
},
|
|
5265
|
+
async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5266
|
+
const id = await strategy.id(leaf);
|
|
5267
|
+
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5268
|
+
writeBuffer.set(id, node);
|
|
5188
5269
|
return node;
|
|
5189
5270
|
},
|
|
5190
5271
|
async updateNode(node) {
|
|
5191
|
-
|
|
5272
|
+
writeBuffer.set(node.id, node);
|
|
5192
5273
|
},
|
|
5193
5274
|
async deleteNode(node) {
|
|
5194
|
-
|
|
5275
|
+
deleteBuffer.add(node.id);
|
|
5276
|
+
writeBuffer.delete(node.id);
|
|
5195
5277
|
},
|
|
5196
5278
|
async readHead() {
|
|
5279
|
+
if (headBuffer) return headBuffer;
|
|
5197
5280
|
return await strategy.readHead();
|
|
5198
5281
|
},
|
|
5199
5282
|
async writeHead(head) {
|
|
5200
|
-
|
|
5283
|
+
headBuffer = head;
|
|
5201
5284
|
}
|
|
5202
5285
|
};
|
|
5286
|
+
async function flush() {
|
|
5287
|
+
for (const id of deleteBuffer) {
|
|
5288
|
+
await strategy.delete(id);
|
|
5289
|
+
}
|
|
5290
|
+
for (const [id, node] of writeBuffer) {
|
|
5291
|
+
await strategy.write(id, node);
|
|
5292
|
+
}
|
|
5293
|
+
if (headBuffer) {
|
|
5294
|
+
await strategy.writeHead(headBuffer);
|
|
5295
|
+
}
|
|
5296
|
+
}
|
|
5297
|
+
return { ops, flush };
|
|
5298
|
+
}
|
|
5299
|
+
async writeLock(fn) {
|
|
5300
|
+
let lockId;
|
|
5301
|
+
return this.lock.writeLock(async (_lockId) => {
|
|
5302
|
+
lockId = _lockId;
|
|
5303
|
+
return fn();
|
|
5304
|
+
}).finally(() => {
|
|
5305
|
+
this.lock.writeUnlock(lockId);
|
|
5306
|
+
});
|
|
5203
5307
|
}
|
|
5204
5308
|
async init() {
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5309
|
+
return this.writeLock(async () => {
|
|
5310
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5311
|
+
this._ctx = {
|
|
5312
|
+
rootId: "",
|
|
5313
|
+
order: this.strategy.order,
|
|
5314
|
+
headData: () => this.strategy.head.data
|
|
5315
|
+
};
|
|
5316
|
+
await initOpAsync(
|
|
5317
|
+
ops,
|
|
5318
|
+
this._ctx,
|
|
5319
|
+
this.strategy.order,
|
|
5320
|
+
this.strategy.head,
|
|
5321
|
+
(head) => {
|
|
5322
|
+
this.strategy.head = head;
|
|
5323
|
+
}
|
|
5324
|
+
);
|
|
5325
|
+
await flush();
|
|
5326
|
+
this._ops = this._createOps();
|
|
5327
|
+
});
|
|
5220
5328
|
}
|
|
5221
5329
|
getRootId() {
|
|
5222
5330
|
return this._ctx.rootId;
|
|
@@ -5240,28 +5348,40 @@ var BPTreePureAsync = class {
|
|
|
5240
5348
|
return existsOpAsync(this._ops, this._ctx.rootId, key, value, this.comparator);
|
|
5241
5349
|
}
|
|
5242
5350
|
async *keysStream(condition, options) {
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
this.
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5351
|
+
let lockId;
|
|
5352
|
+
try {
|
|
5353
|
+
lockId = await this.lock.readLock([0, 0.1], async (id) => id);
|
|
5354
|
+
yield* keysStreamOpAsync(
|
|
5355
|
+
this._ops,
|
|
5356
|
+
this._ctx.rootId,
|
|
5357
|
+
condition,
|
|
5358
|
+
this.comparator,
|
|
5359
|
+
this._verifierMap,
|
|
5360
|
+
this._searchConfigs,
|
|
5361
|
+
this._ensureValues,
|
|
5362
|
+
options
|
|
5363
|
+
);
|
|
5364
|
+
} finally {
|
|
5365
|
+
if (lockId) this.lock.readUnlock(lockId);
|
|
5366
|
+
}
|
|
5253
5367
|
}
|
|
5254
5368
|
async *whereStream(condition, options) {
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
this.
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5369
|
+
let lockId;
|
|
5370
|
+
try {
|
|
5371
|
+
lockId = await this.lock.readLock([0, 0.1], async (id) => id);
|
|
5372
|
+
yield* whereStreamOpAsync(
|
|
5373
|
+
this._ops,
|
|
5374
|
+
this._ctx.rootId,
|
|
5375
|
+
condition,
|
|
5376
|
+
this.comparator,
|
|
5377
|
+
this._verifierMap,
|
|
5378
|
+
this._searchConfigs,
|
|
5379
|
+
this._ensureValues,
|
|
5380
|
+
options
|
|
5381
|
+
);
|
|
5382
|
+
} finally {
|
|
5383
|
+
if (lockId) this.lock.readUnlock(lockId);
|
|
5384
|
+
}
|
|
5265
5385
|
}
|
|
5266
5386
|
async keys(condition, options) {
|
|
5267
5387
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -5279,16 +5399,32 @@ var BPTreePureAsync = class {
|
|
|
5279
5399
|
}
|
|
5280
5400
|
// ─── Mutation ────────────────────────────────────────────────────
|
|
5281
5401
|
async insert(key, value) {
|
|
5282
|
-
|
|
5402
|
+
return this.writeLock(async () => {
|
|
5403
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5404
|
+
await insertOpAsync(ops, this._ctx, key, value, this.comparator);
|
|
5405
|
+
await flush();
|
|
5406
|
+
});
|
|
5283
5407
|
}
|
|
5284
5408
|
async delete(key, value) {
|
|
5285
|
-
|
|
5409
|
+
return this.writeLock(async () => {
|
|
5410
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5411
|
+
await deleteOpAsync(ops, this._ctx, key, this.comparator, value);
|
|
5412
|
+
await flush();
|
|
5413
|
+
});
|
|
5286
5414
|
}
|
|
5287
5415
|
async batchInsert(entries) {
|
|
5288
|
-
|
|
5416
|
+
return this.writeLock(async () => {
|
|
5417
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5418
|
+
await batchInsertOpAsync(ops, this._ctx, entries, this.comparator);
|
|
5419
|
+
await flush();
|
|
5420
|
+
});
|
|
5289
5421
|
}
|
|
5290
5422
|
async bulkLoad(entries) {
|
|
5291
|
-
|
|
5423
|
+
return this.writeLock(async () => {
|
|
5424
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5425
|
+
await bulkLoadOpAsync(ops, this._ctx, entries, this.comparator);
|
|
5426
|
+
await flush();
|
|
5427
|
+
});
|
|
5292
5428
|
}
|
|
5293
5429
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
5294
5430
|
async getHeadData() {
|
|
@@ -5297,9 +5433,13 @@ var BPTreePureAsync = class {
|
|
|
5297
5433
|
return head.data;
|
|
5298
5434
|
}
|
|
5299
5435
|
async setHeadData(data) {
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5436
|
+
return this.writeLock(async () => {
|
|
5437
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5438
|
+
const head = await ops.readHead();
|
|
5439
|
+
if (head === null) throw new Error("Head not found");
|
|
5440
|
+
await ops.writeHead({ root: head.root, order: head.order, data });
|
|
5441
|
+
await flush();
|
|
5442
|
+
});
|
|
5303
5443
|
}
|
|
5304
5444
|
// ─── Static utilities ────────────────────────────────────────────
|
|
5305
5445
|
static ChooseDriver = BPTreeTransaction.ChooseDriver;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -4976,32 +4976,73 @@ var BPTreePureSync = class {
|
|
|
4976
4976
|
createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
4977
4977
|
const id = strategy.id(leaf);
|
|
4978
4978
|
const node = { id, keys, values, leaf, parent, next, prev };
|
|
4979
|
-
|
|
4979
|
+
return node;
|
|
4980
|
+
},
|
|
4981
|
+
updateNode() {
|
|
4982
|
+
},
|
|
4983
|
+
deleteNode() {
|
|
4984
|
+
},
|
|
4985
|
+
readHead() {
|
|
4986
|
+
return strategy.readHead();
|
|
4987
|
+
},
|
|
4988
|
+
writeHead() {
|
|
4989
|
+
}
|
|
4990
|
+
};
|
|
4991
|
+
}
|
|
4992
|
+
_createBufferedOps() {
|
|
4993
|
+
const strategy = this.strategy;
|
|
4994
|
+
const writeBuffer = /* @__PURE__ */ new Map();
|
|
4995
|
+
const deleteBuffer = /* @__PURE__ */ new Set();
|
|
4996
|
+
let headBuffer = null;
|
|
4997
|
+
const ops = {
|
|
4998
|
+
getNode(id) {
|
|
4999
|
+
const buffered = writeBuffer.get(id);
|
|
5000
|
+
if (buffered) return buffered;
|
|
5001
|
+
return strategy.read(id);
|
|
5002
|
+
},
|
|
5003
|
+
createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5004
|
+
const id = strategy.id(leaf);
|
|
5005
|
+
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5006
|
+
writeBuffer.set(id, node);
|
|
4980
5007
|
return node;
|
|
4981
5008
|
},
|
|
4982
5009
|
updateNode(node) {
|
|
4983
|
-
|
|
5010
|
+
writeBuffer.set(node.id, node);
|
|
4984
5011
|
},
|
|
4985
5012
|
deleteNode(node) {
|
|
4986
|
-
|
|
5013
|
+
deleteBuffer.add(node.id);
|
|
5014
|
+
writeBuffer.delete(node.id);
|
|
4987
5015
|
},
|
|
4988
5016
|
readHead() {
|
|
5017
|
+
if (headBuffer) return headBuffer;
|
|
4989
5018
|
return strategy.readHead();
|
|
4990
5019
|
},
|
|
4991
5020
|
writeHead(head) {
|
|
4992
|
-
|
|
5021
|
+
headBuffer = head;
|
|
4993
5022
|
}
|
|
4994
5023
|
};
|
|
5024
|
+
function flush() {
|
|
5025
|
+
for (const id of deleteBuffer) {
|
|
5026
|
+
strategy.delete(id);
|
|
5027
|
+
}
|
|
5028
|
+
for (const [id, node] of writeBuffer) {
|
|
5029
|
+
strategy.write(id, node);
|
|
5030
|
+
}
|
|
5031
|
+
if (headBuffer) {
|
|
5032
|
+
strategy.writeHead(headBuffer);
|
|
5033
|
+
}
|
|
5034
|
+
}
|
|
5035
|
+
return { ops, flush };
|
|
4995
5036
|
}
|
|
4996
5037
|
init() {
|
|
4997
|
-
|
|
5038
|
+
const { ops, flush } = this._createBufferedOps();
|
|
4998
5039
|
this._ctx = {
|
|
4999
5040
|
rootId: "",
|
|
5000
5041
|
order: this.strategy.order,
|
|
5001
5042
|
headData: () => this.strategy.head.data
|
|
5002
5043
|
};
|
|
5003
5044
|
initOp(
|
|
5004
|
-
|
|
5045
|
+
ops,
|
|
5005
5046
|
this._ctx,
|
|
5006
5047
|
this.strategy.order,
|
|
5007
5048
|
this.strategy.head,
|
|
@@ -5009,6 +5050,8 @@ var BPTreePureSync = class {
|
|
|
5009
5050
|
this.strategy.head = head;
|
|
5010
5051
|
}
|
|
5011
5052
|
);
|
|
5053
|
+
flush();
|
|
5054
|
+
this._ops = this._createOps();
|
|
5012
5055
|
}
|
|
5013
5056
|
/**
|
|
5014
5057
|
* Returns the ID of the root node.
|
|
@@ -5082,16 +5125,24 @@ var BPTreePureSync = class {
|
|
|
5082
5125
|
}
|
|
5083
5126
|
// ─── Mutation ────────────────────────────────────────────────────
|
|
5084
5127
|
insert(key, value) {
|
|
5085
|
-
|
|
5128
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5129
|
+
insertOp(ops, this._ctx, key, value, this.comparator);
|
|
5130
|
+
flush();
|
|
5086
5131
|
}
|
|
5087
5132
|
delete(key, value) {
|
|
5088
|
-
|
|
5133
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5134
|
+
deleteOp(ops, this._ctx, key, this.comparator, value);
|
|
5135
|
+
flush();
|
|
5089
5136
|
}
|
|
5090
5137
|
batchInsert(entries) {
|
|
5091
|
-
|
|
5138
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5139
|
+
batchInsertOp(ops, this._ctx, entries, this.comparator);
|
|
5140
|
+
flush();
|
|
5092
5141
|
}
|
|
5093
5142
|
bulkLoad(entries) {
|
|
5094
|
-
|
|
5143
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5144
|
+
bulkLoadOp(ops, this._ctx, entries, this.comparator);
|
|
5145
|
+
flush();
|
|
5095
5146
|
}
|
|
5096
5147
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
5097
5148
|
getHeadData() {
|
|
@@ -5102,15 +5153,17 @@ var BPTreePureSync = class {
|
|
|
5102
5153
|
return head.data;
|
|
5103
5154
|
}
|
|
5104
5155
|
setHeadData(data) {
|
|
5105
|
-
const
|
|
5156
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5157
|
+
const head = ops.readHead();
|
|
5106
5158
|
if (head === null) {
|
|
5107
5159
|
throw new Error("Head not found");
|
|
5108
5160
|
}
|
|
5109
|
-
|
|
5161
|
+
ops.writeHead({
|
|
5110
5162
|
root: head.root,
|
|
5111
5163
|
order: head.order,
|
|
5112
5164
|
data
|
|
5113
5165
|
});
|
|
5166
|
+
flush();
|
|
5114
5167
|
}
|
|
5115
5168
|
// ─── Static utilities ────────────────────────────────────────────
|
|
5116
5169
|
static ChooseDriver = BPTreeTransaction.ChooseDriver;
|
|
@@ -5121,6 +5174,7 @@ var BPTreePureAsync = class {
|
|
|
5121
5174
|
strategy;
|
|
5122
5175
|
comparator;
|
|
5123
5176
|
option;
|
|
5177
|
+
lock = new Ryoiki2();
|
|
5124
5178
|
_cachedRegexp = /* @__PURE__ */ new Map();
|
|
5125
5179
|
_ctx;
|
|
5126
5180
|
_ops;
|
|
@@ -5146,39 +5200,93 @@ var BPTreePureAsync = class {
|
|
|
5146
5200
|
async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5147
5201
|
const id = await strategy.id(leaf);
|
|
5148
5202
|
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5149
|
-
|
|
5203
|
+
return node;
|
|
5204
|
+
},
|
|
5205
|
+
async updateNode() {
|
|
5206
|
+
},
|
|
5207
|
+
async deleteNode() {
|
|
5208
|
+
},
|
|
5209
|
+
async readHead() {
|
|
5210
|
+
return await strategy.readHead();
|
|
5211
|
+
},
|
|
5212
|
+
async writeHead() {
|
|
5213
|
+
}
|
|
5214
|
+
};
|
|
5215
|
+
}
|
|
5216
|
+
_createBufferedOps() {
|
|
5217
|
+
const strategy = this.strategy;
|
|
5218
|
+
const writeBuffer = /* @__PURE__ */ new Map();
|
|
5219
|
+
const deleteBuffer = /* @__PURE__ */ new Set();
|
|
5220
|
+
let headBuffer = null;
|
|
5221
|
+
const ops = {
|
|
5222
|
+
async getNode(id) {
|
|
5223
|
+
const buffered = writeBuffer.get(id);
|
|
5224
|
+
if (buffered) return buffered;
|
|
5225
|
+
return await strategy.read(id);
|
|
5226
|
+
},
|
|
5227
|
+
async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5228
|
+
const id = await strategy.id(leaf);
|
|
5229
|
+
const node = { id, keys, values, leaf, parent, next, prev };
|
|
5230
|
+
writeBuffer.set(id, node);
|
|
5150
5231
|
return node;
|
|
5151
5232
|
},
|
|
5152
5233
|
async updateNode(node) {
|
|
5153
|
-
|
|
5234
|
+
writeBuffer.set(node.id, node);
|
|
5154
5235
|
},
|
|
5155
5236
|
async deleteNode(node) {
|
|
5156
|
-
|
|
5237
|
+
deleteBuffer.add(node.id);
|
|
5238
|
+
writeBuffer.delete(node.id);
|
|
5157
5239
|
},
|
|
5158
5240
|
async readHead() {
|
|
5241
|
+
if (headBuffer) return headBuffer;
|
|
5159
5242
|
return await strategy.readHead();
|
|
5160
5243
|
},
|
|
5161
5244
|
async writeHead(head) {
|
|
5162
|
-
|
|
5245
|
+
headBuffer = head;
|
|
5163
5246
|
}
|
|
5164
5247
|
};
|
|
5248
|
+
async function flush() {
|
|
5249
|
+
for (const id of deleteBuffer) {
|
|
5250
|
+
await strategy.delete(id);
|
|
5251
|
+
}
|
|
5252
|
+
for (const [id, node] of writeBuffer) {
|
|
5253
|
+
await strategy.write(id, node);
|
|
5254
|
+
}
|
|
5255
|
+
if (headBuffer) {
|
|
5256
|
+
await strategy.writeHead(headBuffer);
|
|
5257
|
+
}
|
|
5258
|
+
}
|
|
5259
|
+
return { ops, flush };
|
|
5260
|
+
}
|
|
5261
|
+
async writeLock(fn) {
|
|
5262
|
+
let lockId;
|
|
5263
|
+
return this.lock.writeLock(async (_lockId) => {
|
|
5264
|
+
lockId = _lockId;
|
|
5265
|
+
return fn();
|
|
5266
|
+
}).finally(() => {
|
|
5267
|
+
this.lock.writeUnlock(lockId);
|
|
5268
|
+
});
|
|
5165
5269
|
}
|
|
5166
5270
|
async init() {
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5271
|
+
return this.writeLock(async () => {
|
|
5272
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5273
|
+
this._ctx = {
|
|
5274
|
+
rootId: "",
|
|
5275
|
+
order: this.strategy.order,
|
|
5276
|
+
headData: () => this.strategy.head.data
|
|
5277
|
+
};
|
|
5278
|
+
await initOpAsync(
|
|
5279
|
+
ops,
|
|
5280
|
+
this._ctx,
|
|
5281
|
+
this.strategy.order,
|
|
5282
|
+
this.strategy.head,
|
|
5283
|
+
(head) => {
|
|
5284
|
+
this.strategy.head = head;
|
|
5285
|
+
}
|
|
5286
|
+
);
|
|
5287
|
+
await flush();
|
|
5288
|
+
this._ops = this._createOps();
|
|
5289
|
+
});
|
|
5182
5290
|
}
|
|
5183
5291
|
getRootId() {
|
|
5184
5292
|
return this._ctx.rootId;
|
|
@@ -5202,28 +5310,40 @@ var BPTreePureAsync = class {
|
|
|
5202
5310
|
return existsOpAsync(this._ops, this._ctx.rootId, key, value, this.comparator);
|
|
5203
5311
|
}
|
|
5204
5312
|
async *keysStream(condition, options) {
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
this.
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5313
|
+
let lockId;
|
|
5314
|
+
try {
|
|
5315
|
+
lockId = await this.lock.readLock([0, 0.1], async (id) => id);
|
|
5316
|
+
yield* keysStreamOpAsync(
|
|
5317
|
+
this._ops,
|
|
5318
|
+
this._ctx.rootId,
|
|
5319
|
+
condition,
|
|
5320
|
+
this.comparator,
|
|
5321
|
+
this._verifierMap,
|
|
5322
|
+
this._searchConfigs,
|
|
5323
|
+
this._ensureValues,
|
|
5324
|
+
options
|
|
5325
|
+
);
|
|
5326
|
+
} finally {
|
|
5327
|
+
if (lockId) this.lock.readUnlock(lockId);
|
|
5328
|
+
}
|
|
5215
5329
|
}
|
|
5216
5330
|
async *whereStream(condition, options) {
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
this.
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5331
|
+
let lockId;
|
|
5332
|
+
try {
|
|
5333
|
+
lockId = await this.lock.readLock([0, 0.1], async (id) => id);
|
|
5334
|
+
yield* whereStreamOpAsync(
|
|
5335
|
+
this._ops,
|
|
5336
|
+
this._ctx.rootId,
|
|
5337
|
+
condition,
|
|
5338
|
+
this.comparator,
|
|
5339
|
+
this._verifierMap,
|
|
5340
|
+
this._searchConfigs,
|
|
5341
|
+
this._ensureValues,
|
|
5342
|
+
options
|
|
5343
|
+
);
|
|
5344
|
+
} finally {
|
|
5345
|
+
if (lockId) this.lock.readUnlock(lockId);
|
|
5346
|
+
}
|
|
5227
5347
|
}
|
|
5228
5348
|
async keys(condition, options) {
|
|
5229
5349
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -5241,16 +5361,32 @@ var BPTreePureAsync = class {
|
|
|
5241
5361
|
}
|
|
5242
5362
|
// ─── Mutation ────────────────────────────────────────────────────
|
|
5243
5363
|
async insert(key, value) {
|
|
5244
|
-
|
|
5364
|
+
return this.writeLock(async () => {
|
|
5365
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5366
|
+
await insertOpAsync(ops, this._ctx, key, value, this.comparator);
|
|
5367
|
+
await flush();
|
|
5368
|
+
});
|
|
5245
5369
|
}
|
|
5246
5370
|
async delete(key, value) {
|
|
5247
|
-
|
|
5371
|
+
return this.writeLock(async () => {
|
|
5372
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5373
|
+
await deleteOpAsync(ops, this._ctx, key, this.comparator, value);
|
|
5374
|
+
await flush();
|
|
5375
|
+
});
|
|
5248
5376
|
}
|
|
5249
5377
|
async batchInsert(entries) {
|
|
5250
|
-
|
|
5378
|
+
return this.writeLock(async () => {
|
|
5379
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5380
|
+
await batchInsertOpAsync(ops, this._ctx, entries, this.comparator);
|
|
5381
|
+
await flush();
|
|
5382
|
+
});
|
|
5251
5383
|
}
|
|
5252
5384
|
async bulkLoad(entries) {
|
|
5253
|
-
|
|
5385
|
+
return this.writeLock(async () => {
|
|
5386
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5387
|
+
await bulkLoadOpAsync(ops, this._ctx, entries, this.comparator);
|
|
5388
|
+
await flush();
|
|
5389
|
+
});
|
|
5254
5390
|
}
|
|
5255
5391
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
5256
5392
|
async getHeadData() {
|
|
@@ -5259,9 +5395,13 @@ var BPTreePureAsync = class {
|
|
|
5259
5395
|
return head.data;
|
|
5260
5396
|
}
|
|
5261
5397
|
async setHeadData(data) {
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5398
|
+
return this.writeLock(async () => {
|
|
5399
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5400
|
+
const head = await ops.readHead();
|
|
5401
|
+
if (head === null) throw new Error("Head not found");
|
|
5402
|
+
await ops.writeHead({ root: head.root, order: head.order, data });
|
|
5403
|
+
await flush();
|
|
5404
|
+
});
|
|
5265
5405
|
}
|
|
5266
5406
|
// ─── Static utilities ────────────────────────────────────────────
|
|
5267
5407
|
static ChooseDriver = BPTreeTransaction.ChooseDriver;
|
|
@@ -2,10 +2,12 @@ import type { BPTreeCondition, BPTreeConstructorOption, BPTreePair, BPTreeSearch
|
|
|
2
2
|
import { SerializeStrategyAsync } from './SerializeStrategyAsync';
|
|
3
3
|
import { ValueComparator } from './base/ValueComparator';
|
|
4
4
|
import { BPTreeTransaction } from './base/BPTreeTransaction';
|
|
5
|
+
import { Ryoiki } from 'ryoiki';
|
|
5
6
|
export declare class BPTreePureAsync<K, V> {
|
|
6
7
|
protected readonly strategy: SerializeStrategyAsync<K, V>;
|
|
7
8
|
protected readonly comparator: ValueComparator<V>;
|
|
8
9
|
protected readonly option: BPTreeConstructorOption;
|
|
10
|
+
protected readonly lock: Ryoiki;
|
|
9
11
|
private readonly _cachedRegexp;
|
|
10
12
|
private _ctx;
|
|
11
13
|
private _ops;
|
|
@@ -14,6 +16,8 @@ export declare class BPTreePureAsync<K, V> {
|
|
|
14
16
|
constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
|
|
15
17
|
private _ensureValues;
|
|
16
18
|
private _createOps;
|
|
19
|
+
private _createBufferedOps;
|
|
20
|
+
protected writeLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
17
21
|
init(): Promise<void>;
|
|
18
22
|
getRootId(): string;
|
|
19
23
|
getOrder(): number;
|
|
@@ -14,6 +14,7 @@ export declare class BPTreePureSync<K, V> {
|
|
|
14
14
|
constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
|
|
15
15
|
private _ensureValues;
|
|
16
16
|
private _createOps;
|
|
17
|
+
private _createBufferedOps;
|
|
17
18
|
init(): void;
|
|
18
19
|
/**
|
|
19
20
|
* Returns the ID of the root node.
|