serializable-bptree 7.0.0 → 7.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
CHANGED
|
@@ -475,6 +475,20 @@ var BPTree = class _BPTree {
|
|
|
475
475
|
option;
|
|
476
476
|
order;
|
|
477
477
|
rootId;
|
|
478
|
+
/**
|
|
479
|
+
* Returns the ID of the root node.
|
|
480
|
+
* @returns The root node ID.
|
|
481
|
+
*/
|
|
482
|
+
getRootId() {
|
|
483
|
+
return this.rootId;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Returns the order of the B+Tree.
|
|
487
|
+
* @returns The order of the tree.
|
|
488
|
+
*/
|
|
489
|
+
getOrder() {
|
|
490
|
+
return this.order;
|
|
491
|
+
}
|
|
478
492
|
_strategyDirty;
|
|
479
493
|
_nodeCreateBuffer;
|
|
480
494
|
_nodeUpdateBuffer;
|
|
@@ -707,24 +721,21 @@ var BPTree = class _BPTree {
|
|
|
707
721
|
break;
|
|
708
722
|
}
|
|
709
723
|
keys.push(key);
|
|
710
|
-
this.bufferForNodeUpdate(node);
|
|
711
|
-
break;
|
|
724
|
+
return this.bufferForNodeUpdate(node);
|
|
712
725
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
713
726
|
node.values.splice(i, 0, value);
|
|
714
727
|
node.keys.splice(i, 0, [key]);
|
|
715
|
-
this.bufferForNodeUpdate(node);
|
|
716
|
-
break;
|
|
728
|
+
return this.bufferForNodeUpdate(node);
|
|
717
729
|
} else if (i + 1 === node.values.length) {
|
|
718
730
|
node.values.push(value);
|
|
719
731
|
node.keys.push([key]);
|
|
720
|
-
this.bufferForNodeUpdate(node);
|
|
721
|
-
break;
|
|
732
|
+
return this.bufferForNodeUpdate(node);
|
|
722
733
|
}
|
|
723
734
|
}
|
|
724
735
|
} else {
|
|
725
736
|
node.values = [value];
|
|
726
737
|
node.keys = [[key]];
|
|
727
|
-
this.bufferForNodeUpdate(node);
|
|
738
|
+
return this.bufferForNodeUpdate(node);
|
|
728
739
|
}
|
|
729
740
|
}
|
|
730
741
|
bufferForNodeCreate(node) {
|
|
@@ -840,7 +851,7 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
840
851
|
}
|
|
841
852
|
return id;
|
|
842
853
|
}
|
|
843
|
-
_createNode(isLeaf, keys, values, leaf =
|
|
854
|
+
_createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
844
855
|
const id = this._createNodeId(isLeaf);
|
|
845
856
|
const node = {
|
|
846
857
|
id,
|
|
@@ -851,26 +862,23 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
851
862
|
next,
|
|
852
863
|
prev
|
|
853
864
|
};
|
|
854
|
-
this.
|
|
865
|
+
this.bufferForNodeCreate(node);
|
|
855
866
|
return node;
|
|
856
867
|
}
|
|
857
868
|
_deleteEntry(node, key, value) {
|
|
858
869
|
if (!node.leaf) {
|
|
870
|
+
let keyIndex = -1;
|
|
859
871
|
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
node.keys.splice(i, 1);
|
|
863
|
-
this.bufferForNodeUpdate(node);
|
|
872
|
+
if (node.keys[i] === key) {
|
|
873
|
+
keyIndex = i;
|
|
864
874
|
break;
|
|
865
875
|
}
|
|
866
876
|
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
break;
|
|
873
|
-
}
|
|
877
|
+
if (keyIndex !== -1) {
|
|
878
|
+
node.keys.splice(keyIndex, 1);
|
|
879
|
+
const valueIndex = keyIndex > 0 ? keyIndex - 1 : 0;
|
|
880
|
+
node.values.splice(valueIndex, 1);
|
|
881
|
+
this.bufferForNodeUpdate(node);
|
|
874
882
|
}
|
|
875
883
|
}
|
|
876
884
|
if (this.rootId === node.id && node.keys.length === 1 && !node.leaf) {
|
|
@@ -970,13 +978,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
970
978
|
node.keys = [pointerPm, ...node.keys];
|
|
971
979
|
node.values = [guess, ...node.values];
|
|
972
980
|
parentNode = this.getNode(node.parent);
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
this.bufferForNodeUpdate(parentNode);
|
|
978
|
-
break;
|
|
979
|
-
}
|
|
981
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
982
|
+
if (nodeIndex > 0) {
|
|
983
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
984
|
+
this.bufferForNodeUpdate(parentNode);
|
|
980
985
|
}
|
|
981
986
|
} else {
|
|
982
987
|
pointerPm = pointer.keys.splice(-1)[0];
|
|
@@ -984,13 +989,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
984
989
|
node.keys = [pointerPm, ...node.keys];
|
|
985
990
|
node.values = [pointerKm, ...node.values];
|
|
986
991
|
parentNode = this.getNode(node.parent);
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
this.bufferForNodeUpdate(parentNode);
|
|
992
|
-
break;
|
|
993
|
-
}
|
|
992
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
993
|
+
if (nodeIndex > 0) {
|
|
994
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
995
|
+
this.bufferForNodeUpdate(parentNode);
|
|
994
996
|
}
|
|
995
997
|
}
|
|
996
998
|
this.bufferForNodeUpdate(node);
|
|
@@ -1004,13 +1006,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1004
1006
|
node.keys = [...node.keys, pointerP0];
|
|
1005
1007
|
node.values = [...node.values, guess];
|
|
1006
1008
|
parentNode = this.getNode(node.parent);
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
this.bufferForNodeUpdate(parentNode);
|
|
1012
|
-
break;
|
|
1013
|
-
}
|
|
1009
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
1010
|
+
if (pointerIndex > 0) {
|
|
1011
|
+
parentNode.values[pointerIndex - 1] = pointerK0;
|
|
1012
|
+
this.bufferForNodeUpdate(parentNode);
|
|
1014
1013
|
}
|
|
1015
1014
|
} else {
|
|
1016
1015
|
pointerP0 = pointer.keys.splice(0, 1)[0];
|
|
@@ -1018,13 +1017,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1018
1017
|
node.keys = [...node.keys, pointerP0];
|
|
1019
1018
|
node.values = [...node.values, pointerK0];
|
|
1020
1019
|
parentNode = this.getNode(node.parent);
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
this.bufferForNodeUpdate(parentNode);
|
|
1026
|
-
break;
|
|
1027
|
-
}
|
|
1020
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
1021
|
+
if (pointerIndex > 0) {
|
|
1022
|
+
parentNode.values[pointerIndex - 1] = pointer.values[0];
|
|
1023
|
+
this.bufferForNodeUpdate(parentNode);
|
|
1028
1024
|
}
|
|
1029
1025
|
}
|
|
1030
1026
|
this.bufferForNodeUpdate(node);
|
|
@@ -1052,6 +1048,8 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1052
1048
|
}
|
|
1053
1049
|
}
|
|
1054
1050
|
}
|
|
1051
|
+
} else {
|
|
1052
|
+
this.bufferForNodeUpdate(node);
|
|
1055
1053
|
}
|
|
1056
1054
|
}
|
|
1057
1055
|
_insertInParent(node, value, pointer) {
|
|
@@ -1070,31 +1068,25 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1070
1068
|
return;
|
|
1071
1069
|
}
|
|
1072
1070
|
const parentNode = this.getNode(node.parent);
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
insertIndex = i + 1;
|
|
1077
|
-
} else {
|
|
1078
|
-
break;
|
|
1079
|
-
}
|
|
1071
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
1072
|
+
if (nodeIndex === -1) {
|
|
1073
|
+
throw new Error(`Node ${node.id} not found in parent ${parentNode.id}`);
|
|
1080
1074
|
}
|
|
1075
|
+
const insertIndex = nodeIndex;
|
|
1081
1076
|
parentNode.values.splice(insertIndex, 0, value);
|
|
1082
1077
|
parentNode.keys.splice(insertIndex + 1, 0, pointer.id);
|
|
1083
1078
|
pointer.parent = parentNode.id;
|
|
1084
1079
|
if (pointer.leaf) {
|
|
1085
|
-
const
|
|
1086
|
-
const
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
this.
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
const rightSibling = this.getNode(rightSiblingId);
|
|
1096
|
-
rightSibling.prev = pointer.id;
|
|
1097
|
-
this.bufferForNodeUpdate(rightSibling);
|
|
1080
|
+
const leftSibling = node;
|
|
1081
|
+
const oldNextId = leftSibling.next;
|
|
1082
|
+
pointer.prev = leftSibling.id;
|
|
1083
|
+
pointer.next = oldNextId;
|
|
1084
|
+
leftSibling.next = pointer.id;
|
|
1085
|
+
this.bufferForNodeUpdate(leftSibling);
|
|
1086
|
+
if (oldNextId) {
|
|
1087
|
+
const oldNext = this.getNode(oldNextId);
|
|
1088
|
+
oldNext.prev = pointer.id;
|
|
1089
|
+
this.bufferForNodeUpdate(oldNext);
|
|
1098
1090
|
}
|
|
1099
1091
|
}
|
|
1100
1092
|
this.bufferForNodeUpdate(parentNode);
|
|
@@ -1123,6 +1115,7 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1123
1115
|
}
|
|
1124
1116
|
}
|
|
1125
1117
|
init() {
|
|
1118
|
+
this.clear();
|
|
1126
1119
|
const head = this.strategy.readHead();
|
|
1127
1120
|
if (head === null) {
|
|
1128
1121
|
this.order = this.strategy.order;
|
|
@@ -1153,18 +1146,35 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1153
1146
|
}
|
|
1154
1147
|
insertableNode(value) {
|
|
1155
1148
|
let node = this.getNode(this.rootId);
|
|
1149
|
+
if (node.parent !== null) {
|
|
1150
|
+
node.parent = null;
|
|
1151
|
+
this.bufferForNodeUpdate(node);
|
|
1152
|
+
}
|
|
1156
1153
|
while (!node.leaf) {
|
|
1154
|
+
const parentId = node.id;
|
|
1157
1155
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1158
1156
|
const nValue = node.values[i];
|
|
1159
1157
|
const k = node.keys;
|
|
1160
1158
|
if (this.comparator.isSame(value, nValue)) {
|
|
1161
1159
|
node = this.getNode(k[i + 1]);
|
|
1160
|
+
if (node.parent !== parentId) {
|
|
1161
|
+
node.parent = parentId;
|
|
1162
|
+
this.bufferForNodeUpdate(node);
|
|
1163
|
+
}
|
|
1162
1164
|
break;
|
|
1163
1165
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
1164
1166
|
node = this.getNode(k[i]);
|
|
1167
|
+
if (node.parent !== parentId) {
|
|
1168
|
+
node.parent = parentId;
|
|
1169
|
+
this.bufferForNodeUpdate(node);
|
|
1170
|
+
}
|
|
1165
1171
|
break;
|
|
1166
1172
|
} else if (i + 1 === node.values.length) {
|
|
1167
1173
|
node = this.getNode(k[i + 1]);
|
|
1174
|
+
if (node.parent !== parentId) {
|
|
1175
|
+
node.parent = parentId;
|
|
1176
|
+
this.bufferForNodeUpdate(node);
|
|
1177
|
+
}
|
|
1168
1178
|
break;
|
|
1169
1179
|
}
|
|
1170
1180
|
}
|
|
@@ -1173,18 +1183,35 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1173
1183
|
}
|
|
1174
1184
|
insertableNodeByPrimary(value) {
|
|
1175
1185
|
let node = this.getNode(this.rootId);
|
|
1186
|
+
if (node.parent !== null) {
|
|
1187
|
+
node.parent = null;
|
|
1188
|
+
this.bufferForNodeUpdate(node);
|
|
1189
|
+
}
|
|
1176
1190
|
while (!node.leaf) {
|
|
1191
|
+
const parentId = node.id;
|
|
1177
1192
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1178
1193
|
const nValue = node.values[i];
|
|
1179
1194
|
const k = node.keys;
|
|
1180
1195
|
if (this.comparator.isPrimarySame(value, nValue)) {
|
|
1181
1196
|
node = this.getNode(k[i]);
|
|
1197
|
+
if (node.parent !== parentId) {
|
|
1198
|
+
node.parent = parentId;
|
|
1199
|
+
this.bufferForNodeUpdate(node);
|
|
1200
|
+
}
|
|
1182
1201
|
break;
|
|
1183
1202
|
} else if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
1184
1203
|
node = this.getNode(k[i]);
|
|
1204
|
+
if (node.parent !== parentId) {
|
|
1205
|
+
node.parent = parentId;
|
|
1206
|
+
this.bufferForNodeUpdate(node);
|
|
1207
|
+
}
|
|
1185
1208
|
break;
|
|
1186
1209
|
} else if (i + 1 === node.values.length) {
|
|
1187
1210
|
node = this.getNode(k[i + 1]);
|
|
1211
|
+
if (node.parent !== parentId) {
|
|
1212
|
+
node.parent = parentId;
|
|
1213
|
+
this.bufferForNodeUpdate(node);
|
|
1214
|
+
}
|
|
1188
1215
|
break;
|
|
1189
1216
|
}
|
|
1190
1217
|
}
|
|
@@ -1193,16 +1220,29 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1193
1220
|
}
|
|
1194
1221
|
insertableRightestNodeByPrimary(value) {
|
|
1195
1222
|
let node = this.getNode(this.rootId);
|
|
1223
|
+
if (node.parent !== null) {
|
|
1224
|
+
node.parent = null;
|
|
1225
|
+
this.bufferForNodeUpdate(node);
|
|
1226
|
+
}
|
|
1196
1227
|
while (!node.leaf) {
|
|
1228
|
+
const parentId = node.id;
|
|
1197
1229
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1198
1230
|
const nValue = node.values[i];
|
|
1199
1231
|
const k = node.keys;
|
|
1200
1232
|
if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
1201
1233
|
node = this.getNode(k[i]);
|
|
1234
|
+
if (node.parent !== parentId) {
|
|
1235
|
+
node.parent = parentId;
|
|
1236
|
+
this.bufferForNodeUpdate(node);
|
|
1237
|
+
}
|
|
1202
1238
|
break;
|
|
1203
1239
|
}
|
|
1204
1240
|
if (i + 1 === node.values.length) {
|
|
1205
1241
|
node = this.getNode(k[i + 1]);
|
|
1242
|
+
if (node.parent !== parentId) {
|
|
1243
|
+
node.parent = parentId;
|
|
1244
|
+
this.bufferForNodeUpdate(node);
|
|
1245
|
+
}
|
|
1206
1246
|
break;
|
|
1207
1247
|
}
|
|
1208
1248
|
}
|
|
@@ -1237,17 +1277,35 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1237
1277
|
}
|
|
1238
1278
|
leftestNode() {
|
|
1239
1279
|
let node = this.getNode(this.rootId);
|
|
1280
|
+
if (node.parent !== null) {
|
|
1281
|
+
node.parent = null;
|
|
1282
|
+
this.bufferForNodeUpdate(node);
|
|
1283
|
+
}
|
|
1240
1284
|
while (!node.leaf) {
|
|
1285
|
+
const parentId = node.id;
|
|
1241
1286
|
const keys = node.keys;
|
|
1242
1287
|
node = this.getNode(keys[0]);
|
|
1288
|
+
if (node.parent !== parentId) {
|
|
1289
|
+
node.parent = parentId;
|
|
1290
|
+
this.bufferForNodeUpdate(node);
|
|
1291
|
+
}
|
|
1243
1292
|
}
|
|
1244
1293
|
return node;
|
|
1245
1294
|
}
|
|
1246
1295
|
rightestNode() {
|
|
1247
1296
|
let node = this.getNode(this.rootId);
|
|
1297
|
+
if (node.parent !== null) {
|
|
1298
|
+
node.parent = null;
|
|
1299
|
+
this.bufferForNodeUpdate(node);
|
|
1300
|
+
}
|
|
1248
1301
|
while (!node.leaf) {
|
|
1302
|
+
const parentId = node.id;
|
|
1249
1303
|
const keys = node.keys;
|
|
1250
1304
|
node = this.getNode(keys[keys.length - 1]);
|
|
1305
|
+
if (node.parent !== parentId) {
|
|
1306
|
+
node.parent = parentId;
|
|
1307
|
+
this.bufferForNodeUpdate(node);
|
|
1308
|
+
}
|
|
1251
1309
|
}
|
|
1252
1310
|
return node;
|
|
1253
1311
|
}
|
|
@@ -1586,23 +1644,37 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1586
1644
|
realBaseTree;
|
|
1587
1645
|
realBaseStrategy;
|
|
1588
1646
|
txNodes = /* @__PURE__ */ new Map();
|
|
1589
|
-
dirtyIds
|
|
1590
|
-
createdInTx
|
|
1647
|
+
dirtyIds;
|
|
1648
|
+
createdInTx;
|
|
1649
|
+
deletedIds;
|
|
1591
1650
|
initialRootId;
|
|
1592
1651
|
transactionRootId;
|
|
1593
1652
|
constructor(baseTree) {
|
|
1594
1653
|
super(baseTree.strategy, baseTree.comparator, baseTree.option);
|
|
1595
1654
|
this.realBaseTree = baseTree;
|
|
1596
1655
|
this.realBaseStrategy = baseTree.strategy;
|
|
1656
|
+
this.order = baseTree.getOrder();
|
|
1597
1657
|
this.initialRootId = "";
|
|
1598
1658
|
this.transactionRootId = "";
|
|
1659
|
+
this.dirtyIds = /* @__PURE__ */ new Set();
|
|
1660
|
+
this.createdInTx = /* @__PURE__ */ new Set();
|
|
1661
|
+
this.deletedIds = /* @__PURE__ */ new Set();
|
|
1599
1662
|
}
|
|
1600
1663
|
/**
|
|
1601
1664
|
* Initializes the transaction by capturing the current state of the tree.
|
|
1602
1665
|
*/
|
|
1603
1666
|
initTransaction() {
|
|
1604
1667
|
const head = this.realBaseStrategy.readHead();
|
|
1605
|
-
|
|
1668
|
+
if (head) {
|
|
1669
|
+
this.order = head.order;
|
|
1670
|
+
this.initialRootId = head.root;
|
|
1671
|
+
} else {
|
|
1672
|
+
this.initialRootId = this.realBaseTree.getRootId();
|
|
1673
|
+
}
|
|
1674
|
+
if (!this.initialRootId) {
|
|
1675
|
+
const root = this._createNode(true, [], [], true);
|
|
1676
|
+
this.initialRootId = root.id;
|
|
1677
|
+
}
|
|
1606
1678
|
this.transactionRootId = this.initialRootId;
|
|
1607
1679
|
this.rootId = this.transactionRootId;
|
|
1608
1680
|
const snapshotStrategy = new BPTreeSyncSnapshotStrategy(this.realBaseStrategy, this.initialRootId);
|
|
@@ -1610,34 +1682,76 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1610
1682
|
this.txNodes.clear();
|
|
1611
1683
|
this.dirtyIds.clear();
|
|
1612
1684
|
this.createdInTx.clear();
|
|
1685
|
+
this.deletedIds.clear();
|
|
1613
1686
|
}
|
|
1614
1687
|
getNode(id) {
|
|
1615
1688
|
if (this.txNodes.has(id)) {
|
|
1616
1689
|
return this.txNodes.get(id);
|
|
1617
1690
|
}
|
|
1691
|
+
if (this.deletedIds.has(id)) {
|
|
1692
|
+
throw new Error(`The tree attempted to reference deleted node '${id}'`);
|
|
1693
|
+
}
|
|
1618
1694
|
const baseNode = this.realBaseStrategy.read(id);
|
|
1619
1695
|
const clone = JSON.parse(JSON.stringify(baseNode));
|
|
1620
1696
|
this.txNodes.set(id, clone);
|
|
1621
1697
|
return clone;
|
|
1622
1698
|
}
|
|
1623
1699
|
bufferForNodeUpdate(node) {
|
|
1700
|
+
if (this.dirtyIds.has(node.id) && this.txNodes.has(node.id) && node._p) {
|
|
1701
|
+
this.txNodes.set(node.id, node);
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
node._p = true;
|
|
1624
1705
|
this.txNodes.set(node.id, node);
|
|
1625
1706
|
this.dirtyIds.add(node.id);
|
|
1707
|
+
if (node.leaf) {
|
|
1708
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
1709
|
+
try {
|
|
1710
|
+
this.bufferForNodeUpdate(this.getNode(node.next));
|
|
1711
|
+
} catch (e) {
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
1715
|
+
try {
|
|
1716
|
+
this.bufferForNodeUpdate(this.getNode(node.prev));
|
|
1717
|
+
} catch (e) {
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1626
1721
|
this.markPathDirty(node);
|
|
1722
|
+
delete node._p;
|
|
1627
1723
|
}
|
|
1628
1724
|
bufferForNodeCreate(node) {
|
|
1629
1725
|
this.txNodes.set(node.id, node);
|
|
1630
1726
|
this.dirtyIds.add(node.id);
|
|
1631
1727
|
this.createdInTx.add(node.id);
|
|
1728
|
+
if (node.leaf) {
|
|
1729
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
1730
|
+
try {
|
|
1731
|
+
this.bufferForNodeUpdate(this.getNode(node.next));
|
|
1732
|
+
} catch (e) {
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
1736
|
+
try {
|
|
1737
|
+
this.bufferForNodeUpdate(this.getNode(node.prev));
|
|
1738
|
+
} catch (e) {
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1632
1742
|
this.markPathDirty(node);
|
|
1633
1743
|
}
|
|
1634
1744
|
bufferForNodeDelete(node) {
|
|
1635
1745
|
this.txNodes.delete(node.id);
|
|
1636
1746
|
this.dirtyIds.add(node.id);
|
|
1747
|
+
this.deletedIds.add(node.id);
|
|
1637
1748
|
}
|
|
1638
1749
|
markPathDirty(node) {
|
|
1639
1750
|
let curr = node;
|
|
1640
1751
|
while (curr.parent) {
|
|
1752
|
+
if (this.deletedIds.has(curr.parent)) {
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1641
1755
|
if (this.dirtyIds.has(curr.parent) && this.txNodes.has(curr.parent)) {
|
|
1642
1756
|
break;
|
|
1643
1757
|
}
|
|
@@ -1649,13 +1763,13 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1649
1763
|
this.transactionRootId = curr.id;
|
|
1650
1764
|
}
|
|
1651
1765
|
}
|
|
1652
|
-
_createNode(isLeaf, keys, values, leaf =
|
|
1653
|
-
const id = this.
|
|
1766
|
+
_createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
1767
|
+
const id = this.strategy.id(isLeaf);
|
|
1654
1768
|
const node = {
|
|
1655
1769
|
id,
|
|
1656
1770
|
keys,
|
|
1657
1771
|
values,
|
|
1658
|
-
leaf
|
|
1772
|
+
leaf,
|
|
1659
1773
|
parent,
|
|
1660
1774
|
next,
|
|
1661
1775
|
prev
|
|
@@ -1713,9 +1827,9 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1713
1827
|
finalNodes.push(node);
|
|
1714
1828
|
newCreatedIds.push(newId);
|
|
1715
1829
|
}
|
|
1716
|
-
let newRootId = this.
|
|
1717
|
-
if (idMapping.has(this.
|
|
1718
|
-
newRootId = idMapping.get(this.
|
|
1830
|
+
let newRootId = this.rootId;
|
|
1831
|
+
if (idMapping.has(this.rootId)) {
|
|
1832
|
+
newRootId = idMapping.get(this.rootId);
|
|
1719
1833
|
}
|
|
1720
1834
|
for (const node of finalNodes) {
|
|
1721
1835
|
this.realBaseStrategy.write(node.id, node);
|
|
@@ -1766,6 +1880,7 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1766
1880
|
var BPTreeSync = class extends BPTreeSyncBase {
|
|
1767
1881
|
constructor(strategy, comparator, option) {
|
|
1768
1882
|
super(strategy, comparator, option);
|
|
1883
|
+
this.init();
|
|
1769
1884
|
}
|
|
1770
1885
|
/**
|
|
1771
1886
|
* Creates a new synchronous transaction.
|
|
@@ -1873,7 +1988,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1873
1988
|
}
|
|
1874
1989
|
return id;
|
|
1875
1990
|
}
|
|
1876
|
-
async _createNode(isLeaf, keys, values, leaf =
|
|
1991
|
+
async _createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
1877
1992
|
const id = await this._createNodeId(isLeaf);
|
|
1878
1993
|
const node = {
|
|
1879
1994
|
id,
|
|
@@ -1884,40 +1999,37 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1884
1999
|
next,
|
|
1885
2000
|
prev
|
|
1886
2001
|
};
|
|
1887
|
-
this.
|
|
2002
|
+
await this.bufferForNodeCreate(node);
|
|
1888
2003
|
return node;
|
|
1889
2004
|
}
|
|
1890
2005
|
async _deleteEntry(node, key, value) {
|
|
1891
2006
|
if (!node.leaf) {
|
|
2007
|
+
let keyIndex = -1;
|
|
1892
2008
|
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
node.keys.splice(i, 1);
|
|
1896
|
-
this.bufferForNodeUpdate(node);
|
|
2009
|
+
if (node.keys[i] === key) {
|
|
2010
|
+
keyIndex = i;
|
|
1897
2011
|
break;
|
|
1898
2012
|
}
|
|
1899
2013
|
}
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
break;
|
|
1906
|
-
}
|
|
2014
|
+
if (keyIndex !== -1) {
|
|
2015
|
+
node.keys.splice(keyIndex, 1);
|
|
2016
|
+
const valueIndex = keyIndex > 0 ? keyIndex - 1 : 0;
|
|
2017
|
+
node.values.splice(valueIndex, 1);
|
|
2018
|
+
await this.bufferForNodeUpdate(node);
|
|
1907
2019
|
}
|
|
1908
2020
|
}
|
|
1909
2021
|
if (this.rootId === node.id && node.keys.length === 1 && !node.leaf) {
|
|
1910
2022
|
const keys = node.keys;
|
|
1911
|
-
this.bufferForNodeDelete(node);
|
|
2023
|
+
await this.bufferForNodeDelete(node);
|
|
1912
2024
|
const newRoot = await this.getNode(keys[0]);
|
|
1913
2025
|
this.rootId = newRoot.id;
|
|
1914
2026
|
newRoot.parent = null;
|
|
1915
2027
|
this.strategy.head.root = this.rootId;
|
|
1916
|
-
this.bufferForNodeUpdate(newRoot);
|
|
2028
|
+
await this.bufferForNodeUpdate(newRoot);
|
|
1917
2029
|
return;
|
|
1918
2030
|
} else if (this.rootId === node.id) {
|
|
1919
2031
|
const root = await this.getNode(this.rootId);
|
|
1920
|
-
this.bufferForNodeUpdate(root);
|
|
2032
|
+
await this.bufferForNodeUpdate(root);
|
|
1921
2033
|
return;
|
|
1922
2034
|
} else if (node.keys.length < Math.ceil(this.order / 2) && !node.leaf || node.values.length < Math.ceil((this.order - 1) / 2) && node.leaf) {
|
|
1923
2035
|
if (node.parent === null) {
|
|
@@ -1978,7 +2090,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1978
2090
|
if (pointer.next) {
|
|
1979
2091
|
const n = await this.getNode(pointer.next);
|
|
1980
2092
|
n.prev = pointer.id;
|
|
1981
|
-
this.bufferForNodeUpdate(n);
|
|
2093
|
+
await this.bufferForNodeUpdate(n);
|
|
1982
2094
|
}
|
|
1983
2095
|
}
|
|
1984
2096
|
pointer.values.push(...node.values);
|
|
@@ -1987,12 +2099,12 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1987
2099
|
for (const key2 of keys) {
|
|
1988
2100
|
const n = await this.getNode(key2);
|
|
1989
2101
|
n.parent = pointer.id;
|
|
1990
|
-
this.bufferForNodeUpdate(n);
|
|
2102
|
+
await this.bufferForNodeUpdate(n);
|
|
1991
2103
|
}
|
|
1992
2104
|
}
|
|
1993
2105
|
await this._deleteEntry(await this.getNode(node.parent), node.id, guess);
|
|
1994
|
-
this.bufferForNodeUpdate(pointer);
|
|
1995
|
-
this.bufferForNodeDelete(node);
|
|
2106
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2107
|
+
await this.bufferForNodeDelete(node);
|
|
1996
2108
|
} else {
|
|
1997
2109
|
if (isPredecessor) {
|
|
1998
2110
|
let pointerPm;
|
|
@@ -2003,13 +2115,10 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2003
2115
|
node.keys = [pointerPm, ...node.keys];
|
|
2004
2116
|
node.values = [guess, ...node.values];
|
|
2005
2117
|
parentNode = await this.getNode(node.parent);
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2011
|
-
break;
|
|
2012
|
-
}
|
|
2118
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
2119
|
+
if (nodeIndex > 0) {
|
|
2120
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
2121
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2013
2122
|
}
|
|
2014
2123
|
} else {
|
|
2015
2124
|
pointerPm = pointer.keys.splice(-1)[0];
|
|
@@ -2017,17 +2126,14 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2017
2126
|
node.keys = [pointerPm, ...node.keys];
|
|
2018
2127
|
node.values = [pointerKm, ...node.values];
|
|
2019
2128
|
parentNode = await this.getNode(node.parent);
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2025
|
-
break;
|
|
2026
|
-
}
|
|
2129
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
2130
|
+
if (nodeIndex > 0) {
|
|
2131
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
2132
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2027
2133
|
}
|
|
2028
2134
|
}
|
|
2029
|
-
this.bufferForNodeUpdate(node);
|
|
2030
|
-
this.bufferForNodeUpdate(pointer);
|
|
2135
|
+
await this.bufferForNodeUpdate(node);
|
|
2136
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2031
2137
|
} else {
|
|
2032
2138
|
let pointerP0;
|
|
2033
2139
|
let pointerK0;
|
|
@@ -2037,13 +2143,10 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2037
2143
|
node.keys = [...node.keys, pointerP0];
|
|
2038
2144
|
node.values = [...node.values, guess];
|
|
2039
2145
|
parentNode = await this.getNode(node.parent);
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2045
|
-
break;
|
|
2046
|
-
}
|
|
2146
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
2147
|
+
if (pointerIndex > 0) {
|
|
2148
|
+
parentNode.values[pointerIndex - 1] = pointerK0;
|
|
2149
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2047
2150
|
}
|
|
2048
2151
|
} else {
|
|
2049
2152
|
pointerP0 = pointer.keys.splice(0, 1)[0];
|
|
@@ -2051,24 +2154,21 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2051
2154
|
node.keys = [...node.keys, pointerP0];
|
|
2052
2155
|
node.values = [...node.values, pointerK0];
|
|
2053
2156
|
parentNode = await this.getNode(node.parent);
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2059
|
-
break;
|
|
2060
|
-
}
|
|
2157
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
2158
|
+
if (pointerIndex > 0) {
|
|
2159
|
+
parentNode.values[pointerIndex - 1] = pointer.values[0];
|
|
2160
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2061
2161
|
}
|
|
2062
2162
|
}
|
|
2063
|
-
this.bufferForNodeUpdate(node);
|
|
2064
|
-
this.bufferForNodeUpdate(pointer);
|
|
2163
|
+
await this.bufferForNodeUpdate(node);
|
|
2164
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2065
2165
|
}
|
|
2066
2166
|
if (!pointer.leaf) {
|
|
2067
2167
|
const keys = pointer.keys;
|
|
2068
2168
|
for (const key2 of keys) {
|
|
2069
2169
|
const n = await this.getNode(key2);
|
|
2070
2170
|
n.parent = pointer.id;
|
|
2071
|
-
this.bufferForNodeUpdate(n);
|
|
2171
|
+
await this.bufferForNodeUpdate(n);
|
|
2072
2172
|
}
|
|
2073
2173
|
}
|
|
2074
2174
|
if (!node.leaf) {
|
|
@@ -2076,7 +2176,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2076
2176
|
for (const key2 of keys) {
|
|
2077
2177
|
const n = await this.getNode(key2);
|
|
2078
2178
|
n.parent = node.id;
|
|
2079
|
-
this.bufferForNodeUpdate(n);
|
|
2179
|
+
await this.bufferForNodeUpdate(n);
|
|
2080
2180
|
}
|
|
2081
2181
|
}
|
|
2082
2182
|
if (!parentNode.leaf) {
|
|
@@ -2084,10 +2184,12 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2084
2184
|
for (const key2 of keys) {
|
|
2085
2185
|
const n = await this.getNode(key2);
|
|
2086
2186
|
n.parent = parentNode.id;
|
|
2087
|
-
this.bufferForNodeUpdate(n);
|
|
2187
|
+
await this.bufferForNodeUpdate(n);
|
|
2088
2188
|
}
|
|
2089
2189
|
}
|
|
2090
2190
|
}
|
|
2191
|
+
} else {
|
|
2192
|
+
await this.bufferForNodeUpdate(node);
|
|
2091
2193
|
}
|
|
2092
2194
|
}
|
|
2093
2195
|
async _insertInParent(node, value, pointer) {
|
|
@@ -2098,43 +2200,39 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2098
2200
|
node.parent = root.id;
|
|
2099
2201
|
pointer.parent = root.id;
|
|
2100
2202
|
if (pointer.leaf) {
|
|
2101
|
-
|
|
2102
|
-
|
|
2203
|
+
const nNode = node;
|
|
2204
|
+
nNode.next = pointer.id;
|
|
2205
|
+
const nPointer = pointer;
|
|
2206
|
+
nPointer.prev = node.id;
|
|
2103
2207
|
}
|
|
2104
|
-
this.bufferForNodeUpdate(node);
|
|
2105
|
-
this.bufferForNodeUpdate(pointer);
|
|
2208
|
+
await this.bufferForNodeUpdate(node);
|
|
2209
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2106
2210
|
return;
|
|
2107
2211
|
}
|
|
2108
2212
|
const parentNode = await this.getNode(node.parent);
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
insertIndex = i + 1;
|
|
2113
|
-
} else {
|
|
2114
|
-
break;
|
|
2115
|
-
}
|
|
2213
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
2214
|
+
if (nodeIndex === -1) {
|
|
2215
|
+
throw new Error(`Node ${node.id} not found in parent ${parentNode.id}`);
|
|
2116
2216
|
}
|
|
2217
|
+
const insertIndex = nodeIndex;
|
|
2117
2218
|
parentNode.values.splice(insertIndex, 0, value);
|
|
2118
2219
|
parentNode.keys.splice(insertIndex + 1, 0, pointer.id);
|
|
2119
2220
|
pointer.parent = parentNode.id;
|
|
2120
2221
|
if (pointer.leaf) {
|
|
2121
|
-
const
|
|
2122
|
-
const
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
this.
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
}
|
|
2136
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2137
|
-
this.bufferForNodeUpdate(pointer);
|
|
2222
|
+
const leftSibling = node;
|
|
2223
|
+
const oldNextId = leftSibling.next;
|
|
2224
|
+
pointer.prev = leftSibling.id;
|
|
2225
|
+
pointer.next = oldNextId;
|
|
2226
|
+
leftSibling.next = pointer.id;
|
|
2227
|
+
await this.bufferForNodeUpdate(leftSibling);
|
|
2228
|
+
if (oldNextId) {
|
|
2229
|
+
const oldNext = await this.getNode(oldNextId);
|
|
2230
|
+
oldNext.prev = pointer.id;
|
|
2231
|
+
await this.bufferForNodeUpdate(oldNext);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2235
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2138
2236
|
if (parentNode.keys.length > this.order) {
|
|
2139
2237
|
const parentPointer = await this._createNode(false, [], []);
|
|
2140
2238
|
parentPointer.parent = parentNode.parent;
|
|
@@ -2147,18 +2245,19 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2147
2245
|
for (const k of parentNode.keys) {
|
|
2148
2246
|
const n = await this.getNode(k);
|
|
2149
2247
|
n.parent = parentNode.id;
|
|
2150
|
-
this.bufferForNodeUpdate(n);
|
|
2248
|
+
await this.bufferForNodeUpdate(n);
|
|
2151
2249
|
}
|
|
2152
2250
|
for (const k of parentPointer.keys) {
|
|
2153
2251
|
const n = await this.getNode(k);
|
|
2154
2252
|
n.parent = parentPointer.id;
|
|
2155
|
-
this.bufferForNodeUpdate(n);
|
|
2253
|
+
await this.bufferForNodeUpdate(n);
|
|
2156
2254
|
}
|
|
2157
2255
|
await this._insertInParent(parentNode, midValue, parentPointer);
|
|
2158
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2256
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2159
2257
|
}
|
|
2160
2258
|
}
|
|
2161
2259
|
async init() {
|
|
2260
|
+
this.clear();
|
|
2162
2261
|
const head = await this.strategy.readHead();
|
|
2163
2262
|
if (head === null) {
|
|
2164
2263
|
this.order = this.strategy.order;
|
|
@@ -2189,18 +2288,35 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2189
2288
|
}
|
|
2190
2289
|
async insertableNode(value) {
|
|
2191
2290
|
let node = await this.getNode(this.rootId);
|
|
2291
|
+
if (node.parent !== null) {
|
|
2292
|
+
node.parent = null;
|
|
2293
|
+
await this.bufferForNodeUpdate(node);
|
|
2294
|
+
}
|
|
2192
2295
|
while (!node.leaf) {
|
|
2296
|
+
const parentId = node.id;
|
|
2193
2297
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2194
2298
|
const nValue = node.values[i];
|
|
2195
2299
|
const k = node.keys;
|
|
2196
2300
|
if (this.comparator.isSame(value, nValue)) {
|
|
2197
2301
|
node = await this.getNode(node.keys[i + 1]);
|
|
2302
|
+
if (node.parent !== parentId) {
|
|
2303
|
+
node.parent = parentId;
|
|
2304
|
+
await this.bufferForNodeUpdate(node);
|
|
2305
|
+
}
|
|
2198
2306
|
break;
|
|
2199
2307
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
2200
2308
|
node = await this.getNode(node.keys[i]);
|
|
2309
|
+
if (node.parent !== parentId) {
|
|
2310
|
+
node.parent = parentId;
|
|
2311
|
+
await this.bufferForNodeUpdate(node);
|
|
2312
|
+
}
|
|
2201
2313
|
break;
|
|
2202
2314
|
} else if (i + 1 === node.values.length) {
|
|
2203
2315
|
node = await this.getNode(node.keys[i + 1]);
|
|
2316
|
+
if (node.parent !== parentId) {
|
|
2317
|
+
node.parent = parentId;
|
|
2318
|
+
await this.bufferForNodeUpdate(node);
|
|
2319
|
+
}
|
|
2204
2320
|
break;
|
|
2205
2321
|
}
|
|
2206
2322
|
}
|
|
@@ -2209,18 +2325,35 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2209
2325
|
}
|
|
2210
2326
|
async insertableNodeByPrimary(value) {
|
|
2211
2327
|
let node = await this.getNode(this.rootId);
|
|
2328
|
+
if (node.parent !== null) {
|
|
2329
|
+
node.parent = null;
|
|
2330
|
+
await this.bufferForNodeUpdate(node);
|
|
2331
|
+
}
|
|
2212
2332
|
while (!node.leaf) {
|
|
2333
|
+
const parentId = node.id;
|
|
2213
2334
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2214
2335
|
const nValue = node.values[i];
|
|
2215
2336
|
const k = node.keys;
|
|
2216
2337
|
if (this.comparator.isPrimarySame(value, nValue)) {
|
|
2217
2338
|
node = await this.getNode(node.keys[i]);
|
|
2339
|
+
if (node.parent !== parentId) {
|
|
2340
|
+
node.parent = parentId;
|
|
2341
|
+
await this.bufferForNodeUpdate(node);
|
|
2342
|
+
}
|
|
2218
2343
|
break;
|
|
2219
2344
|
} else if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
2220
2345
|
node = await this.getNode(node.keys[i]);
|
|
2346
|
+
if (node.parent !== parentId) {
|
|
2347
|
+
node.parent = parentId;
|
|
2348
|
+
await this.bufferForNodeUpdate(node);
|
|
2349
|
+
}
|
|
2221
2350
|
break;
|
|
2222
2351
|
} else if (i + 1 === node.values.length) {
|
|
2223
2352
|
node = await this.getNode(node.keys[i + 1]);
|
|
2353
|
+
if (node.parent !== parentId) {
|
|
2354
|
+
node.parent = parentId;
|
|
2355
|
+
await this.bufferForNodeUpdate(node);
|
|
2356
|
+
}
|
|
2224
2357
|
break;
|
|
2225
2358
|
}
|
|
2226
2359
|
}
|
|
@@ -2229,16 +2362,29 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2229
2362
|
}
|
|
2230
2363
|
async insertableRightestNodeByPrimary(value) {
|
|
2231
2364
|
let node = await this.getNode(this.rootId);
|
|
2365
|
+
if (node.parent !== null) {
|
|
2366
|
+
node.parent = null;
|
|
2367
|
+
await this.bufferForNodeUpdate(node);
|
|
2368
|
+
}
|
|
2232
2369
|
while (!node.leaf) {
|
|
2370
|
+
const parentId = node.id;
|
|
2233
2371
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2234
2372
|
const nValue = node.values[i];
|
|
2235
2373
|
const k = node.keys;
|
|
2236
2374
|
if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
2237
2375
|
node = await this.getNode(node.keys[i]);
|
|
2376
|
+
if (node.parent !== parentId) {
|
|
2377
|
+
node.parent = parentId;
|
|
2378
|
+
await this.bufferForNodeUpdate(node);
|
|
2379
|
+
}
|
|
2238
2380
|
break;
|
|
2239
2381
|
}
|
|
2240
2382
|
if (i + 1 === node.values.length) {
|
|
2241
2383
|
node = await this.getNode(node.keys[i + 1]);
|
|
2384
|
+
if (node.parent !== parentId) {
|
|
2385
|
+
node.parent = parentId;
|
|
2386
|
+
await this.bufferForNodeUpdate(node);
|
|
2387
|
+
}
|
|
2242
2388
|
break;
|
|
2243
2389
|
}
|
|
2244
2390
|
}
|
|
@@ -2273,17 +2419,35 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2273
2419
|
}
|
|
2274
2420
|
async leftestNode() {
|
|
2275
2421
|
let node = await this.getNode(this.rootId);
|
|
2422
|
+
if (node.parent !== null) {
|
|
2423
|
+
node.parent = null;
|
|
2424
|
+
await this.bufferForNodeUpdate(node);
|
|
2425
|
+
}
|
|
2276
2426
|
while (!node.leaf) {
|
|
2427
|
+
const parentId = node.id;
|
|
2277
2428
|
const keys = node.keys;
|
|
2278
2429
|
node = await this.getNode(node.keys[0]);
|
|
2430
|
+
if (node.parent !== parentId) {
|
|
2431
|
+
node.parent = parentId;
|
|
2432
|
+
await this.bufferForNodeUpdate(node);
|
|
2433
|
+
}
|
|
2279
2434
|
}
|
|
2280
2435
|
return node;
|
|
2281
2436
|
}
|
|
2282
2437
|
async rightestNode() {
|
|
2283
2438
|
let node = await this.getNode(this.rootId);
|
|
2439
|
+
if (node.parent !== null) {
|
|
2440
|
+
node.parent = null;
|
|
2441
|
+
await this.bufferForNodeUpdate(node);
|
|
2442
|
+
}
|
|
2284
2443
|
while (!node.leaf) {
|
|
2444
|
+
const parentId = node.id;
|
|
2285
2445
|
const keys = node.keys;
|
|
2286
2446
|
node = await this.getNode(node.keys[node.keys.length - 1]);
|
|
2447
|
+
if (node.parent !== parentId) {
|
|
2448
|
+
node.parent = parentId;
|
|
2449
|
+
await this.bufferForNodeUpdate(node);
|
|
2450
|
+
}
|
|
2287
2451
|
}
|
|
2288
2452
|
return node;
|
|
2289
2453
|
}
|
|
@@ -2443,7 +2607,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2443
2607
|
async insert(key, value) {
|
|
2444
2608
|
await this.writeLock(async () => {
|
|
2445
2609
|
const before = await this.insertableNode(value);
|
|
2446
|
-
this._insertAtLeaf(before, key, value);
|
|
2610
|
+
await this._insertAtLeaf(before, key, value);
|
|
2447
2611
|
if (before.values.length === this.order) {
|
|
2448
2612
|
const after = await this._createNode(
|
|
2449
2613
|
true,
|
|
@@ -2460,7 +2624,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2460
2624
|
before.values = before.values.slice(0, mid + 1);
|
|
2461
2625
|
before.keys = before.keys.slice(0, mid + 1);
|
|
2462
2626
|
await this._insertInParent(before, after.values[0], after);
|
|
2463
|
-
this.bufferForNodeUpdate(before);
|
|
2627
|
+
await this.bufferForNodeUpdate(before);
|
|
2464
2628
|
}
|
|
2465
2629
|
await this.commitHeadBuffer();
|
|
2466
2630
|
await this.commitNodeCreateBuffer();
|
|
@@ -2483,11 +2647,13 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2483
2647
|
node.values.splice(i, 1);
|
|
2484
2648
|
}
|
|
2485
2649
|
await this._deleteEntry(node, key, value);
|
|
2650
|
+
await this.bufferForNodeUpdate(node);
|
|
2486
2651
|
break;
|
|
2487
2652
|
}
|
|
2488
2653
|
}
|
|
2489
2654
|
}
|
|
2490
2655
|
await this.commitHeadBuffer();
|
|
2656
|
+
await this.commitNodeCreateBuffer();
|
|
2491
2657
|
await this.commitNodeUpdateBuffer();
|
|
2492
2658
|
await this.commitNodeDeleteBuffer();
|
|
2493
2659
|
});
|
|
@@ -2613,23 +2779,37 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2613
2779
|
realBaseTree;
|
|
2614
2780
|
realBaseStrategy;
|
|
2615
2781
|
txNodes = /* @__PURE__ */ new Map();
|
|
2616
|
-
dirtyIds
|
|
2617
|
-
createdInTx
|
|
2782
|
+
dirtyIds;
|
|
2783
|
+
createdInTx;
|
|
2784
|
+
deletedIds;
|
|
2618
2785
|
initialRootId;
|
|
2619
2786
|
transactionRootId;
|
|
2620
2787
|
constructor(baseTree) {
|
|
2621
2788
|
super(baseTree.strategy, baseTree.comparator, baseTree.option);
|
|
2622
2789
|
this.realBaseTree = baseTree;
|
|
2623
2790
|
this.realBaseStrategy = baseTree.strategy;
|
|
2791
|
+
this.order = baseTree.getOrder();
|
|
2624
2792
|
this.initialRootId = "";
|
|
2625
2793
|
this.transactionRootId = "";
|
|
2794
|
+
this.dirtyIds = /* @__PURE__ */ new Set();
|
|
2795
|
+
this.createdInTx = /* @__PURE__ */ new Set();
|
|
2796
|
+
this.deletedIds = /* @__PURE__ */ new Set();
|
|
2626
2797
|
}
|
|
2627
2798
|
/**
|
|
2628
2799
|
* Initializes the transaction by capturing the current state of the tree.
|
|
2629
2800
|
*/
|
|
2630
2801
|
async initTransaction() {
|
|
2631
2802
|
const head = await this.realBaseStrategy.readHead();
|
|
2632
|
-
|
|
2803
|
+
if (head) {
|
|
2804
|
+
this.order = head.order;
|
|
2805
|
+
this.initialRootId = head.root;
|
|
2806
|
+
} else {
|
|
2807
|
+
this.initialRootId = this.realBaseTree.getRootId();
|
|
2808
|
+
}
|
|
2809
|
+
if (!this.initialRootId) {
|
|
2810
|
+
const root = await this._createNode(true, [], [], true);
|
|
2811
|
+
this.initialRootId = root.id;
|
|
2812
|
+
}
|
|
2633
2813
|
this.transactionRootId = this.initialRootId;
|
|
2634
2814
|
this.rootId = this.transactionRootId;
|
|
2635
2815
|
const snapshotStrategy = new BPTreeAsyncSnapshotStrategy(this.realBaseStrategy, this.initialRootId);
|
|
@@ -2637,34 +2817,76 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2637
2817
|
this.txNodes.clear();
|
|
2638
2818
|
this.dirtyIds.clear();
|
|
2639
2819
|
this.createdInTx.clear();
|
|
2820
|
+
this.deletedIds.clear();
|
|
2640
2821
|
}
|
|
2641
2822
|
async getNode(id) {
|
|
2642
2823
|
if (this.txNodes.has(id)) {
|
|
2643
2824
|
return this.txNodes.get(id);
|
|
2644
2825
|
}
|
|
2826
|
+
if (this.deletedIds.has(id)) {
|
|
2827
|
+
throw new Error(`The tree attempted to reference deleted node '${id}'`);
|
|
2828
|
+
}
|
|
2645
2829
|
const baseNode = await this.realBaseStrategy.read(id);
|
|
2646
2830
|
const clone = JSON.parse(JSON.stringify(baseNode));
|
|
2647
2831
|
this.txNodes.set(id, clone);
|
|
2648
2832
|
return clone;
|
|
2649
2833
|
}
|
|
2650
2834
|
async bufferForNodeUpdate(node) {
|
|
2835
|
+
if (this.dirtyIds.has(node.id) && this.txNodes.has(node.id) && node._p) {
|
|
2836
|
+
this.txNodes.set(node.id, node);
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
node._p = true;
|
|
2651
2840
|
this.txNodes.set(node.id, node);
|
|
2652
2841
|
this.dirtyIds.add(node.id);
|
|
2842
|
+
if (node.leaf) {
|
|
2843
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
2844
|
+
try {
|
|
2845
|
+
await this.bufferForNodeUpdate(await this.getNode(node.next));
|
|
2846
|
+
} catch (e) {
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
2850
|
+
try {
|
|
2851
|
+
await this.bufferForNodeUpdate(await this.getNode(node.prev));
|
|
2852
|
+
} catch (e) {
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
}
|
|
2653
2856
|
await this.markPathDirty(node);
|
|
2857
|
+
delete node._p;
|
|
2654
2858
|
}
|
|
2655
2859
|
async bufferForNodeCreate(node) {
|
|
2656
2860
|
this.txNodes.set(node.id, node);
|
|
2657
2861
|
this.dirtyIds.add(node.id);
|
|
2658
2862
|
this.createdInTx.add(node.id);
|
|
2863
|
+
if (node.leaf) {
|
|
2864
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
2865
|
+
try {
|
|
2866
|
+
await this.bufferForNodeUpdate(await this.getNode(node.next));
|
|
2867
|
+
} catch (e) {
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
2871
|
+
try {
|
|
2872
|
+
await this.bufferForNodeUpdate(await this.getNode(node.prev));
|
|
2873
|
+
} catch (e) {
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2659
2877
|
await this.markPathDirty(node);
|
|
2660
2878
|
}
|
|
2661
2879
|
async bufferForNodeDelete(node) {
|
|
2662
2880
|
this.txNodes.delete(node.id);
|
|
2663
2881
|
this.dirtyIds.add(node.id);
|
|
2882
|
+
this.deletedIds.add(node.id);
|
|
2664
2883
|
}
|
|
2665
2884
|
async markPathDirty(node) {
|
|
2666
2885
|
let curr = node;
|
|
2667
2886
|
while (curr.parent) {
|
|
2887
|
+
if (this.deletedIds.has(curr.parent)) {
|
|
2888
|
+
break;
|
|
2889
|
+
}
|
|
2668
2890
|
if (this.dirtyIds.has(curr.parent) && this.txNodes.has(curr.parent)) {
|
|
2669
2891
|
break;
|
|
2670
2892
|
}
|
|
@@ -2676,13 +2898,13 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2676
2898
|
this.transactionRootId = curr.id;
|
|
2677
2899
|
}
|
|
2678
2900
|
}
|
|
2679
|
-
async _createNode(isLeaf, keys, values, leaf =
|
|
2680
|
-
const id = await this.
|
|
2901
|
+
async _createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
2902
|
+
const id = await this.strategy.id(isLeaf);
|
|
2681
2903
|
const node = {
|
|
2682
2904
|
id,
|
|
2683
2905
|
keys,
|
|
2684
2906
|
values,
|
|
2685
|
-
leaf
|
|
2907
|
+
leaf,
|
|
2686
2908
|
parent,
|
|
2687
2909
|
next,
|
|
2688
2910
|
prev
|
|
@@ -2740,9 +2962,9 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2740
2962
|
finalNodes.push(node);
|
|
2741
2963
|
newCreatedIds.push(newId);
|
|
2742
2964
|
}
|
|
2743
|
-
let newRootId = this.
|
|
2744
|
-
if (idMapping.has(this.
|
|
2745
|
-
newRootId = idMapping.get(this.
|
|
2965
|
+
let newRootId = this.rootId;
|
|
2966
|
+
if (idMapping.has(this.rootId)) {
|
|
2967
|
+
newRootId = idMapping.get(this.rootId);
|
|
2746
2968
|
}
|
|
2747
2969
|
for (const node of finalNodes) {
|
|
2748
2970
|
await this.realBaseStrategy.write(node.id, node);
|