dataply 0.0.26-alpha.8 → 0.0.26
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.js +401 -201
- package/dist/types/core/Dataply.d.ts +7 -7
- package/dist/types/core/DataplyAPI.d.ts +8 -0
- package/dist/types/core/PageFileSystem.d.ts +8 -4
- package/dist/types/core/RowTableEngine.d.ts +7 -0
- package/dist/types/core/transaction/Transaction.d.ts +2 -1
- package/package.json +2 -2
package/dist/cjs/index.js
CHANGED
|
@@ -2191,13 +2191,7 @@ function insertOp(ops, ctx, key, value, comparator) {
|
|
|
2191
2191
|
}
|
|
2192
2192
|
function deleteEntry(ops, ctx, node, key, comparator) {
|
|
2193
2193
|
if (!node.leaf) {
|
|
2194
|
-
let keyIndex =
|
|
2195
|
-
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
2196
|
-
if (node.keys[i] === key) {
|
|
2197
|
-
keyIndex = i;
|
|
2198
|
-
break;
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2194
|
+
let keyIndex = node.keys.indexOf(key);
|
|
2201
2195
|
if (keyIndex !== -1) {
|
|
2202
2196
|
node = cloneNode(node);
|
|
2203
2197
|
node.keys.splice(keyIndex, 1);
|
|
@@ -2236,17 +2230,15 @@ function deleteEntry(ops, ctx, node, key, comparator) {
|
|
|
2236
2230
|
let nextNode = null;
|
|
2237
2231
|
let prevValue = null;
|
|
2238
2232
|
let postValue = null;
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
if (
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
postValue = parentNode.values[i];
|
|
2249
|
-
}
|
|
2233
|
+
let keyIndex = parentNode.keys.indexOf(node.id);
|
|
2234
|
+
if (keyIndex !== -1) {
|
|
2235
|
+
if (keyIndex > 0) {
|
|
2236
|
+
prevNode = ops.getNode(parentNode.keys[keyIndex - 1]);
|
|
2237
|
+
prevValue = parentNode.values[keyIndex - 1];
|
|
2238
|
+
}
|
|
2239
|
+
if (keyIndex < parentNode.keys.length - 1) {
|
|
2240
|
+
nextNode = ops.getNode(parentNode.keys[keyIndex + 1]);
|
|
2241
|
+
postValue = parentNode.values[keyIndex];
|
|
2250
2242
|
}
|
|
2251
2243
|
}
|
|
2252
2244
|
let siblingNode;
|
|
@@ -2279,7 +2271,7 @@ function deleteEntry(ops, ctx, node, key, comparator) {
|
|
|
2279
2271
|
siblingNode = node;
|
|
2280
2272
|
node = pTemp;
|
|
2281
2273
|
}
|
|
2282
|
-
siblingNode.keys.
|
|
2274
|
+
siblingNode.keys = siblingNode.keys.concat(node.keys);
|
|
2283
2275
|
if (!node.leaf) {
|
|
2284
2276
|
siblingNode.values.push(guess);
|
|
2285
2277
|
} else {
|
|
@@ -2290,7 +2282,7 @@ function deleteEntry(ops, ctx, node, key, comparator) {
|
|
|
2290
2282
|
ops.updateNode(n);
|
|
2291
2283
|
}
|
|
2292
2284
|
}
|
|
2293
|
-
siblingNode.values.
|
|
2285
|
+
siblingNode.values = siblingNode.values.concat(node.values);
|
|
2294
2286
|
if (!siblingNode.leaf) {
|
|
2295
2287
|
const keys = siblingNode.keys;
|
|
2296
2288
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
@@ -2338,8 +2330,8 @@ function deleteEntry(ops, ctx, node, key, comparator) {
|
|
|
2338
2330
|
if (!node.leaf) {
|
|
2339
2331
|
pointerP0 = siblingNode.keys.splice(0, 1)[0];
|
|
2340
2332
|
pointerK0 = siblingNode.values.splice(0, 1)[0];
|
|
2341
|
-
node.keys =
|
|
2342
|
-
node.values =
|
|
2333
|
+
node.keys = node.keys.concat(pointerP0);
|
|
2334
|
+
node.values = node.values.concat(guess);
|
|
2343
2335
|
parentNode = cloneNode(ops.getNode(node.parent));
|
|
2344
2336
|
const pointerIndex = parentNode.keys.indexOf(siblingNode.id);
|
|
2345
2337
|
if (pointerIndex > 0) {
|
|
@@ -2430,6 +2422,13 @@ function deleteOp(ops, ctx, key, comparator, value) {
|
|
|
2430
2422
|
break;
|
|
2431
2423
|
}
|
|
2432
2424
|
}
|
|
2425
|
+
function batchDeleteOp(ops, ctx, entries, comparator) {
|
|
2426
|
+
if (entries.length === 0) return;
|
|
2427
|
+
for (let i = 0, len = entries.length; i < len; i++) {
|
|
2428
|
+
const [key, value] = entries[i];
|
|
2429
|
+
deleteOp(ops, ctx, key, comparator, value);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2433
2432
|
function batchInsertOp(ops, ctx, entries, comparator) {
|
|
2434
2433
|
if (entries.length === 0) return;
|
|
2435
2434
|
const sorted = [...entries].sort((a, b) => comparator.asc(a[1], b[1]));
|
|
@@ -2985,27 +2984,12 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
2985
2984
|
static CheckConflicts(transactions) {
|
|
2986
2985
|
return MVCCTransaction.CheckConflicts(transactions.map((tx) => tx.mvcc));
|
|
2987
2986
|
}
|
|
2988
|
-
/**
|
|
2989
|
-
* Returns the ID of the root node.
|
|
2990
|
-
* @returns The root node ID.
|
|
2991
|
-
*/
|
|
2992
2987
|
getRootId() {
|
|
2993
2988
|
return this.rootId;
|
|
2994
2989
|
}
|
|
2995
|
-
/**
|
|
2996
|
-
* Returns the order of the B+Tree.
|
|
2997
|
-
* @returns The order of the tree.
|
|
2998
|
-
*/
|
|
2999
2990
|
getOrder() {
|
|
3000
2991
|
return this.order;
|
|
3001
2992
|
}
|
|
3002
|
-
/**
|
|
3003
|
-
* Verified if the value satisfies the condition.
|
|
3004
|
-
*
|
|
3005
|
-
* @param nodeValue The value to verify.
|
|
3006
|
-
* @param condition The condition to verify against.
|
|
3007
|
-
* @returns Returns true if the value satisfies the condition.
|
|
3008
|
-
*/
|
|
3009
2993
|
verify(nodeValue, condition) {
|
|
3010
2994
|
for (const key in condition) {
|
|
3011
2995
|
const verify2 = this.verifierMap[key];
|
|
@@ -3264,6 +3248,9 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
3264
3248
|
this._verifierMapCached = createVerifierMap(this.comparator, this._cachedRegexp, ensureValues);
|
|
3265
3249
|
this._searchConfigsCached = createSearchConfigs(this.comparator, ensureValues);
|
|
3266
3250
|
}
|
|
3251
|
+
getRootNode() {
|
|
3252
|
+
return this.getNode(this.rootId);
|
|
3253
|
+
}
|
|
3267
3254
|
// ─── Legacy protected methods (delegating to ops) ────────────────
|
|
3268
3255
|
getNode(id) {
|
|
3269
3256
|
return this._ops.getNode(id);
|
|
@@ -3413,6 +3400,9 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
3413
3400
|
delete(key, value) {
|
|
3414
3401
|
deleteOp(this._ops, this._ctx, key, this.comparator, value);
|
|
3415
3402
|
}
|
|
3403
|
+
batchDelete(entries) {
|
|
3404
|
+
batchDeleteOp(this._ops, this._ctx, entries, this.comparator);
|
|
3405
|
+
}
|
|
3416
3406
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
3417
3407
|
getHeadData() {
|
|
3418
3408
|
const head = this._readHead();
|
|
@@ -3534,6 +3524,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
|
|
|
3534
3524
|
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
3535
3525
|
}
|
|
3536
3526
|
}
|
|
3527
|
+
batchDelete(entries) {
|
|
3528
|
+
const tx = this.createTransaction();
|
|
3529
|
+
tx.batchDelete(entries);
|
|
3530
|
+
const result = tx.commit();
|
|
3531
|
+
if (!result.success) {
|
|
3532
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3537
3535
|
batchInsert(entries) {
|
|
3538
3536
|
const tx = this.createTransaction();
|
|
3539
3537
|
tx.batchInsert(entries);
|
|
@@ -4218,13 +4216,7 @@ async function insertOpAsync(ops, ctx, key, value, comparator) {
|
|
|
4218
4216
|
}
|
|
4219
4217
|
async function deleteEntryAsync(ops, ctx, node, key, comparator) {
|
|
4220
4218
|
if (!node.leaf) {
|
|
4221
|
-
let keyIndex =
|
|
4222
|
-
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
4223
|
-
if (node.keys[i] === key) {
|
|
4224
|
-
keyIndex = i;
|
|
4225
|
-
break;
|
|
4226
|
-
}
|
|
4227
|
-
}
|
|
4219
|
+
let keyIndex = node.keys.indexOf(key);
|
|
4228
4220
|
if (keyIndex !== -1) {
|
|
4229
4221
|
node = cloneNode(node);
|
|
4230
4222
|
node.keys.splice(keyIndex, 1);
|
|
@@ -4253,16 +4245,15 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
|
|
|
4253
4245
|
let nextNode = null;
|
|
4254
4246
|
let prevValue = null;
|
|
4255
4247
|
let postValue = null;
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
}
|
|
4248
|
+
let keyIndex = parentNode.keys.indexOf(node.id);
|
|
4249
|
+
if (keyIndex !== -1) {
|
|
4250
|
+
if (keyIndex > 0) {
|
|
4251
|
+
prevNode = await ops.getNode(parentNode.keys[keyIndex - 1]);
|
|
4252
|
+
prevValue = parentNode.values[keyIndex - 1];
|
|
4253
|
+
}
|
|
4254
|
+
if (keyIndex < parentNode.keys.length - 1) {
|
|
4255
|
+
nextNode = await ops.getNode(parentNode.keys[keyIndex + 1]);
|
|
4256
|
+
postValue = parentNode.values[keyIndex];
|
|
4266
4257
|
}
|
|
4267
4258
|
}
|
|
4268
4259
|
let siblingNode;
|
|
@@ -4289,11 +4280,11 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
|
|
|
4289
4280
|
siblingNode = cloneNode(siblingNode);
|
|
4290
4281
|
if (node.values.length + siblingNode.values.length < ctx.order) {
|
|
4291
4282
|
if (!isPredecessor) {
|
|
4292
|
-
const
|
|
4283
|
+
const pTemp = siblingNode;
|
|
4293
4284
|
siblingNode = node;
|
|
4294
|
-
node =
|
|
4285
|
+
node = pTemp;
|
|
4295
4286
|
}
|
|
4296
|
-
siblingNode.keys.
|
|
4287
|
+
siblingNode.keys = siblingNode.keys.concat(node.keys);
|
|
4297
4288
|
if (!node.leaf) {
|
|
4298
4289
|
siblingNode.values.push(guess);
|
|
4299
4290
|
} else {
|
|
@@ -4304,7 +4295,7 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
|
|
|
4304
4295
|
await ops.updateNode(n);
|
|
4305
4296
|
}
|
|
4306
4297
|
}
|
|
4307
|
-
siblingNode.values.
|
|
4298
|
+
siblingNode.values = siblingNode.values.concat(node.values);
|
|
4308
4299
|
if (!siblingNode.leaf) {
|
|
4309
4300
|
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
4310
4301
|
const n = cloneNode(await ops.getNode(siblingNode.keys[i]));
|
|
@@ -4348,8 +4339,8 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
|
|
|
4348
4339
|
if (!node.leaf) {
|
|
4349
4340
|
pointerP0 = siblingNode.keys.splice(0, 1)[0];
|
|
4350
4341
|
pointerK0 = siblingNode.values.splice(0, 1)[0];
|
|
4351
|
-
node.keys =
|
|
4352
|
-
node.values =
|
|
4342
|
+
node.keys = node.keys.concat(pointerP0);
|
|
4343
|
+
node.values = node.values.concat(guess);
|
|
4353
4344
|
parentNode = cloneNode(await ops.getNode(node.parent));
|
|
4354
4345
|
const pi = parentNode.keys.indexOf(siblingNode.id);
|
|
4355
4346
|
if (pi > 0) {
|
|
@@ -4432,6 +4423,13 @@ async function deleteOpAsync(ops, ctx, key, comparator, value) {
|
|
|
4432
4423
|
break;
|
|
4433
4424
|
}
|
|
4434
4425
|
}
|
|
4426
|
+
async function batchDeleteOpAsync(ops, ctx, entries, comparator) {
|
|
4427
|
+
if (entries.length === 0) return;
|
|
4428
|
+
for (let i = 0, len = entries.length; i < len; i++) {
|
|
4429
|
+
const [key, value] = entries[i];
|
|
4430
|
+
await deleteOpAsync(ops, ctx, key, comparator, value);
|
|
4431
|
+
}
|
|
4432
|
+
}
|
|
4435
4433
|
async function batchInsertOpAsync(ops, ctx, entries, comparator) {
|
|
4436
4434
|
if (entries.length === 0) return;
|
|
4437
4435
|
const sorted = [...entries].sort((a, b) => comparator.asc(a[1], b[1]));
|
|
@@ -4692,6 +4690,9 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
4692
4690
|
this.lock.writeUnlock(lockId);
|
|
4693
4691
|
});
|
|
4694
4692
|
}
|
|
4693
|
+
async getRootNode() {
|
|
4694
|
+
return this.getNode(this.rootId);
|
|
4695
|
+
}
|
|
4695
4696
|
// ─── Legacy protected methods (delegating to ops) ────────────────
|
|
4696
4697
|
async getNode(id) {
|
|
4697
4698
|
return this._ops.getNode(id);
|
|
@@ -4851,6 +4852,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
4851
4852
|
await deleteOpAsync(this._ops, this._ctx, key, this.comparator, value);
|
|
4852
4853
|
});
|
|
4853
4854
|
}
|
|
4855
|
+
async batchDelete(entries) {
|
|
4856
|
+
if (entries.length === 0) return;
|
|
4857
|
+
return this.writeLock(0, async () => {
|
|
4858
|
+
await batchDeleteOpAsync(this._ops, this._ctx, entries, this.comparator);
|
|
4859
|
+
});
|
|
4860
|
+
}
|
|
4854
4861
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
4855
4862
|
async getHeadData() {
|
|
4856
4863
|
const head = await this._readHead();
|
|
@@ -4976,6 +4983,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
|
|
|
4976
4983
|
}
|
|
4977
4984
|
});
|
|
4978
4985
|
}
|
|
4986
|
+
async batchDelete(entries) {
|
|
4987
|
+
return this.writeLock(1, async () => {
|
|
4988
|
+
const tx = await this.createTransaction();
|
|
4989
|
+
await tx.batchDelete(entries);
|
|
4990
|
+
const result = await tx.commit();
|
|
4991
|
+
if (!result.success) {
|
|
4992
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
4993
|
+
}
|
|
4994
|
+
});
|
|
4995
|
+
}
|
|
4979
4996
|
async batchInsert(entries) {
|
|
4980
4997
|
return this.writeLock(1, async () => {
|
|
4981
4998
|
const tx = await this.createTransaction();
|
|
@@ -5002,8 +5019,6 @@ var BPTreePureSync = class {
|
|
|
5002
5019
|
comparator;
|
|
5003
5020
|
option;
|
|
5004
5021
|
_cachedRegexp = /* @__PURE__ */ new Map();
|
|
5005
|
-
_ctx;
|
|
5006
|
-
_ops;
|
|
5007
5022
|
_verifierMap;
|
|
5008
5023
|
_searchConfigs;
|
|
5009
5024
|
constructor(strategy, comparator, option) {
|
|
@@ -5017,11 +5032,16 @@ var BPTreePureSync = class {
|
|
|
5017
5032
|
_ensureValues(v) {
|
|
5018
5033
|
return Array.isArray(v) ? v : [v];
|
|
5019
5034
|
}
|
|
5020
|
-
|
|
5035
|
+
_createReadOps() {
|
|
5021
5036
|
const strategy = this.strategy;
|
|
5037
|
+
const readBuffer = /* @__PURE__ */ new Map();
|
|
5022
5038
|
return {
|
|
5023
5039
|
getNode(id) {
|
|
5024
|
-
|
|
5040
|
+
const buffered = readBuffer.get(id);
|
|
5041
|
+
if (buffered) return buffered;
|
|
5042
|
+
const node = strategy.read(id);
|
|
5043
|
+
readBuffer.set(id, node);
|
|
5044
|
+
return node;
|
|
5025
5045
|
},
|
|
5026
5046
|
createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5027
5047
|
const id = strategy.id(leaf);
|
|
@@ -5041,6 +5061,7 @@ var BPTreePureSync = class {
|
|
|
5041
5061
|
}
|
|
5042
5062
|
_createBufferedOps() {
|
|
5043
5063
|
const strategy = this.strategy;
|
|
5064
|
+
const readBuffer = /* @__PURE__ */ new Map();
|
|
5044
5065
|
const writeBuffer = /* @__PURE__ */ new Map();
|
|
5045
5066
|
const deleteBuffer = /* @__PURE__ */ new Set();
|
|
5046
5067
|
let headBuffer = null;
|
|
@@ -5048,7 +5069,11 @@ var BPTreePureSync = class {
|
|
|
5048
5069
|
getNode(id) {
|
|
5049
5070
|
const buffered = writeBuffer.get(id);
|
|
5050
5071
|
if (buffered) return buffered;
|
|
5051
|
-
|
|
5072
|
+
const read = readBuffer.get(id);
|
|
5073
|
+
if (read) return read;
|
|
5074
|
+
const node = strategy.read(id);
|
|
5075
|
+
readBuffer.set(id, node);
|
|
5076
|
+
return node;
|
|
5052
5077
|
},
|
|
5053
5078
|
createNode(leaf, keys, values, parent = null, next = null, prev = null) {
|
|
5054
5079
|
const id = strategy.id(leaf);
|
|
@@ -5073,6 +5098,7 @@ var BPTreePureSync = class {
|
|
|
5073
5098
|
};
|
|
5074
5099
|
function flush() {
|
|
5075
5100
|
for (const id of deleteBuffer) {
|
|
5101
|
+
writeBuffer.delete(id);
|
|
5076
5102
|
strategy.delete(id);
|
|
5077
5103
|
}
|
|
5078
5104
|
for (const [id, node] of writeBuffer) {
|
|
@@ -5081,19 +5107,42 @@ var BPTreePureSync = class {
|
|
|
5081
5107
|
if (headBuffer) {
|
|
5082
5108
|
strategy.writeHead(headBuffer);
|
|
5083
5109
|
}
|
|
5110
|
+
readBuffer.clear();
|
|
5111
|
+
writeBuffer.clear();
|
|
5112
|
+
deleteBuffer.clear();
|
|
5113
|
+
headBuffer = null;
|
|
5084
5114
|
}
|
|
5085
5115
|
return { ops, flush };
|
|
5086
5116
|
}
|
|
5117
|
+
_readCtx() {
|
|
5118
|
+
const head = this.strategy.readHead();
|
|
5119
|
+
if (head === null) {
|
|
5120
|
+
throw new Error("Tree not initialized. Call init() first.");
|
|
5121
|
+
}
|
|
5122
|
+
return { rootId: head.root, order: head.order };
|
|
5123
|
+
}
|
|
5124
|
+
_createCtx() {
|
|
5125
|
+
const strategy = this.strategy;
|
|
5126
|
+
const head = strategy.readHead();
|
|
5127
|
+
if (head === null) {
|
|
5128
|
+
throw new Error("Tree not initialized. Call init() first.");
|
|
5129
|
+
}
|
|
5130
|
+
return {
|
|
5131
|
+
rootId: head.root,
|
|
5132
|
+
order: head.order,
|
|
5133
|
+
headData: () => strategy.head.data
|
|
5134
|
+
};
|
|
5135
|
+
}
|
|
5087
5136
|
init() {
|
|
5088
5137
|
const { ops, flush } = this._createBufferedOps();
|
|
5089
|
-
|
|
5138
|
+
const ctx = {
|
|
5090
5139
|
rootId: "",
|
|
5091
5140
|
order: this.strategy.order,
|
|
5092
5141
|
headData: () => this.strategy.head.data
|
|
5093
5142
|
};
|
|
5094
5143
|
initOp(
|
|
5095
5144
|
ops,
|
|
5096
|
-
|
|
5145
|
+
ctx,
|
|
5097
5146
|
this.strategy.order,
|
|
5098
5147
|
this.strategy.head,
|
|
5099
5148
|
(head) => {
|
|
@@ -5101,23 +5150,19 @@ var BPTreePureSync = class {
|
|
|
5101
5150
|
}
|
|
5102
5151
|
);
|
|
5103
5152
|
flush();
|
|
5104
|
-
this._ops = this._createOps();
|
|
5105
5153
|
}
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5154
|
+
getRootNode() {
|
|
5155
|
+
const ctx = this._readCtx();
|
|
5156
|
+
return this.strategy.read(ctx.rootId);
|
|
5157
|
+
}
|
|
5109
5158
|
getRootId() {
|
|
5110
|
-
|
|
5159
|
+
const ctx = this._readCtx();
|
|
5160
|
+
return ctx.rootId;
|
|
5111
5161
|
}
|
|
5112
|
-
/**
|
|
5113
|
-
* Returns the order of the B+Tree.
|
|
5114
|
-
*/
|
|
5115
5162
|
getOrder() {
|
|
5116
|
-
|
|
5163
|
+
const ctx = this._readCtx();
|
|
5164
|
+
return ctx.order;
|
|
5117
5165
|
}
|
|
5118
|
-
/**
|
|
5119
|
-
* Verified if the value satisfies the condition.
|
|
5120
|
-
*/
|
|
5121
5166
|
verify(nodeValue, condition) {
|
|
5122
5167
|
for (const key in condition) {
|
|
5123
5168
|
const verifyFn = this._verifierMap[key];
|
|
@@ -5130,15 +5175,18 @@ var BPTreePureSync = class {
|
|
|
5130
5175
|
}
|
|
5131
5176
|
// ─── Query ───────────────────────────────────────────────────────
|
|
5132
5177
|
get(key) {
|
|
5133
|
-
|
|
5178
|
+
const ctx = this._readCtx();
|
|
5179
|
+
return getOp(this._createReadOps(), ctx.rootId, key);
|
|
5134
5180
|
}
|
|
5135
5181
|
exists(key, value) {
|
|
5136
|
-
|
|
5182
|
+
const ctx = this._readCtx();
|
|
5183
|
+
return existsOp(this._createReadOps(), ctx.rootId, key, value, this.comparator);
|
|
5137
5184
|
}
|
|
5138
5185
|
*keysStream(condition, options) {
|
|
5186
|
+
const ctx = this._readCtx();
|
|
5139
5187
|
yield* keysStreamOp(
|
|
5140
|
-
this.
|
|
5141
|
-
|
|
5188
|
+
this._createReadOps(),
|
|
5189
|
+
ctx.rootId,
|
|
5142
5190
|
condition,
|
|
5143
5191
|
this.comparator,
|
|
5144
5192
|
this._verifierMap,
|
|
@@ -5148,9 +5196,10 @@ var BPTreePureSync = class {
|
|
|
5148
5196
|
);
|
|
5149
5197
|
}
|
|
5150
5198
|
*whereStream(condition, options) {
|
|
5199
|
+
const ctx = this._readCtx();
|
|
5151
5200
|
yield* whereStreamOp(
|
|
5152
|
-
this.
|
|
5153
|
-
|
|
5201
|
+
this._createReadOps(),
|
|
5202
|
+
ctx.rootId,
|
|
5154
5203
|
condition,
|
|
5155
5204
|
this.comparator,
|
|
5156
5205
|
this._verifierMap,
|
|
@@ -5176,27 +5225,37 @@ var BPTreePureSync = class {
|
|
|
5176
5225
|
// ─── Mutation ────────────────────────────────────────────────────
|
|
5177
5226
|
insert(key, value) {
|
|
5178
5227
|
const { ops, flush } = this._createBufferedOps();
|
|
5179
|
-
|
|
5228
|
+
const ctx = this._createCtx();
|
|
5229
|
+
insertOp(ops, ctx, key, value, this.comparator);
|
|
5180
5230
|
flush();
|
|
5181
5231
|
}
|
|
5182
5232
|
delete(key, value) {
|
|
5183
5233
|
const { ops, flush } = this._createBufferedOps();
|
|
5184
|
-
|
|
5234
|
+
const ctx = this._createCtx();
|
|
5235
|
+
deleteOp(ops, ctx, key, this.comparator, value);
|
|
5236
|
+
flush();
|
|
5237
|
+
}
|
|
5238
|
+
batchDelete(entries) {
|
|
5239
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5240
|
+
const ctx = this._createCtx();
|
|
5241
|
+
batchDeleteOp(ops, ctx, entries, this.comparator);
|
|
5185
5242
|
flush();
|
|
5186
5243
|
}
|
|
5187
5244
|
batchInsert(entries) {
|
|
5188
5245
|
const { ops, flush } = this._createBufferedOps();
|
|
5189
|
-
|
|
5246
|
+
const ctx = this._createCtx();
|
|
5247
|
+
batchInsertOp(ops, ctx, entries, this.comparator);
|
|
5190
5248
|
flush();
|
|
5191
5249
|
}
|
|
5192
5250
|
bulkLoad(entries) {
|
|
5193
5251
|
const { ops, flush } = this._createBufferedOps();
|
|
5194
|
-
|
|
5252
|
+
const ctx = this._createCtx();
|
|
5253
|
+
bulkLoadOp(ops, ctx, entries, this.comparator);
|
|
5195
5254
|
flush();
|
|
5196
5255
|
}
|
|
5197
5256
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
5198
5257
|
getHeadData() {
|
|
5199
|
-
const head = this.
|
|
5258
|
+
const head = this.strategy.readHead();
|
|
5200
5259
|
if (head === null) {
|
|
5201
5260
|
throw new Error("Head not found");
|
|
5202
5261
|
}
|
|
@@ -5224,8 +5283,6 @@ var BPTreePureAsync = class {
|
|
|
5224
5283
|
option;
|
|
5225
5284
|
lock = new Ryoiki2();
|
|
5226
5285
|
_cachedRegexp = /* @__PURE__ */ new Map();
|
|
5227
|
-
_ctx;
|
|
5228
|
-
_ops;
|
|
5229
5286
|
_verifierMap;
|
|
5230
5287
|
_searchConfigs;
|
|
5231
5288
|
constructor(strategy, comparator, option) {
|
|
@@ -5239,8 +5296,9 @@ var BPTreePureAsync = class {
|
|
|
5239
5296
|
_ensureValues(v) {
|
|
5240
5297
|
return Array.isArray(v) ? v : [v];
|
|
5241
5298
|
}
|
|
5242
|
-
|
|
5299
|
+
_createReadOps() {
|
|
5243
5300
|
const strategy = this.strategy;
|
|
5301
|
+
let headBuffer = null;
|
|
5244
5302
|
return {
|
|
5245
5303
|
async getNode(id) {
|
|
5246
5304
|
return await strategy.read(id);
|
|
@@ -5255,9 +5313,12 @@ var BPTreePureAsync = class {
|
|
|
5255
5313
|
async deleteNode() {
|
|
5256
5314
|
},
|
|
5257
5315
|
async readHead() {
|
|
5258
|
-
|
|
5316
|
+
if (headBuffer) return headBuffer;
|
|
5317
|
+
headBuffer = await strategy.readHead();
|
|
5318
|
+
return headBuffer;
|
|
5259
5319
|
},
|
|
5260
|
-
async writeHead() {
|
|
5320
|
+
async writeHead(head) {
|
|
5321
|
+
headBuffer = head;
|
|
5261
5322
|
}
|
|
5262
5323
|
};
|
|
5263
5324
|
}
|
|
@@ -5287,7 +5348,8 @@ var BPTreePureAsync = class {
|
|
|
5287
5348
|
},
|
|
5288
5349
|
async readHead() {
|
|
5289
5350
|
if (headBuffer) return headBuffer;
|
|
5290
|
-
|
|
5351
|
+
headBuffer = await strategy.readHead();
|
|
5352
|
+
return headBuffer;
|
|
5291
5353
|
},
|
|
5292
5354
|
async writeHead(head) {
|
|
5293
5355
|
headBuffer = head;
|
|
@@ -5295,6 +5357,7 @@ var BPTreePureAsync = class {
|
|
|
5295
5357
|
};
|
|
5296
5358
|
async function flush() {
|
|
5297
5359
|
for (const id of deleteBuffer) {
|
|
5360
|
+
writeBuffer.delete(id);
|
|
5298
5361
|
await strategy.delete(id);
|
|
5299
5362
|
}
|
|
5300
5363
|
for (const [id, node] of writeBuffer) {
|
|
@@ -5303,9 +5366,31 @@ var BPTreePureAsync = class {
|
|
|
5303
5366
|
if (headBuffer) {
|
|
5304
5367
|
await strategy.writeHead(headBuffer);
|
|
5305
5368
|
}
|
|
5369
|
+
writeBuffer.clear();
|
|
5370
|
+
deleteBuffer.clear();
|
|
5371
|
+
headBuffer = null;
|
|
5306
5372
|
}
|
|
5307
5373
|
return { ops, flush };
|
|
5308
5374
|
}
|
|
5375
|
+
async _readCtx() {
|
|
5376
|
+
const head = await this.strategy.readHead();
|
|
5377
|
+
if (head === null) {
|
|
5378
|
+
throw new Error("Tree not initialized. Call init() first.");
|
|
5379
|
+
}
|
|
5380
|
+
return { rootId: head.root, order: head.order };
|
|
5381
|
+
}
|
|
5382
|
+
async _createCtx() {
|
|
5383
|
+
const strategy = this.strategy;
|
|
5384
|
+
const head = await strategy.readHead();
|
|
5385
|
+
if (head === null) {
|
|
5386
|
+
throw new Error("Tree not initialized. Call init() first.");
|
|
5387
|
+
}
|
|
5388
|
+
return {
|
|
5389
|
+
rootId: head.root,
|
|
5390
|
+
order: head.order,
|
|
5391
|
+
headData: () => strategy.head.data
|
|
5392
|
+
};
|
|
5393
|
+
}
|
|
5309
5394
|
async writeLock(fn) {
|
|
5310
5395
|
let lockId;
|
|
5311
5396
|
return this.lock.writeLock(async (_lockId) => {
|
|
@@ -5318,14 +5403,14 @@ var BPTreePureAsync = class {
|
|
|
5318
5403
|
async init() {
|
|
5319
5404
|
return this.writeLock(async () => {
|
|
5320
5405
|
const { ops, flush } = this._createBufferedOps();
|
|
5321
|
-
|
|
5406
|
+
const ctx = {
|
|
5322
5407
|
rootId: "",
|
|
5323
5408
|
order: this.strategy.order,
|
|
5324
5409
|
headData: () => this.strategy.head.data
|
|
5325
5410
|
};
|
|
5326
5411
|
await initOpAsync(
|
|
5327
5412
|
ops,
|
|
5328
|
-
|
|
5413
|
+
ctx,
|
|
5329
5414
|
this.strategy.order,
|
|
5330
5415
|
this.strategy.head,
|
|
5331
5416
|
(head) => {
|
|
@@ -5333,14 +5418,19 @@ var BPTreePureAsync = class {
|
|
|
5333
5418
|
}
|
|
5334
5419
|
);
|
|
5335
5420
|
await flush();
|
|
5336
|
-
this._ops = this._createOps();
|
|
5337
5421
|
});
|
|
5338
5422
|
}
|
|
5339
|
-
|
|
5340
|
-
|
|
5423
|
+
async getRootNode() {
|
|
5424
|
+
const ctx = await this._readCtx();
|
|
5425
|
+
return await this.strategy.read(ctx.rootId);
|
|
5341
5426
|
}
|
|
5342
|
-
|
|
5343
|
-
|
|
5427
|
+
async getRootId() {
|
|
5428
|
+
const ctx = await this._readCtx();
|
|
5429
|
+
return ctx.rootId;
|
|
5430
|
+
}
|
|
5431
|
+
async getOrder() {
|
|
5432
|
+
const ctx = await this._readCtx();
|
|
5433
|
+
return ctx.order;
|
|
5344
5434
|
}
|
|
5345
5435
|
verify(nodeValue, condition) {
|
|
5346
5436
|
for (const key in condition) {
|
|
@@ -5352,18 +5442,21 @@ var BPTreePureAsync = class {
|
|
|
5352
5442
|
}
|
|
5353
5443
|
// ─── Query ───────────────────────────────────────────────────────
|
|
5354
5444
|
async get(key) {
|
|
5355
|
-
|
|
5445
|
+
const ctx = await this._readCtx();
|
|
5446
|
+
return getOpAsync(this._createReadOps(), ctx.rootId, key);
|
|
5356
5447
|
}
|
|
5357
5448
|
async exists(key, value) {
|
|
5358
|
-
|
|
5449
|
+
const ctx = await this._readCtx();
|
|
5450
|
+
return existsOpAsync(this._createReadOps(), ctx.rootId, key, value, this.comparator);
|
|
5359
5451
|
}
|
|
5360
5452
|
async *keysStream(condition, options) {
|
|
5361
5453
|
let lockId;
|
|
5362
5454
|
try {
|
|
5363
5455
|
lockId = await this.lock.readLock([0, 0.1], async (id) => id);
|
|
5456
|
+
const ctx = await this._readCtx();
|
|
5364
5457
|
yield* keysStreamOpAsync(
|
|
5365
|
-
this.
|
|
5366
|
-
|
|
5458
|
+
this._createReadOps(),
|
|
5459
|
+
ctx.rootId,
|
|
5367
5460
|
condition,
|
|
5368
5461
|
this.comparator,
|
|
5369
5462
|
this._verifierMap,
|
|
@@ -5379,9 +5472,10 @@ var BPTreePureAsync = class {
|
|
|
5379
5472
|
let lockId;
|
|
5380
5473
|
try {
|
|
5381
5474
|
lockId = await this.lock.readLock([0, 0.1], async (id) => id);
|
|
5475
|
+
const ctx = await this._readCtx();
|
|
5382
5476
|
yield* whereStreamOpAsync(
|
|
5383
|
-
this.
|
|
5384
|
-
|
|
5477
|
+
this._createReadOps(),
|
|
5478
|
+
ctx.rootId,
|
|
5385
5479
|
condition,
|
|
5386
5480
|
this.comparator,
|
|
5387
5481
|
this._verifierMap,
|
|
@@ -5411,34 +5505,46 @@ var BPTreePureAsync = class {
|
|
|
5411
5505
|
async insert(key, value) {
|
|
5412
5506
|
return this.writeLock(async () => {
|
|
5413
5507
|
const { ops, flush } = this._createBufferedOps();
|
|
5414
|
-
|
|
5508
|
+
const ctx = await this._createCtx();
|
|
5509
|
+
await insertOpAsync(ops, ctx, key, value, this.comparator);
|
|
5415
5510
|
await flush();
|
|
5416
5511
|
});
|
|
5417
5512
|
}
|
|
5418
5513
|
async delete(key, value) {
|
|
5419
5514
|
return this.writeLock(async () => {
|
|
5420
5515
|
const { ops, flush } = this._createBufferedOps();
|
|
5421
|
-
|
|
5516
|
+
const ctx = await this._createCtx();
|
|
5517
|
+
await deleteOpAsync(ops, ctx, key, this.comparator, value);
|
|
5422
5518
|
await flush();
|
|
5423
5519
|
});
|
|
5424
5520
|
}
|
|
5425
5521
|
async batchInsert(entries) {
|
|
5426
5522
|
return this.writeLock(async () => {
|
|
5427
5523
|
const { ops, flush } = this._createBufferedOps();
|
|
5428
|
-
|
|
5524
|
+
const ctx = await this._createCtx();
|
|
5525
|
+
await batchInsertOpAsync(ops, ctx, entries, this.comparator);
|
|
5526
|
+
await flush();
|
|
5527
|
+
});
|
|
5528
|
+
}
|
|
5529
|
+
async batchDelete(entries) {
|
|
5530
|
+
return this.writeLock(async () => {
|
|
5531
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5532
|
+
const ctx = await this._createCtx();
|
|
5533
|
+
await batchDeleteOpAsync(ops, ctx, entries, this.comparator);
|
|
5429
5534
|
await flush();
|
|
5430
5535
|
});
|
|
5431
5536
|
}
|
|
5432
5537
|
async bulkLoad(entries) {
|
|
5433
5538
|
return this.writeLock(async () => {
|
|
5434
5539
|
const { ops, flush } = this._createBufferedOps();
|
|
5435
|
-
|
|
5540
|
+
const ctx = await this._createCtx();
|
|
5541
|
+
await bulkLoadOpAsync(ops, ctx, entries, this.comparator);
|
|
5436
5542
|
await flush();
|
|
5437
5543
|
});
|
|
5438
5544
|
}
|
|
5439
5545
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
5440
5546
|
async getHeadData() {
|
|
5441
|
-
const head = await this.
|
|
5547
|
+
const head = await this.strategy.readHead();
|
|
5442
5548
|
if (head === null) throw new Error("Head not found");
|
|
5443
5549
|
return head.data;
|
|
5444
5550
|
}
|
|
@@ -9859,7 +9965,7 @@ var PageFileSystem = class {
|
|
|
9859
9965
|
* @param tx Transaction
|
|
9860
9966
|
*/
|
|
9861
9967
|
async updateBitmap(pageId, isFree, tx) {
|
|
9862
|
-
const metadata = await this.getMetadata(tx);
|
|
9968
|
+
const metadata = await this.getMetadata(false, tx);
|
|
9863
9969
|
const metadataManager = this.pageFactory.getManager(metadata);
|
|
9864
9970
|
const bitmapPageId = metadataManager.getBitmapPageId(metadata);
|
|
9865
9971
|
const headerSize = PageManager.CONSTANT.SIZE_PAGE_HEADER;
|
|
@@ -9867,7 +9973,7 @@ var PageFileSystem = class {
|
|
|
9867
9973
|
let currentBitmapPageId = bitmapPageId;
|
|
9868
9974
|
let targetBitIndex = pageId;
|
|
9869
9975
|
while (targetBitIndex >= capacityPerBitmapPage) {
|
|
9870
|
-
const currentBitmapPage = await this.get(currentBitmapPageId, tx);
|
|
9976
|
+
const currentBitmapPage = await this.get(currentBitmapPageId, true, tx);
|
|
9871
9977
|
const manager = this.pageFactory.getManager(currentBitmapPage);
|
|
9872
9978
|
targetBitIndex -= capacityPerBitmapPage;
|
|
9873
9979
|
const nextPageId = manager.getNextPageId(currentBitmapPage);
|
|
@@ -9884,7 +9990,7 @@ var PageFileSystem = class {
|
|
|
9884
9990
|
}
|
|
9885
9991
|
}
|
|
9886
9992
|
await tx.__acquireWriteLock(currentBitmapPageId);
|
|
9887
|
-
const targetBitmapPage = await this.get(currentBitmapPageId, tx);
|
|
9993
|
+
const targetBitmapPage = await this.get(currentBitmapPageId, true, tx);
|
|
9888
9994
|
const bitmapManager = this.pageFactory.getManager(targetBitmapPage);
|
|
9889
9995
|
bitmapManager.setBit(targetBitmapPage, targetBitIndex, isFree);
|
|
9890
9996
|
await this.setPage(currentBitmapPageId, targetBitmapPage, tx);
|
|
@@ -9903,20 +10009,22 @@ var PageFileSystem = class {
|
|
|
9903
10009
|
}
|
|
9904
10010
|
/**
|
|
9905
10011
|
* @param pageIndex 페이지 인덱스
|
|
10012
|
+
* @param copy Copy-on-Read
|
|
9906
10013
|
* @param tx 트랜잭션
|
|
9907
10014
|
* @returns 페이지 버퍼
|
|
9908
10015
|
*/
|
|
9909
|
-
async get(pageIndex, tx) {
|
|
9910
|
-
return tx.__readPage(pageIndex);
|
|
10016
|
+
async get(pageIndex, copy, tx) {
|
|
10017
|
+
return tx.__readPage(pageIndex, copy);
|
|
9911
10018
|
}
|
|
9912
10019
|
/**
|
|
9913
10020
|
* Reads the page header.
|
|
9914
10021
|
* @param pageIndex Page index
|
|
10022
|
+
* @param copy Copy-on-Read
|
|
9915
10023
|
* @param tx Transaction
|
|
9916
10024
|
* @returns Page header buffer
|
|
9917
10025
|
*/
|
|
9918
|
-
async getHeader(pageIndex, tx) {
|
|
9919
|
-
const page = await this.get(pageIndex, tx);
|
|
10026
|
+
async getHeader(pageIndex, copy, tx) {
|
|
10027
|
+
const page = await this.get(pageIndex, copy, tx);
|
|
9920
10028
|
return page.subarray(0, PageManager.CONSTANT.SIZE_PAGE_HEADER);
|
|
9921
10029
|
}
|
|
9922
10030
|
/**
|
|
@@ -9927,7 +10035,7 @@ var PageFileSystem = class {
|
|
|
9927
10035
|
* @returns Page body buffer
|
|
9928
10036
|
*/
|
|
9929
10037
|
async getBody(pageIndex, recursive = false, tx) {
|
|
9930
|
-
const page = await this.get(pageIndex, tx);
|
|
10038
|
+
const page = await this.get(pageIndex, false, tx);
|
|
9931
10039
|
const manager = this.pageFactory.getManager(page);
|
|
9932
10040
|
const fullBody = manager.getBody(page);
|
|
9933
10041
|
if (!recursive) {
|
|
@@ -9945,11 +10053,12 @@ var PageFileSystem = class {
|
|
|
9945
10053
|
}
|
|
9946
10054
|
/**
|
|
9947
10055
|
* Returns the metadata page.
|
|
10056
|
+
* @param copy Copy-on-Read
|
|
9948
10057
|
* @param tx Transaction
|
|
9949
10058
|
* @returns Metadata page
|
|
9950
10059
|
*/
|
|
9951
|
-
async getMetadata(tx) {
|
|
9952
|
-
const page = await this.get(0, tx);
|
|
10060
|
+
async getMetadata(copy, tx) {
|
|
10061
|
+
const page = await this.get(0, copy, tx);
|
|
9953
10062
|
if (!MetadataPageManager.IsMetadataPage(page)) {
|
|
9954
10063
|
throw new Error("Invalid metadata page");
|
|
9955
10064
|
}
|
|
@@ -9961,20 +10070,21 @@ var PageFileSystem = class {
|
|
|
9961
10070
|
* @returns Number of pages
|
|
9962
10071
|
*/
|
|
9963
10072
|
async getPageCount(tx) {
|
|
9964
|
-
const metadata = await this.getMetadata(tx);
|
|
10073
|
+
const metadata = await this.getMetadata(false, tx);
|
|
9965
10074
|
const manager = this.pageFactory.getManager(metadata);
|
|
9966
10075
|
return manager.getPageCount(metadata);
|
|
9967
10076
|
}
|
|
9968
10077
|
/**
|
|
9969
10078
|
* Returns the root index page.
|
|
10079
|
+
* @param copy Copy-on-Read
|
|
9970
10080
|
* @param tx Transaction
|
|
9971
10081
|
* @returns Root index page
|
|
9972
10082
|
*/
|
|
9973
|
-
async getRootIndex(tx) {
|
|
9974
|
-
const metadata = await this.getMetadata(tx);
|
|
10083
|
+
async getRootIndex(copy, tx) {
|
|
10084
|
+
const metadata = await this.getMetadata(false, tx);
|
|
9975
10085
|
const manager = this.pageFactory.getManager(metadata);
|
|
9976
10086
|
const rootIndexPageId = manager.getRootIndexPageId(metadata);
|
|
9977
|
-
const rootIndexPage = await this.get(rootIndexPageId, tx);
|
|
10087
|
+
const rootIndexPage = await this.get(rootIndexPageId, copy, tx);
|
|
9978
10088
|
if (!IndexPageManager.IsIndexPage(rootIndexPage)) {
|
|
9979
10089
|
throw new Error("Invalid root index page");
|
|
9980
10090
|
}
|
|
@@ -10009,12 +10119,12 @@ var PageFileSystem = class {
|
|
|
10009
10119
|
async appendNewPage(pageType = PageManager.CONSTANT.PAGE_TYPE_EMPTY, tx) {
|
|
10010
10120
|
this.logger.debug(`Appending new page of type ${pageType}`);
|
|
10011
10121
|
await tx.__acquireWriteLock(0);
|
|
10012
|
-
const metadata = await this.getMetadata(tx);
|
|
10122
|
+
const metadata = await this.getMetadata(true, tx);
|
|
10013
10123
|
const metadataManager = this.pageFactory.getManager(metadata);
|
|
10014
10124
|
const freePageId = metadataManager.getFreePageId(metadata);
|
|
10015
10125
|
if (freePageId !== -1) {
|
|
10016
10126
|
const reusedPageId = freePageId;
|
|
10017
|
-
const reusedPage = await this.get(reusedPageId, tx);
|
|
10127
|
+
const reusedPage = await this.get(reusedPageId, false, tx);
|
|
10018
10128
|
const reusedPageManager = this.pageFactory.getManager(reusedPage);
|
|
10019
10129
|
const nextFreePageId = reusedPageManager.getNextPageId(reusedPage);
|
|
10020
10130
|
metadataManager.setFreePageId(metadata, nextFreePageId);
|
|
@@ -10059,7 +10169,7 @@ var PageFileSystem = class {
|
|
|
10059
10169
|
let currentOffset = offset;
|
|
10060
10170
|
let dataOffset = 0;
|
|
10061
10171
|
while (dataOffset < data.length) {
|
|
10062
|
-
const page = await this.get(currentPageId, tx);
|
|
10172
|
+
const page = await this.get(currentPageId, true, tx);
|
|
10063
10173
|
const manager = this.pageFactory.getManager(page);
|
|
10064
10174
|
const bodyStart = PageManager.CONSTANT.SIZE_PAGE_HEADER;
|
|
10065
10175
|
const bodySize = this.pageSize - bodyStart;
|
|
@@ -10119,7 +10229,7 @@ var PageFileSystem = class {
|
|
|
10119
10229
|
break;
|
|
10120
10230
|
}
|
|
10121
10231
|
visited.add(currentPageId);
|
|
10122
|
-
const page = await this.get(currentPageId, tx);
|
|
10232
|
+
const page = await this.get(currentPageId, false, tx);
|
|
10123
10233
|
const nextPageId = this.pageFactory.getManager(page).getNextPageId(page);
|
|
10124
10234
|
await this.setFreePage(currentPageId, tx);
|
|
10125
10235
|
currentPageId = nextPageId;
|
|
@@ -10135,7 +10245,7 @@ var PageFileSystem = class {
|
|
|
10135
10245
|
if (pageId <= 0) return;
|
|
10136
10246
|
await tx.__acquireWriteLock(0);
|
|
10137
10247
|
await tx.__acquireWriteLock(pageId);
|
|
10138
|
-
const metadata = await this.getMetadata(tx);
|
|
10248
|
+
const metadata = await this.getMetadata(true, tx);
|
|
10139
10249
|
const metadataManager = this.pageFactory.getManager(metadata);
|
|
10140
10250
|
const currentHeadFreePageId = metadataManager.getFreePageId(metadata);
|
|
10141
10251
|
const emptyPageManager = this.pageFactory.getManagerFromType(PageManager.CONSTANT.PAGE_TYPE_EMPTY);
|
|
@@ -10218,12 +10328,12 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
|
|
|
10218
10328
|
async id(isLeaf) {
|
|
10219
10329
|
const tx = this.txContext.get();
|
|
10220
10330
|
await tx.__acquireWriteLock(0);
|
|
10221
|
-
const metadata = await this.pfs.getMetadata(tx);
|
|
10331
|
+
const metadata = await this.pfs.getMetadata(true, tx);
|
|
10222
10332
|
const metadataManager = this.factory.getManager(metadata);
|
|
10223
10333
|
const freePageId = metadataManager.getFreePageId(metadata);
|
|
10224
10334
|
let pageId;
|
|
10225
10335
|
if (freePageId !== -1) {
|
|
10226
|
-
const freePage = await this.pfs.get(freePageId, tx);
|
|
10336
|
+
const freePage = await this.pfs.get(freePageId, false, tx);
|
|
10227
10337
|
const freePageManager = this.factory.getManager(freePage);
|
|
10228
10338
|
const nextFreePageId = freePageManager.getNextPageId(freePage);
|
|
10229
10339
|
metadataManager.setFreePageId(metadata, nextFreePageId);
|
|
@@ -10239,7 +10349,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
|
|
|
10239
10349
|
async read(id) {
|
|
10240
10350
|
const tx = this.txContext.get();
|
|
10241
10351
|
const pageId = +id;
|
|
10242
|
-
const page = await this.pfs.get(pageId, tx);
|
|
10352
|
+
const page = await this.pfs.get(pageId, false, tx);
|
|
10243
10353
|
if (!IndexPageManager.IsIndexPage(page)) {
|
|
10244
10354
|
throw new Error(`Node ${id} does not exist - not a valid index page`);
|
|
10245
10355
|
}
|
|
@@ -10274,7 +10384,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
|
|
|
10274
10384
|
async write(id, node) {
|
|
10275
10385
|
const tx = this.txContext.get();
|
|
10276
10386
|
const pageId = +id;
|
|
10277
|
-
let page = await this.pfs.get(pageId, tx);
|
|
10387
|
+
let page = await this.pfs.get(pageId, true, tx);
|
|
10278
10388
|
if (!IndexPageManager.IsIndexPage(page)) {
|
|
10279
10389
|
page = this.indexPageManger.create(this.pfs.pageSize, pageId);
|
|
10280
10390
|
}
|
|
@@ -10322,7 +10432,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
|
|
|
10322
10432
|
}
|
|
10323
10433
|
async readHead() {
|
|
10324
10434
|
const tx = this.txContext.get();
|
|
10325
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
10435
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10326
10436
|
const manager = this.factory.getManager(metadataPage);
|
|
10327
10437
|
const rootIndexPageId = manager.getRootIndexPageId(metadataPage);
|
|
10328
10438
|
if (rootIndexPageId === -1) {
|
|
@@ -10342,7 +10452,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
|
|
|
10342
10452
|
if (root === null) {
|
|
10343
10453
|
throw new Error("");
|
|
10344
10454
|
}
|
|
10345
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
10455
|
+
const metadataPage = await this.pfs.getMetadata(true, tx);
|
|
10346
10456
|
const manager = this.factory.getManager(metadataPage);
|
|
10347
10457
|
manager.setRootIndexPageId(metadataPage, +root);
|
|
10348
10458
|
manager.setRootIndexOrder(metadataPage, order);
|
|
@@ -10503,7 +10613,7 @@ var RowTableEngine = class {
|
|
|
10503
10613
|
if (!this.initialized) {
|
|
10504
10614
|
throw new Error("RowTableEngine instance is not initialized");
|
|
10505
10615
|
}
|
|
10506
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
10616
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10507
10617
|
const manager = this.factory.getManagerFromType(MetadataPageManager.CONSTANT.PAGE_TYPE_METADATA);
|
|
10508
10618
|
const pageSize = manager.getPageSize(metadataPage);
|
|
10509
10619
|
const pageCount = manager.getPageCount(metadataPage);
|
|
@@ -10531,10 +10641,10 @@ var RowTableEngine = class {
|
|
|
10531
10641
|
}
|
|
10532
10642
|
await tx.__acquireWriteLock(0);
|
|
10533
10643
|
const pks = [];
|
|
10534
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
10644
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10535
10645
|
let lastPk = this.metadataPageManager.getLastRowPk(metadataPage);
|
|
10536
10646
|
let lastInsertDataPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
|
|
10537
|
-
let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, tx);
|
|
10647
|
+
let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, true, tx);
|
|
10538
10648
|
if (!this.factory.isDataPage(lastInsertDataPage)) {
|
|
10539
10649
|
throw new Error(`Last insert page is not data page`);
|
|
10540
10650
|
}
|
|
@@ -10556,7 +10666,7 @@ var RowTableEngine = class {
|
|
|
10556
10666
|
await this.pfs.setPage(lastInsertDataPageId, lastInsertDataPage, tx);
|
|
10557
10667
|
} else {
|
|
10558
10668
|
const newPageId = await this.pfs.appendNewPage(this.dataPageManager.pageType, tx);
|
|
10559
|
-
const newPage = await this.pfs.get(newPageId, tx);
|
|
10669
|
+
const newPage = await this.pfs.get(newPageId, true, tx);
|
|
10560
10670
|
this.dataPageManager.insert(newPage, row);
|
|
10561
10671
|
this.setRID(newPageId, 0);
|
|
10562
10672
|
lastInsertDataPageId = newPageId;
|
|
@@ -10571,7 +10681,7 @@ var RowTableEngine = class {
|
|
|
10571
10681
|
this.rowManager.setBody(row, data);
|
|
10572
10682
|
if (slotIndex === -1) {
|
|
10573
10683
|
const newPageId = await this.pfs.appendNewPage(this.dataPageManager.pageType, tx);
|
|
10574
|
-
const newPage = await this.pfs.get(newPageId, tx);
|
|
10684
|
+
const newPage = await this.pfs.get(newPageId, true, tx);
|
|
10575
10685
|
this.dataPageManager.insert(newPage, row);
|
|
10576
10686
|
this.setRID(newPageId, 0);
|
|
10577
10687
|
lastInsertDataPageId = newPageId;
|
|
@@ -10587,7 +10697,7 @@ var RowTableEngine = class {
|
|
|
10587
10697
|
pks.push(pk);
|
|
10588
10698
|
}
|
|
10589
10699
|
await this.bptree.batchInsert(batchInsertData);
|
|
10590
|
-
const freshMetadataPage = await this.pfs.getMetadata(tx);
|
|
10700
|
+
const freshMetadataPage = await this.pfs.getMetadata(true, tx);
|
|
10591
10701
|
this.metadataPageManager.setLastInsertPageId(freshMetadataPage, lastInsertDataPageId);
|
|
10592
10702
|
this.metadataPageManager.setLastRowPk(freshMetadataPage, lastPk);
|
|
10593
10703
|
if (incrementRowCount) {
|
|
@@ -10633,7 +10743,7 @@ var RowTableEngine = class {
|
|
|
10633
10743
|
this.keyManager.setBufferFromKey(rid, this.ridBuffer);
|
|
10634
10744
|
const pageId = this.keyManager.getPageId(this.ridBuffer);
|
|
10635
10745
|
const slotIndex = this.keyManager.getSlotIndex(this.ridBuffer);
|
|
10636
|
-
const page = await this.pfs.get(pageId, tx);
|
|
10746
|
+
const page = await this.pfs.get(pageId, true, tx);
|
|
10637
10747
|
if (!this.factory.isDataPage(page)) {
|
|
10638
10748
|
throw new Error(`RID not found for PK: ${pk}`);
|
|
10639
10749
|
}
|
|
@@ -10669,22 +10779,22 @@ var RowTableEngine = class {
|
|
|
10669
10779
|
this.rowManager.setBodySize(newRow, newBodySize);
|
|
10670
10780
|
this.rowManager.setBody(newRow, data);
|
|
10671
10781
|
await tx.__acquireWriteLock(0);
|
|
10672
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
10782
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10673
10783
|
let lastInsertDataPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
|
|
10674
|
-
let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, tx);
|
|
10784
|
+
let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, true, tx);
|
|
10675
10785
|
if (!this.factory.isDataPage(lastInsertDataPage)) {
|
|
10676
10786
|
throw new Error("Last insert page is not data page");
|
|
10677
10787
|
}
|
|
10678
10788
|
let newSlotIndex = this.dataPageManager.getNextSlotIndex(lastInsertDataPage, newRow);
|
|
10679
10789
|
if (newSlotIndex === -1) {
|
|
10680
10790
|
const newPageId = await this.pfs.appendNewPage(this.dataPageManager.pageType, tx);
|
|
10681
|
-
lastInsertDataPage = await this.pfs.get(newPageId, tx);
|
|
10791
|
+
lastInsertDataPage = await this.pfs.get(newPageId, true, tx);
|
|
10682
10792
|
lastInsertDataPageId = newPageId;
|
|
10683
10793
|
newSlotIndex = 0;
|
|
10684
10794
|
}
|
|
10685
10795
|
this.dataPageManager.insert(lastInsertDataPage, newRow);
|
|
10686
10796
|
await this.pfs.setPage(lastInsertDataPageId, lastInsertDataPage, tx);
|
|
10687
|
-
const targetPage = await this.pfs.get(pageId, tx);
|
|
10797
|
+
const targetPage = await this.pfs.get(pageId, true, tx);
|
|
10688
10798
|
if (!this.factory.isDataPage(targetPage)) {
|
|
10689
10799
|
throw new Error("Target page is not data page");
|
|
10690
10800
|
}
|
|
@@ -10697,7 +10807,7 @@ var RowTableEngine = class {
|
|
|
10697
10807
|
const newRidNumeric = this.getRID();
|
|
10698
10808
|
await this.bptree.delete(oldRidNumeric, pk);
|
|
10699
10809
|
await this.bptree.insert(newRidNumeric, pk);
|
|
10700
|
-
const freshMetadataPage = await this.pfs.getMetadata(tx);
|
|
10810
|
+
const freshMetadataPage = await this.pfs.getMetadata(true, tx);
|
|
10701
10811
|
this.metadataPageManager.setLastInsertPageId(freshMetadataPage, lastInsertDataPageId);
|
|
10702
10812
|
await this.pfs.setMetadata(freshMetadataPage, tx);
|
|
10703
10813
|
}
|
|
@@ -10717,7 +10827,7 @@ var RowTableEngine = class {
|
|
|
10717
10827
|
this.keyManager.setBufferFromKey(rid, this.ridBuffer);
|
|
10718
10828
|
const pageId = this.keyManager.getPageId(this.ridBuffer);
|
|
10719
10829
|
const slotIndex = this.keyManager.getSlotIndex(this.ridBuffer);
|
|
10720
|
-
const page = await this.pfs.get(pageId, tx);
|
|
10830
|
+
const page = await this.pfs.get(pageId, true, tx);
|
|
10721
10831
|
if (!this.factory.isDataPage(page)) {
|
|
10722
10832
|
throw new Error(`RID not found for PK: ${pk}`);
|
|
10723
10833
|
}
|
|
@@ -10733,14 +10843,14 @@ var RowTableEngine = class {
|
|
|
10733
10843
|
await this.pfs.setPage(pageId, page, tx);
|
|
10734
10844
|
await this.bptree.delete(rid, pk);
|
|
10735
10845
|
if (decrementRowCount) {
|
|
10736
|
-
const metadataPage2 = await this.pfs.getMetadata(tx);
|
|
10846
|
+
const metadataPage2 = await this.pfs.getMetadata(true, tx);
|
|
10737
10847
|
const currentRowCount = this.metadataPageManager.getRowCount(metadataPage2);
|
|
10738
10848
|
this.metadataPageManager.setRowCount(metadataPage2, currentRowCount - 1);
|
|
10739
10849
|
await this.pfs.setMetadata(metadataPage2, tx);
|
|
10740
10850
|
}
|
|
10741
10851
|
const insertedRowCount = this.dataPageManager.getInsertedRowCount(page);
|
|
10742
10852
|
let allDeleted = true;
|
|
10743
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
10853
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10744
10854
|
const lastInsertPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
|
|
10745
10855
|
if (pageId === lastInsertPageId) {
|
|
10746
10856
|
allDeleted = false;
|
|
@@ -10759,6 +10869,82 @@ var RowTableEngine = class {
|
|
|
10759
10869
|
await this.pfs.freeChain(pageId, tx);
|
|
10760
10870
|
}
|
|
10761
10871
|
}
|
|
10872
|
+
/**
|
|
10873
|
+
* Deletes multiple data in batch.
|
|
10874
|
+
* @param pks Array of PKs to delete
|
|
10875
|
+
* @param decrementRowCount Whether to decrement the row count to metadata
|
|
10876
|
+
* @param tx Transaction
|
|
10877
|
+
*/
|
|
10878
|
+
async deleteBatch(pks, decrementRowCount, tx) {
|
|
10879
|
+
this.logger.debug(`Batch deleting ${pks.length} rows`);
|
|
10880
|
+
if (pks.length === 0) {
|
|
10881
|
+
return;
|
|
10882
|
+
}
|
|
10883
|
+
await tx.__acquireWriteLock(0);
|
|
10884
|
+
const collections = await this.collectItemsByPage(pks, tx);
|
|
10885
|
+
if (collections.size === 0) {
|
|
10886
|
+
return;
|
|
10887
|
+
}
|
|
10888
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10889
|
+
const lastInsertPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
|
|
10890
|
+
const batchDeleteData = [];
|
|
10891
|
+
const pagesToFree = [];
|
|
10892
|
+
let deletedCount = 0;
|
|
10893
|
+
for (const [pageId, items] of collections) {
|
|
10894
|
+
const page = await this.pfs.get(pageId, true, tx);
|
|
10895
|
+
if (!this.factory.isDataPage(page)) {
|
|
10896
|
+
continue;
|
|
10897
|
+
}
|
|
10898
|
+
let pageModified = false;
|
|
10899
|
+
for (const item of items) {
|
|
10900
|
+
const row = this.dataPageManager.getRow(page, item.slotIndex);
|
|
10901
|
+
if (this.rowManager.getDeletedFlag(row)) {
|
|
10902
|
+
continue;
|
|
10903
|
+
}
|
|
10904
|
+
if (this.rowManager.getOverflowFlag(row)) {
|
|
10905
|
+
const overflowPageId = bytesToNumber(this.rowManager.getBody(row));
|
|
10906
|
+
await this.pfs.freeChain(overflowPageId, tx);
|
|
10907
|
+
}
|
|
10908
|
+
this.rowManager.setDeletedFlag(row, true);
|
|
10909
|
+
pageModified = true;
|
|
10910
|
+
this.setRID(pageId, item.slotIndex);
|
|
10911
|
+
batchDeleteData.push([this.getRID(), item.pk]);
|
|
10912
|
+
deletedCount++;
|
|
10913
|
+
}
|
|
10914
|
+
if (pageModified) {
|
|
10915
|
+
await this.pfs.setPage(pageId, page, tx);
|
|
10916
|
+
}
|
|
10917
|
+
if (pageId !== lastInsertPageId) {
|
|
10918
|
+
const insertedRowCount = this.dataPageManager.getInsertedRowCount(page);
|
|
10919
|
+
let allDeleted = true;
|
|
10920
|
+
let i = 0;
|
|
10921
|
+
while (i < insertedRowCount) {
|
|
10922
|
+
const slotRow = this.dataPageManager.getRow(page, i);
|
|
10923
|
+
if (!this.rowManager.getDeletedFlag(slotRow)) {
|
|
10924
|
+
allDeleted = false;
|
|
10925
|
+
break;
|
|
10926
|
+
}
|
|
10927
|
+
i++;
|
|
10928
|
+
}
|
|
10929
|
+
if (allDeleted) {
|
|
10930
|
+
pagesToFree.push(pageId);
|
|
10931
|
+
}
|
|
10932
|
+
}
|
|
10933
|
+
}
|
|
10934
|
+
if (batchDeleteData.length === 0) {
|
|
10935
|
+
return;
|
|
10936
|
+
}
|
|
10937
|
+
await this.bptree.batchDelete(batchDeleteData);
|
|
10938
|
+
if (decrementRowCount) {
|
|
10939
|
+
const freshMetadataPage = await this.pfs.getMetadata(true, tx);
|
|
10940
|
+
const currentRowCount = this.metadataPageManager.getRowCount(freshMetadataPage);
|
|
10941
|
+
this.metadataPageManager.setRowCount(freshMetadataPage, currentRowCount - deletedCount);
|
|
10942
|
+
await this.pfs.setMetadata(freshMetadataPage, tx);
|
|
10943
|
+
}
|
|
10944
|
+
for (const pageId of pagesToFree) {
|
|
10945
|
+
await this.pfs.freeChain(pageId, tx);
|
|
10946
|
+
}
|
|
10947
|
+
}
|
|
10762
10948
|
/**
|
|
10763
10949
|
* Looks up the RID corresponding to the PK in the B+ Tree and returns the actual row.
|
|
10764
10950
|
* @param pk Primary key of the row
|
|
@@ -10846,7 +11032,7 @@ var RowTableEngine = class {
|
|
|
10846
11032
|
const sortedPageIds = Array.from(collections.keys()).sort((a, b) => a - b);
|
|
10847
11033
|
await Promise.all(sortedPageIds.map(async (pageId) => {
|
|
10848
11034
|
const items = collections.get(pageId);
|
|
10849
|
-
const page = await this.pfs.get(pageId, tx);
|
|
11035
|
+
const page = await this.pfs.get(pageId, false, tx);
|
|
10850
11036
|
if (!this.factory.isDataPage(page)) {
|
|
10851
11037
|
throw new Error(`Page ${pageId} is not a data page`);
|
|
10852
11038
|
}
|
|
@@ -10871,7 +11057,7 @@ var RowTableEngine = class {
|
|
|
10871
11057
|
this.keyManager.setBufferFromKey(rid, this.ridBuffer);
|
|
10872
11058
|
const pageId = this.keyManager.getPageId(this.ridBuffer);
|
|
10873
11059
|
const slotIndex = this.keyManager.getSlotIndex(this.ridBuffer);
|
|
10874
|
-
const page = await this.pfs.get(pageId, tx);
|
|
11060
|
+
const page = await this.pfs.get(pageId, false, tx);
|
|
10875
11061
|
if (!this.factory.isDataPage(page)) {
|
|
10876
11062
|
throw new Error(`RID not found for PK: ${pk}`);
|
|
10877
11063
|
}
|
|
@@ -10881,7 +11067,7 @@ var RowTableEngine = class {
|
|
|
10881
11067
|
return null;
|
|
10882
11068
|
} else if (this.rowManager.getOverflowFlag(row)) {
|
|
10883
11069
|
const overflowPageId = bytesToNumber(this.rowManager.getBody(row));
|
|
10884
|
-
const overflowPage = await this.pfs.get(overflowPageId, tx);
|
|
11070
|
+
const overflowPage = await this.pfs.get(overflowPageId, false, tx);
|
|
10885
11071
|
if (!this.factory.isOverflowPage(overflowPage)) {
|
|
10886
11072
|
throw new Error(`Overflow page not found for RID: ${rid}`);
|
|
10887
11073
|
}
|
|
@@ -10895,16 +11081,11 @@ var RowTableEngine = class {
|
|
|
10895
11081
|
* @returns Row count
|
|
10896
11082
|
*/
|
|
10897
11083
|
async getRowCount(tx) {
|
|
10898
|
-
const metadataPage = await this.pfs.getMetadata(tx);
|
|
11084
|
+
const metadataPage = await this.pfs.getMetadata(false, tx);
|
|
10899
11085
|
return this.metadataPageManager.getRowCount(metadataPage);
|
|
10900
11086
|
}
|
|
10901
11087
|
};
|
|
10902
11088
|
|
|
10903
|
-
// src/utils/catchPromise.ts
|
|
10904
|
-
async function catchPromise(promise) {
|
|
10905
|
-
return promise.then((res) => [void 0, res]).catch((reason) => [reason]);
|
|
10906
|
-
}
|
|
10907
|
-
|
|
10908
11089
|
// src/core/transaction/LockManager.ts
|
|
10909
11090
|
var LockManager = class {
|
|
10910
11091
|
lock;
|
|
@@ -11006,16 +11187,20 @@ var Transaction = class {
|
|
|
11006
11187
|
/**
|
|
11007
11188
|
* Reads a page through the MVCC transaction.
|
|
11008
11189
|
* @param pageId Page ID
|
|
11190
|
+
* @param copy Copy-on-Read
|
|
11009
11191
|
* @returns Page data
|
|
11010
11192
|
*/
|
|
11011
|
-
async __readPage(pageId) {
|
|
11193
|
+
async __readPage(pageId, copy) {
|
|
11012
11194
|
const data = await this.mvccTx.read(pageId);
|
|
11013
11195
|
if (data === null) {
|
|
11014
11196
|
return new Uint8Array(this.pfs.pageSize);
|
|
11015
11197
|
}
|
|
11016
|
-
|
|
11017
|
-
|
|
11018
|
-
|
|
11198
|
+
if (copy) {
|
|
11199
|
+
const copy2 = new Uint8Array(data.length);
|
|
11200
|
+
copy2.set(data);
|
|
11201
|
+
return copy2;
|
|
11202
|
+
}
|
|
11203
|
+
return data;
|
|
11019
11204
|
}
|
|
11020
11205
|
/**
|
|
11021
11206
|
* Writes a page through the MVCC transaction.
|
|
@@ -11025,9 +11210,7 @@ var Transaction = class {
|
|
|
11025
11210
|
async __writePage(pageId, data) {
|
|
11026
11211
|
const exists = await this.mvccTx.exists(pageId);
|
|
11027
11212
|
if (exists) {
|
|
11028
|
-
|
|
11029
|
-
copy.set(data);
|
|
11030
|
-
await this.mvccTx.write(pageId, copy);
|
|
11213
|
+
await this.mvccTx.write(pageId, data);
|
|
11031
11214
|
} else {
|
|
11032
11215
|
await this.mvccTx.create(pageId, data);
|
|
11033
11216
|
}
|
|
@@ -11433,46 +11616,46 @@ var DataplyAPI = class {
|
|
|
11433
11616
|
* @returns The result of the callback.
|
|
11434
11617
|
*/
|
|
11435
11618
|
async withWriteTransaction(callback, tx) {
|
|
11436
|
-
this.logger.debug("Running with
|
|
11619
|
+
this.logger.debug("Running with write transaction");
|
|
11437
11620
|
if (!tx) {
|
|
11438
11621
|
const release = await this.acquireWriteLock();
|
|
11439
11622
|
const internalTx = this.createTransaction();
|
|
11440
11623
|
internalTx.__setWriteLockRelease(release);
|
|
11441
|
-
|
|
11442
|
-
|
|
11624
|
+
try {
|
|
11625
|
+
const result = await this.txContext.run(internalTx, () => callback(internalTx));
|
|
11626
|
+
await internalTx.commit();
|
|
11627
|
+
return result;
|
|
11628
|
+
} catch (error) {
|
|
11443
11629
|
await internalTx.rollback();
|
|
11444
|
-
throw
|
|
11630
|
+
throw error;
|
|
11445
11631
|
}
|
|
11446
|
-
await internalTx.commit();
|
|
11447
|
-
return result2;
|
|
11448
11632
|
}
|
|
11449
11633
|
if (!tx.__hasWriteLockRelease()) {
|
|
11450
11634
|
const release = await this.acquireWriteLock();
|
|
11451
11635
|
tx.__setWriteLockRelease(release);
|
|
11452
11636
|
}
|
|
11453
|
-
|
|
11454
|
-
|
|
11455
|
-
throw error;
|
|
11637
|
+
if (this.txContext.get() === tx) {
|
|
11638
|
+
return callback(tx);
|
|
11456
11639
|
}
|
|
11457
|
-
return
|
|
11640
|
+
return this.txContext.run(tx, () => callback(tx));
|
|
11458
11641
|
}
|
|
11459
11642
|
async withReadTransaction(callback, tx) {
|
|
11460
|
-
this.logger.debug("Running with
|
|
11461
|
-
const isInternalTx = !tx;
|
|
11643
|
+
this.logger.debug("Running with read transaction");
|
|
11462
11644
|
if (!tx) {
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11645
|
+
const internalTx = this.createTransaction();
|
|
11646
|
+
try {
|
|
11647
|
+
const result = await this.txContext.run(internalTx, () => callback(internalTx));
|
|
11648
|
+
await internalTx.commit();
|
|
11649
|
+
return result;
|
|
11650
|
+
} catch (error) {
|
|
11651
|
+
await internalTx.rollback();
|
|
11652
|
+
throw error;
|
|
11469
11653
|
}
|
|
11470
|
-
throw error;
|
|
11471
11654
|
}
|
|
11472
|
-
if (
|
|
11473
|
-
|
|
11655
|
+
if (this.txContext.get() === tx) {
|
|
11656
|
+
return callback(tx);
|
|
11474
11657
|
}
|
|
11475
|
-
return
|
|
11658
|
+
return this.txContext.run(tx, () => callback(tx));
|
|
11476
11659
|
}
|
|
11477
11660
|
/**
|
|
11478
11661
|
* Runs a generator callback function within a transaction context.
|
|
@@ -11616,6 +11799,23 @@ var DataplyAPI = class {
|
|
|
11616
11799
|
await this.rowTableEngine.delete(pk, decrementRowCount, tx2);
|
|
11617
11800
|
}, tx);
|
|
11618
11801
|
}
|
|
11802
|
+
/**
|
|
11803
|
+
* Deletes multiple data in batch.
|
|
11804
|
+
* If a transaction is not provided, it internally creates a single transaction to process.
|
|
11805
|
+
* @param pks Array of PKs to delete
|
|
11806
|
+
* @param decrementRowCount Whether to decrement the row count to metadata
|
|
11807
|
+
* @param tx Transaction
|
|
11808
|
+
*/
|
|
11809
|
+
async deleteBatch(pks, decrementRowCount, tx) {
|
|
11810
|
+
this.logger.debug(`Deleting batch data: ${pks.length} items`);
|
|
11811
|
+
if (!this.initialized) {
|
|
11812
|
+
throw new Error("Dataply instance is not initialized");
|
|
11813
|
+
}
|
|
11814
|
+
return this.withWriteTransaction(async (tx2) => {
|
|
11815
|
+
decrementRowCount = decrementRowCount ?? true;
|
|
11816
|
+
await this.rowTableEngine.deleteBatch(pks, decrementRowCount, tx2);
|
|
11817
|
+
}, tx);
|
|
11818
|
+
}
|
|
11619
11819
|
async select(pk, asRaw = false, tx) {
|
|
11620
11820
|
this.logger.debug(`Selecting data for PK: ${pk}`);
|
|
11621
11821
|
if (!this.initialized) {
|
|
@@ -11672,15 +11872,6 @@ var Dataply = class {
|
|
|
11672
11872
|
get options() {
|
|
11673
11873
|
return this.api.options;
|
|
11674
11874
|
}
|
|
11675
|
-
/**
|
|
11676
|
-
* Creates a transaction.
|
|
11677
|
-
* The created transaction object can be used to add or modify data.
|
|
11678
|
-
* A transaction must be terminated by calling either `commit` or `rollback`.
|
|
11679
|
-
* @returns Transaction object
|
|
11680
|
-
*/
|
|
11681
|
-
createTransaction() {
|
|
11682
|
-
return this.api.createTransaction();
|
|
11683
|
-
}
|
|
11684
11875
|
/**
|
|
11685
11876
|
* Runs a write callback within a transaction context.
|
|
11686
11877
|
*/
|
|
@@ -11750,6 +11941,15 @@ var Dataply = class {
|
|
|
11750
11941
|
async delete(pk, tx) {
|
|
11751
11942
|
return this.api.delete(pk, true, tx);
|
|
11752
11943
|
}
|
|
11944
|
+
/**
|
|
11945
|
+
* Deletes multiple data in batch.
|
|
11946
|
+
* If a transaction is not provided, it internally creates a single transaction to process.
|
|
11947
|
+
* @param pks Array of PKs to delete
|
|
11948
|
+
* @param tx Transaction
|
|
11949
|
+
*/
|
|
11950
|
+
async deleteBatch(pks, tx) {
|
|
11951
|
+
return this.api.deleteBatch(pks, true, tx);
|
|
11952
|
+
}
|
|
11753
11953
|
async select(pk, asRaw = false, tx) {
|
|
11754
11954
|
return this.api.select(pk, asRaw, tx);
|
|
11755
11955
|
}
|