dataply 0.0.26-alpha.13 → 0.0.26-alpha.15
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
CHANGED
|
@@ -2341,8 +2341,8 @@ function deleteEntry(ops, ctx, node, key, comparator) {
|
|
|
2341
2341
|
} else {
|
|
2342
2342
|
pointerP0 = siblingNode.keys.splice(0, 1)[0];
|
|
2343
2343
|
pointerK0 = siblingNode.values.splice(0, 1)[0];
|
|
2344
|
-
node.keys = node.keys
|
|
2345
|
-
node.values = node.values
|
|
2344
|
+
node.keys = [...node.keys, pointerP0];
|
|
2345
|
+
node.values = [...node.values, pointerK0];
|
|
2346
2346
|
parentNode = cloneNode(ops.getNode(node.parent));
|
|
2347
2347
|
const pointerIndex = parentNode.keys.indexOf(siblingNode.id);
|
|
2348
2348
|
if (pointerIndex > 0) {
|
|
@@ -2422,6 +2422,13 @@ function deleteOp(ops, ctx, key, comparator, value) {
|
|
|
2422
2422
|
break;
|
|
2423
2423
|
}
|
|
2424
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
|
+
}
|
|
2425
2432
|
function batchInsertOp(ops, ctx, entries, comparator) {
|
|
2426
2433
|
if (entries.length === 0) return;
|
|
2427
2434
|
const sorted = [...entries].sort((a, b) => comparator.asc(a[1], b[1]));
|
|
@@ -3393,6 +3400,9 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
3393
3400
|
delete(key, value) {
|
|
3394
3401
|
deleteOp(this._ops, this._ctx, key, this.comparator, value);
|
|
3395
3402
|
}
|
|
3403
|
+
batchDelete(entries) {
|
|
3404
|
+
batchDeleteOp(this._ops, this._ctx, entries, this.comparator);
|
|
3405
|
+
}
|
|
3396
3406
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
3397
3407
|
getHeadData() {
|
|
3398
3408
|
const head = this._readHead();
|
|
@@ -3514,6 +3524,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
|
|
|
3514
3524
|
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
3515
3525
|
}
|
|
3516
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
|
+
}
|
|
3517
3535
|
batchInsert(entries) {
|
|
3518
3536
|
const tx = this.createTransaction();
|
|
3519
3537
|
tx.batchInsert(entries);
|
|
@@ -4332,8 +4350,8 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
|
|
|
4332
4350
|
} else {
|
|
4333
4351
|
pointerP0 = siblingNode.keys.splice(0, 1)[0];
|
|
4334
4352
|
pointerK0 = siblingNode.values.splice(0, 1)[0];
|
|
4335
|
-
node.keys = node.keys
|
|
4336
|
-
node.values = node.values
|
|
4353
|
+
node.keys = [...node.keys, pointerP0];
|
|
4354
|
+
node.values = [...node.values, pointerK0];
|
|
4337
4355
|
parentNode = cloneNode(await ops.getNode(node.parent));
|
|
4338
4356
|
const pi = parentNode.keys.indexOf(siblingNode.id);
|
|
4339
4357
|
if (pi > 0) {
|
|
@@ -4405,6 +4423,13 @@ async function deleteOpAsync(ops, ctx, key, comparator, value) {
|
|
|
4405
4423
|
break;
|
|
4406
4424
|
}
|
|
4407
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
|
+
}
|
|
4408
4433
|
async function batchInsertOpAsync(ops, ctx, entries, comparator) {
|
|
4409
4434
|
if (entries.length === 0) return;
|
|
4410
4435
|
const sorted = [...entries].sort((a, b) => comparator.asc(a[1], b[1]));
|
|
@@ -4827,6 +4852,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
4827
4852
|
await deleteOpAsync(this._ops, this._ctx, key, this.comparator, value);
|
|
4828
4853
|
});
|
|
4829
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
|
+
}
|
|
4830
4861
|
// ─── Head Data ───────────────────────────────────────────────────
|
|
4831
4862
|
async getHeadData() {
|
|
4832
4863
|
const head = await this._readHead();
|
|
@@ -4952,6 +4983,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
|
|
|
4952
4983
|
}
|
|
4953
4984
|
});
|
|
4954
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
|
+
}
|
|
4955
4996
|
async batchInsert(entries) {
|
|
4956
4997
|
return this.writeLock(1, async () => {
|
|
4957
4998
|
const tx = await this.createTransaction();
|
|
@@ -5057,6 +5098,7 @@ var BPTreePureSync = class {
|
|
|
5057
5098
|
};
|
|
5058
5099
|
function flush() {
|
|
5059
5100
|
for (const id of deleteBuffer) {
|
|
5101
|
+
writeBuffer.delete(id);
|
|
5060
5102
|
strategy.delete(id);
|
|
5061
5103
|
}
|
|
5062
5104
|
for (const [id, node] of writeBuffer) {
|
|
@@ -5193,6 +5235,12 @@ var BPTreePureSync = class {
|
|
|
5193
5235
|
deleteOp(ops, ctx, key, this.comparator, value);
|
|
5194
5236
|
flush();
|
|
5195
5237
|
}
|
|
5238
|
+
batchDelete(entries) {
|
|
5239
|
+
const { ops, flush } = this._createBufferedOps();
|
|
5240
|
+
const ctx = this._createCtx();
|
|
5241
|
+
batchDeleteOp(ops, ctx, entries, this.comparator);
|
|
5242
|
+
flush();
|
|
5243
|
+
}
|
|
5196
5244
|
batchInsert(entries) {
|
|
5197
5245
|
const { ops, flush } = this._createBufferedOps();
|
|
5198
5246
|
const ctx = this._createCtx();
|
|
@@ -5309,6 +5357,7 @@ var BPTreePureAsync = class {
|
|
|
5309
5357
|
};
|
|
5310
5358
|
async function flush() {
|
|
5311
5359
|
for (const id of deleteBuffer) {
|
|
5360
|
+
writeBuffer.delete(id);
|
|
5312
5361
|
await strategy.delete(id);
|
|
5313
5362
|
}
|
|
5314
5363
|
for (const [id, node] of writeBuffer) {
|
|
@@ -5477,6 +5526,14 @@ var BPTreePureAsync = class {
|
|
|
5477
5526
|
await flush();
|
|
5478
5527
|
});
|
|
5479
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);
|
|
5534
|
+
await flush();
|
|
5535
|
+
});
|
|
5536
|
+
}
|
|
5480
5537
|
async bulkLoad(entries) {
|
|
5481
5538
|
return this.writeLock(async () => {
|
|
5482
5539
|
const { ops, flush } = this._createBufferedOps();
|
|
@@ -10812,6 +10869,82 @@ var RowTableEngine = class {
|
|
|
10812
10869
|
await this.pfs.freeChain(pageId, tx);
|
|
10813
10870
|
}
|
|
10814
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
|
+
}
|
|
10815
10948
|
/**
|
|
10816
10949
|
* Looks up the RID corresponding to the PK in the B+ Tree and returns the actual row.
|
|
10817
10950
|
* @param pk Primary key of the row
|
|
@@ -10953,11 +11086,6 @@ var RowTableEngine = class {
|
|
|
10953
11086
|
}
|
|
10954
11087
|
};
|
|
10955
11088
|
|
|
10956
|
-
// src/utils/catchPromise.ts
|
|
10957
|
-
async function catchPromise(promise) {
|
|
10958
|
-
return promise.then((res) => [void 0, res]).catch((reason) => [reason]);
|
|
10959
|
-
}
|
|
10960
|
-
|
|
10961
11089
|
// src/core/transaction/LockManager.ts
|
|
10962
11090
|
var LockManager = class {
|
|
10963
11091
|
lock;
|
|
@@ -11493,41 +11621,41 @@ var DataplyAPI = class {
|
|
|
11493
11621
|
const release = await this.acquireWriteLock();
|
|
11494
11622
|
const internalTx = this.createTransaction();
|
|
11495
11623
|
internalTx.__setWriteLockRelease(release);
|
|
11496
|
-
|
|
11497
|
-
|
|
11624
|
+
try {
|
|
11625
|
+
const result = await this.txContext.run(internalTx, () => callback(internalTx));
|
|
11626
|
+
await internalTx.commit();
|
|
11627
|
+
return result;
|
|
11628
|
+
} catch (error) {
|
|
11498
11629
|
await internalTx.rollback();
|
|
11499
|
-
throw
|
|
11630
|
+
throw error;
|
|
11500
11631
|
}
|
|
11501
|
-
await internalTx.commit();
|
|
11502
|
-
return result2;
|
|
11503
11632
|
}
|
|
11504
11633
|
if (!tx.__hasWriteLockRelease()) {
|
|
11505
11634
|
const release = await this.acquireWriteLock();
|
|
11506
11635
|
tx.__setWriteLockRelease(release);
|
|
11507
11636
|
}
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
throw error;
|
|
11637
|
+
if (this.txContext.get() === tx) {
|
|
11638
|
+
return callback(tx);
|
|
11511
11639
|
}
|
|
11512
|
-
return
|
|
11640
|
+
return this.txContext.run(tx, () => callback(tx));
|
|
11513
11641
|
}
|
|
11514
11642
|
async withReadTransaction(callback, tx) {
|
|
11515
11643
|
this.logger.debug("Running with read transaction");
|
|
11516
|
-
const isInternalTx = !tx;
|
|
11517
11644
|
if (!tx) {
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
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;
|
|
11524
11653
|
}
|
|
11525
|
-
throw error;
|
|
11526
11654
|
}
|
|
11527
|
-
if (
|
|
11528
|
-
|
|
11655
|
+
if (this.txContext.get() === tx) {
|
|
11656
|
+
return callback(tx);
|
|
11529
11657
|
}
|
|
11530
|
-
return
|
|
11658
|
+
return this.txContext.run(tx, () => callback(tx));
|
|
11531
11659
|
}
|
|
11532
11660
|
/**
|
|
11533
11661
|
* Runs a generator callback function within a transaction context.
|
|
@@ -11671,6 +11799,23 @@ var DataplyAPI = class {
|
|
|
11671
11799
|
await this.rowTableEngine.delete(pk, decrementRowCount, tx2);
|
|
11672
11800
|
}, tx);
|
|
11673
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
|
+
}
|
|
11674
11819
|
async select(pk, asRaw = false, tx) {
|
|
11675
11820
|
this.logger.debug(`Selecting data for PK: ${pk}`);
|
|
11676
11821
|
if (!this.initialized) {
|
|
@@ -11796,6 +11941,15 @@ var Dataply = class {
|
|
|
11796
11941
|
async delete(pk, tx) {
|
|
11797
11942
|
return this.api.delete(pk, true, tx);
|
|
11798
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
|
+
}
|
|
11799
11953
|
async select(pk, asRaw = false, tx) {
|
|
11800
11954
|
return this.api.select(pk, asRaw, tx);
|
|
11801
11955
|
}
|
|
@@ -63,6 +63,13 @@ export declare class Dataply {
|
|
|
63
63
|
* @param tx Transaction
|
|
64
64
|
*/
|
|
65
65
|
delete(pk: number, tx?: Transaction): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Deletes multiple data in batch.
|
|
68
|
+
* If a transaction is not provided, it internally creates a single transaction to process.
|
|
69
|
+
* @param pks Array of PKs to delete
|
|
70
|
+
* @param tx Transaction
|
|
71
|
+
*/
|
|
72
|
+
deleteBatch(pks: number[], tx?: Transaction): Promise<void>;
|
|
66
73
|
/**
|
|
67
74
|
* Selects data.
|
|
68
75
|
* @param pk PK of the data to select
|
|
@@ -162,6 +162,14 @@ export declare class DataplyAPI {
|
|
|
162
162
|
* @param tx Transaction
|
|
163
163
|
*/
|
|
164
164
|
delete(pk: number, decrementRowCount?: boolean, tx?: Transaction): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Deletes multiple data in batch.
|
|
167
|
+
* If a transaction is not provided, it internally creates a single transaction to process.
|
|
168
|
+
* @param pks Array of PKs to delete
|
|
169
|
+
* @param decrementRowCount Whether to decrement the row count to metadata
|
|
170
|
+
* @param tx Transaction
|
|
171
|
+
*/
|
|
172
|
+
deleteBatch(pks: number[], decrementRowCount?: boolean, tx?: Transaction): Promise<void>;
|
|
165
173
|
/**
|
|
166
174
|
* Selects data.
|
|
167
175
|
* @param pk PK of the data to select
|
|
@@ -111,6 +111,13 @@ export declare class RowTableEngine {
|
|
|
111
111
|
* @param tx Transaction
|
|
112
112
|
*/
|
|
113
113
|
delete(pk: number, decrementRowCount: boolean, tx: Transaction): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Deletes multiple data in batch.
|
|
116
|
+
* @param pks Array of PKs to delete
|
|
117
|
+
* @param decrementRowCount Whether to decrement the row count to metadata
|
|
118
|
+
* @param tx Transaction
|
|
119
|
+
*/
|
|
120
|
+
deleteBatch(pks: number[], decrementRowCount: boolean, tx: Transaction): Promise<void>;
|
|
114
121
|
/**
|
|
115
122
|
* Looks up the RID corresponding to the PK in the B+ Tree and returns the actual row.
|
|
116
123
|
* @param pk Primary key of the row
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataply",
|
|
3
|
-
"version": "0.0.26-alpha.
|
|
3
|
+
"version": "0.0.26-alpha.15",
|
|
4
4
|
"description": "A lightweight storage engine for Node.js with support for MVCC, WAL.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "izure <admin@izure.org>",
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"hookall": "^2.2.0",
|
|
50
50
|
"mvcc-api": "^1.3.7",
|
|
51
51
|
"ryoiki": "^1.2.0",
|
|
52
|
-
"serializable-bptree": "^9.0.4-alpha.
|
|
52
|
+
"serializable-bptree": "^9.0.4-alpha.3"
|
|
53
53
|
}
|
|
54
54
|
}
|