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/esm/index.mjs
CHANGED
|
@@ -439,6 +439,20 @@ var BPTree = class _BPTree {
|
|
|
439
439
|
option;
|
|
440
440
|
order;
|
|
441
441
|
rootId;
|
|
442
|
+
/**
|
|
443
|
+
* Returns the ID of the root node.
|
|
444
|
+
* @returns The root node ID.
|
|
445
|
+
*/
|
|
446
|
+
getRootId() {
|
|
447
|
+
return this.rootId;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Returns the order of the B+Tree.
|
|
451
|
+
* @returns The order of the tree.
|
|
452
|
+
*/
|
|
453
|
+
getOrder() {
|
|
454
|
+
return this.order;
|
|
455
|
+
}
|
|
442
456
|
_strategyDirty;
|
|
443
457
|
_nodeCreateBuffer;
|
|
444
458
|
_nodeUpdateBuffer;
|
|
@@ -671,24 +685,21 @@ var BPTree = class _BPTree {
|
|
|
671
685
|
break;
|
|
672
686
|
}
|
|
673
687
|
keys.push(key);
|
|
674
|
-
this.bufferForNodeUpdate(node);
|
|
675
|
-
break;
|
|
688
|
+
return this.bufferForNodeUpdate(node);
|
|
676
689
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
677
690
|
node.values.splice(i, 0, value);
|
|
678
691
|
node.keys.splice(i, 0, [key]);
|
|
679
|
-
this.bufferForNodeUpdate(node);
|
|
680
|
-
break;
|
|
692
|
+
return this.bufferForNodeUpdate(node);
|
|
681
693
|
} else if (i + 1 === node.values.length) {
|
|
682
694
|
node.values.push(value);
|
|
683
695
|
node.keys.push([key]);
|
|
684
|
-
this.bufferForNodeUpdate(node);
|
|
685
|
-
break;
|
|
696
|
+
return this.bufferForNodeUpdate(node);
|
|
686
697
|
}
|
|
687
698
|
}
|
|
688
699
|
} else {
|
|
689
700
|
node.values = [value];
|
|
690
701
|
node.keys = [[key]];
|
|
691
|
-
this.bufferForNodeUpdate(node);
|
|
702
|
+
return this.bufferForNodeUpdate(node);
|
|
692
703
|
}
|
|
693
704
|
}
|
|
694
705
|
bufferForNodeCreate(node) {
|
|
@@ -804,7 +815,7 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
804
815
|
}
|
|
805
816
|
return id;
|
|
806
817
|
}
|
|
807
|
-
_createNode(isLeaf, keys, values, leaf =
|
|
818
|
+
_createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
808
819
|
const id = this._createNodeId(isLeaf);
|
|
809
820
|
const node = {
|
|
810
821
|
id,
|
|
@@ -815,26 +826,23 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
815
826
|
next,
|
|
816
827
|
prev
|
|
817
828
|
};
|
|
818
|
-
this.
|
|
829
|
+
this.bufferForNodeCreate(node);
|
|
819
830
|
return node;
|
|
820
831
|
}
|
|
821
832
|
_deleteEntry(node, key, value) {
|
|
822
833
|
if (!node.leaf) {
|
|
834
|
+
let keyIndex = -1;
|
|
823
835
|
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
node.keys.splice(i, 1);
|
|
827
|
-
this.bufferForNodeUpdate(node);
|
|
836
|
+
if (node.keys[i] === key) {
|
|
837
|
+
keyIndex = i;
|
|
828
838
|
break;
|
|
829
839
|
}
|
|
830
840
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
break;
|
|
837
|
-
}
|
|
841
|
+
if (keyIndex !== -1) {
|
|
842
|
+
node.keys.splice(keyIndex, 1);
|
|
843
|
+
const valueIndex = keyIndex > 0 ? keyIndex - 1 : 0;
|
|
844
|
+
node.values.splice(valueIndex, 1);
|
|
845
|
+
this.bufferForNodeUpdate(node);
|
|
838
846
|
}
|
|
839
847
|
}
|
|
840
848
|
if (this.rootId === node.id && node.keys.length === 1 && !node.leaf) {
|
|
@@ -934,13 +942,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
934
942
|
node.keys = [pointerPm, ...node.keys];
|
|
935
943
|
node.values = [guess, ...node.values];
|
|
936
944
|
parentNode = this.getNode(node.parent);
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
this.bufferForNodeUpdate(parentNode);
|
|
942
|
-
break;
|
|
943
|
-
}
|
|
945
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
946
|
+
if (nodeIndex > 0) {
|
|
947
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
948
|
+
this.bufferForNodeUpdate(parentNode);
|
|
944
949
|
}
|
|
945
950
|
} else {
|
|
946
951
|
pointerPm = pointer.keys.splice(-1)[0];
|
|
@@ -948,13 +953,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
948
953
|
node.keys = [pointerPm, ...node.keys];
|
|
949
954
|
node.values = [pointerKm, ...node.values];
|
|
950
955
|
parentNode = this.getNode(node.parent);
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
this.bufferForNodeUpdate(parentNode);
|
|
956
|
-
break;
|
|
957
|
-
}
|
|
956
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
957
|
+
if (nodeIndex > 0) {
|
|
958
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
959
|
+
this.bufferForNodeUpdate(parentNode);
|
|
958
960
|
}
|
|
959
961
|
}
|
|
960
962
|
this.bufferForNodeUpdate(node);
|
|
@@ -968,13 +970,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
968
970
|
node.keys = [...node.keys, pointerP0];
|
|
969
971
|
node.values = [...node.values, guess];
|
|
970
972
|
parentNode = this.getNode(node.parent);
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
this.bufferForNodeUpdate(parentNode);
|
|
976
|
-
break;
|
|
977
|
-
}
|
|
973
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
974
|
+
if (pointerIndex > 0) {
|
|
975
|
+
parentNode.values[pointerIndex - 1] = pointerK0;
|
|
976
|
+
this.bufferForNodeUpdate(parentNode);
|
|
978
977
|
}
|
|
979
978
|
} else {
|
|
980
979
|
pointerP0 = pointer.keys.splice(0, 1)[0];
|
|
@@ -982,13 +981,10 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
982
981
|
node.keys = [...node.keys, pointerP0];
|
|
983
982
|
node.values = [...node.values, pointerK0];
|
|
984
983
|
parentNode = this.getNode(node.parent);
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
this.bufferForNodeUpdate(parentNode);
|
|
990
|
-
break;
|
|
991
|
-
}
|
|
984
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
985
|
+
if (pointerIndex > 0) {
|
|
986
|
+
parentNode.values[pointerIndex - 1] = pointer.values[0];
|
|
987
|
+
this.bufferForNodeUpdate(parentNode);
|
|
992
988
|
}
|
|
993
989
|
}
|
|
994
990
|
this.bufferForNodeUpdate(node);
|
|
@@ -1016,6 +1012,8 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1016
1012
|
}
|
|
1017
1013
|
}
|
|
1018
1014
|
}
|
|
1015
|
+
} else {
|
|
1016
|
+
this.bufferForNodeUpdate(node);
|
|
1019
1017
|
}
|
|
1020
1018
|
}
|
|
1021
1019
|
_insertInParent(node, value, pointer) {
|
|
@@ -1034,31 +1032,25 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1034
1032
|
return;
|
|
1035
1033
|
}
|
|
1036
1034
|
const parentNode = this.getNode(node.parent);
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
insertIndex = i + 1;
|
|
1041
|
-
} else {
|
|
1042
|
-
break;
|
|
1043
|
-
}
|
|
1035
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
1036
|
+
if (nodeIndex === -1) {
|
|
1037
|
+
throw new Error(`Node ${node.id} not found in parent ${parentNode.id}`);
|
|
1044
1038
|
}
|
|
1039
|
+
const insertIndex = nodeIndex;
|
|
1045
1040
|
parentNode.values.splice(insertIndex, 0, value);
|
|
1046
1041
|
parentNode.keys.splice(insertIndex + 1, 0, pointer.id);
|
|
1047
1042
|
pointer.parent = parentNode.id;
|
|
1048
1043
|
if (pointer.leaf) {
|
|
1049
|
-
const
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
this.
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
const rightSibling = this.getNode(rightSiblingId);
|
|
1060
|
-
rightSibling.prev = pointer.id;
|
|
1061
|
-
this.bufferForNodeUpdate(rightSibling);
|
|
1044
|
+
const leftSibling = node;
|
|
1045
|
+
const oldNextId = leftSibling.next;
|
|
1046
|
+
pointer.prev = leftSibling.id;
|
|
1047
|
+
pointer.next = oldNextId;
|
|
1048
|
+
leftSibling.next = pointer.id;
|
|
1049
|
+
this.bufferForNodeUpdate(leftSibling);
|
|
1050
|
+
if (oldNextId) {
|
|
1051
|
+
const oldNext = this.getNode(oldNextId);
|
|
1052
|
+
oldNext.prev = pointer.id;
|
|
1053
|
+
this.bufferForNodeUpdate(oldNext);
|
|
1062
1054
|
}
|
|
1063
1055
|
}
|
|
1064
1056
|
this.bufferForNodeUpdate(parentNode);
|
|
@@ -1087,6 +1079,7 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1087
1079
|
}
|
|
1088
1080
|
}
|
|
1089
1081
|
init() {
|
|
1082
|
+
this.clear();
|
|
1090
1083
|
const head = this.strategy.readHead();
|
|
1091
1084
|
if (head === null) {
|
|
1092
1085
|
this.order = this.strategy.order;
|
|
@@ -1117,18 +1110,35 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1117
1110
|
}
|
|
1118
1111
|
insertableNode(value) {
|
|
1119
1112
|
let node = this.getNode(this.rootId);
|
|
1113
|
+
if (node.parent !== null) {
|
|
1114
|
+
node.parent = null;
|
|
1115
|
+
this.bufferForNodeUpdate(node);
|
|
1116
|
+
}
|
|
1120
1117
|
while (!node.leaf) {
|
|
1118
|
+
const parentId = node.id;
|
|
1121
1119
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1122
1120
|
const nValue = node.values[i];
|
|
1123
1121
|
const k = node.keys;
|
|
1124
1122
|
if (this.comparator.isSame(value, nValue)) {
|
|
1125
1123
|
node = this.getNode(k[i + 1]);
|
|
1124
|
+
if (node.parent !== parentId) {
|
|
1125
|
+
node.parent = parentId;
|
|
1126
|
+
this.bufferForNodeUpdate(node);
|
|
1127
|
+
}
|
|
1126
1128
|
break;
|
|
1127
1129
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
1128
1130
|
node = this.getNode(k[i]);
|
|
1131
|
+
if (node.parent !== parentId) {
|
|
1132
|
+
node.parent = parentId;
|
|
1133
|
+
this.bufferForNodeUpdate(node);
|
|
1134
|
+
}
|
|
1129
1135
|
break;
|
|
1130
1136
|
} else if (i + 1 === node.values.length) {
|
|
1131
1137
|
node = this.getNode(k[i + 1]);
|
|
1138
|
+
if (node.parent !== parentId) {
|
|
1139
|
+
node.parent = parentId;
|
|
1140
|
+
this.bufferForNodeUpdate(node);
|
|
1141
|
+
}
|
|
1132
1142
|
break;
|
|
1133
1143
|
}
|
|
1134
1144
|
}
|
|
@@ -1137,18 +1147,35 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1137
1147
|
}
|
|
1138
1148
|
insertableNodeByPrimary(value) {
|
|
1139
1149
|
let node = this.getNode(this.rootId);
|
|
1150
|
+
if (node.parent !== null) {
|
|
1151
|
+
node.parent = null;
|
|
1152
|
+
this.bufferForNodeUpdate(node);
|
|
1153
|
+
}
|
|
1140
1154
|
while (!node.leaf) {
|
|
1155
|
+
const parentId = node.id;
|
|
1141
1156
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1142
1157
|
const nValue = node.values[i];
|
|
1143
1158
|
const k = node.keys;
|
|
1144
1159
|
if (this.comparator.isPrimarySame(value, nValue)) {
|
|
1145
1160
|
node = this.getNode(k[i]);
|
|
1161
|
+
if (node.parent !== parentId) {
|
|
1162
|
+
node.parent = parentId;
|
|
1163
|
+
this.bufferForNodeUpdate(node);
|
|
1164
|
+
}
|
|
1146
1165
|
break;
|
|
1147
1166
|
} else if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
1148
1167
|
node = this.getNode(k[i]);
|
|
1168
|
+
if (node.parent !== parentId) {
|
|
1169
|
+
node.parent = parentId;
|
|
1170
|
+
this.bufferForNodeUpdate(node);
|
|
1171
|
+
}
|
|
1149
1172
|
break;
|
|
1150
1173
|
} else if (i + 1 === node.values.length) {
|
|
1151
1174
|
node = this.getNode(k[i + 1]);
|
|
1175
|
+
if (node.parent !== parentId) {
|
|
1176
|
+
node.parent = parentId;
|
|
1177
|
+
this.bufferForNodeUpdate(node);
|
|
1178
|
+
}
|
|
1152
1179
|
break;
|
|
1153
1180
|
}
|
|
1154
1181
|
}
|
|
@@ -1157,16 +1184,29 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1157
1184
|
}
|
|
1158
1185
|
insertableRightestNodeByPrimary(value) {
|
|
1159
1186
|
let node = this.getNode(this.rootId);
|
|
1187
|
+
if (node.parent !== null) {
|
|
1188
|
+
node.parent = null;
|
|
1189
|
+
this.bufferForNodeUpdate(node);
|
|
1190
|
+
}
|
|
1160
1191
|
while (!node.leaf) {
|
|
1192
|
+
const parentId = node.id;
|
|
1161
1193
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1162
1194
|
const nValue = node.values[i];
|
|
1163
1195
|
const k = node.keys;
|
|
1164
1196
|
if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
1165
1197
|
node = this.getNode(k[i]);
|
|
1198
|
+
if (node.parent !== parentId) {
|
|
1199
|
+
node.parent = parentId;
|
|
1200
|
+
this.bufferForNodeUpdate(node);
|
|
1201
|
+
}
|
|
1166
1202
|
break;
|
|
1167
1203
|
}
|
|
1168
1204
|
if (i + 1 === node.values.length) {
|
|
1169
1205
|
node = this.getNode(k[i + 1]);
|
|
1206
|
+
if (node.parent !== parentId) {
|
|
1207
|
+
node.parent = parentId;
|
|
1208
|
+
this.bufferForNodeUpdate(node);
|
|
1209
|
+
}
|
|
1170
1210
|
break;
|
|
1171
1211
|
}
|
|
1172
1212
|
}
|
|
@@ -1201,17 +1241,35 @@ var BPTreeSyncBase = class extends BPTree {
|
|
|
1201
1241
|
}
|
|
1202
1242
|
leftestNode() {
|
|
1203
1243
|
let node = this.getNode(this.rootId);
|
|
1244
|
+
if (node.parent !== null) {
|
|
1245
|
+
node.parent = null;
|
|
1246
|
+
this.bufferForNodeUpdate(node);
|
|
1247
|
+
}
|
|
1204
1248
|
while (!node.leaf) {
|
|
1249
|
+
const parentId = node.id;
|
|
1205
1250
|
const keys = node.keys;
|
|
1206
1251
|
node = this.getNode(keys[0]);
|
|
1252
|
+
if (node.parent !== parentId) {
|
|
1253
|
+
node.parent = parentId;
|
|
1254
|
+
this.bufferForNodeUpdate(node);
|
|
1255
|
+
}
|
|
1207
1256
|
}
|
|
1208
1257
|
return node;
|
|
1209
1258
|
}
|
|
1210
1259
|
rightestNode() {
|
|
1211
1260
|
let node = this.getNode(this.rootId);
|
|
1261
|
+
if (node.parent !== null) {
|
|
1262
|
+
node.parent = null;
|
|
1263
|
+
this.bufferForNodeUpdate(node);
|
|
1264
|
+
}
|
|
1212
1265
|
while (!node.leaf) {
|
|
1266
|
+
const parentId = node.id;
|
|
1213
1267
|
const keys = node.keys;
|
|
1214
1268
|
node = this.getNode(keys[keys.length - 1]);
|
|
1269
|
+
if (node.parent !== parentId) {
|
|
1270
|
+
node.parent = parentId;
|
|
1271
|
+
this.bufferForNodeUpdate(node);
|
|
1272
|
+
}
|
|
1215
1273
|
}
|
|
1216
1274
|
return node;
|
|
1217
1275
|
}
|
|
@@ -1550,23 +1608,37 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1550
1608
|
realBaseTree;
|
|
1551
1609
|
realBaseStrategy;
|
|
1552
1610
|
txNodes = /* @__PURE__ */ new Map();
|
|
1553
|
-
dirtyIds
|
|
1554
|
-
createdInTx
|
|
1611
|
+
dirtyIds;
|
|
1612
|
+
createdInTx;
|
|
1613
|
+
deletedIds;
|
|
1555
1614
|
initialRootId;
|
|
1556
1615
|
transactionRootId;
|
|
1557
1616
|
constructor(baseTree) {
|
|
1558
1617
|
super(baseTree.strategy, baseTree.comparator, baseTree.option);
|
|
1559
1618
|
this.realBaseTree = baseTree;
|
|
1560
1619
|
this.realBaseStrategy = baseTree.strategy;
|
|
1620
|
+
this.order = baseTree.getOrder();
|
|
1561
1621
|
this.initialRootId = "";
|
|
1562
1622
|
this.transactionRootId = "";
|
|
1623
|
+
this.dirtyIds = /* @__PURE__ */ new Set();
|
|
1624
|
+
this.createdInTx = /* @__PURE__ */ new Set();
|
|
1625
|
+
this.deletedIds = /* @__PURE__ */ new Set();
|
|
1563
1626
|
}
|
|
1564
1627
|
/**
|
|
1565
1628
|
* Initializes the transaction by capturing the current state of the tree.
|
|
1566
1629
|
*/
|
|
1567
1630
|
initTransaction() {
|
|
1568
1631
|
const head = this.realBaseStrategy.readHead();
|
|
1569
|
-
|
|
1632
|
+
if (head) {
|
|
1633
|
+
this.order = head.order;
|
|
1634
|
+
this.initialRootId = head.root;
|
|
1635
|
+
} else {
|
|
1636
|
+
this.initialRootId = this.realBaseTree.getRootId();
|
|
1637
|
+
}
|
|
1638
|
+
if (!this.initialRootId) {
|
|
1639
|
+
const root = this._createNode(true, [], [], true);
|
|
1640
|
+
this.initialRootId = root.id;
|
|
1641
|
+
}
|
|
1570
1642
|
this.transactionRootId = this.initialRootId;
|
|
1571
1643
|
this.rootId = this.transactionRootId;
|
|
1572
1644
|
const snapshotStrategy = new BPTreeSyncSnapshotStrategy(this.realBaseStrategy, this.initialRootId);
|
|
@@ -1574,34 +1646,76 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1574
1646
|
this.txNodes.clear();
|
|
1575
1647
|
this.dirtyIds.clear();
|
|
1576
1648
|
this.createdInTx.clear();
|
|
1649
|
+
this.deletedIds.clear();
|
|
1577
1650
|
}
|
|
1578
1651
|
getNode(id) {
|
|
1579
1652
|
if (this.txNodes.has(id)) {
|
|
1580
1653
|
return this.txNodes.get(id);
|
|
1581
1654
|
}
|
|
1655
|
+
if (this.deletedIds.has(id)) {
|
|
1656
|
+
throw new Error(`The tree attempted to reference deleted node '${id}'`);
|
|
1657
|
+
}
|
|
1582
1658
|
const baseNode = this.realBaseStrategy.read(id);
|
|
1583
1659
|
const clone = JSON.parse(JSON.stringify(baseNode));
|
|
1584
1660
|
this.txNodes.set(id, clone);
|
|
1585
1661
|
return clone;
|
|
1586
1662
|
}
|
|
1587
1663
|
bufferForNodeUpdate(node) {
|
|
1664
|
+
if (this.dirtyIds.has(node.id) && this.txNodes.has(node.id) && node._p) {
|
|
1665
|
+
this.txNodes.set(node.id, node);
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
node._p = true;
|
|
1588
1669
|
this.txNodes.set(node.id, node);
|
|
1589
1670
|
this.dirtyIds.add(node.id);
|
|
1671
|
+
if (node.leaf) {
|
|
1672
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
1673
|
+
try {
|
|
1674
|
+
this.bufferForNodeUpdate(this.getNode(node.next));
|
|
1675
|
+
} catch (e) {
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
1679
|
+
try {
|
|
1680
|
+
this.bufferForNodeUpdate(this.getNode(node.prev));
|
|
1681
|
+
} catch (e) {
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1590
1685
|
this.markPathDirty(node);
|
|
1686
|
+
delete node._p;
|
|
1591
1687
|
}
|
|
1592
1688
|
bufferForNodeCreate(node) {
|
|
1593
1689
|
this.txNodes.set(node.id, node);
|
|
1594
1690
|
this.dirtyIds.add(node.id);
|
|
1595
1691
|
this.createdInTx.add(node.id);
|
|
1692
|
+
if (node.leaf) {
|
|
1693
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
1694
|
+
try {
|
|
1695
|
+
this.bufferForNodeUpdate(this.getNode(node.next));
|
|
1696
|
+
} catch (e) {
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
1700
|
+
try {
|
|
1701
|
+
this.bufferForNodeUpdate(this.getNode(node.prev));
|
|
1702
|
+
} catch (e) {
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1596
1706
|
this.markPathDirty(node);
|
|
1597
1707
|
}
|
|
1598
1708
|
bufferForNodeDelete(node) {
|
|
1599
1709
|
this.txNodes.delete(node.id);
|
|
1600
1710
|
this.dirtyIds.add(node.id);
|
|
1711
|
+
this.deletedIds.add(node.id);
|
|
1601
1712
|
}
|
|
1602
1713
|
markPathDirty(node) {
|
|
1603
1714
|
let curr = node;
|
|
1604
1715
|
while (curr.parent) {
|
|
1716
|
+
if (this.deletedIds.has(curr.parent)) {
|
|
1717
|
+
break;
|
|
1718
|
+
}
|
|
1605
1719
|
if (this.dirtyIds.has(curr.parent) && this.txNodes.has(curr.parent)) {
|
|
1606
1720
|
break;
|
|
1607
1721
|
}
|
|
@@ -1613,13 +1727,13 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1613
1727
|
this.transactionRootId = curr.id;
|
|
1614
1728
|
}
|
|
1615
1729
|
}
|
|
1616
|
-
_createNode(isLeaf, keys, values, leaf =
|
|
1617
|
-
const id = this.
|
|
1730
|
+
_createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
1731
|
+
const id = this.strategy.id(isLeaf);
|
|
1618
1732
|
const node = {
|
|
1619
1733
|
id,
|
|
1620
1734
|
keys,
|
|
1621
1735
|
values,
|
|
1622
|
-
leaf
|
|
1736
|
+
leaf,
|
|
1623
1737
|
parent,
|
|
1624
1738
|
next,
|
|
1625
1739
|
prev
|
|
@@ -1677,9 +1791,9 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1677
1791
|
finalNodes.push(node);
|
|
1678
1792
|
newCreatedIds.push(newId);
|
|
1679
1793
|
}
|
|
1680
|
-
let newRootId = this.
|
|
1681
|
-
if (idMapping.has(this.
|
|
1682
|
-
newRootId = idMapping.get(this.
|
|
1794
|
+
let newRootId = this.rootId;
|
|
1795
|
+
if (idMapping.has(this.rootId)) {
|
|
1796
|
+
newRootId = idMapping.get(this.rootId);
|
|
1683
1797
|
}
|
|
1684
1798
|
for (const node of finalNodes) {
|
|
1685
1799
|
this.realBaseStrategy.write(node.id, node);
|
|
@@ -1730,6 +1844,7 @@ var BPTreeSyncTransaction = class extends BPTreeSyncBase {
|
|
|
1730
1844
|
var BPTreeSync = class extends BPTreeSyncBase {
|
|
1731
1845
|
constructor(strategy, comparator, option) {
|
|
1732
1846
|
super(strategy, comparator, option);
|
|
1847
|
+
this.init();
|
|
1733
1848
|
}
|
|
1734
1849
|
/**
|
|
1735
1850
|
* Creates a new synchronous transaction.
|
|
@@ -1837,7 +1952,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1837
1952
|
}
|
|
1838
1953
|
return id;
|
|
1839
1954
|
}
|
|
1840
|
-
async _createNode(isLeaf, keys, values, leaf =
|
|
1955
|
+
async _createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
1841
1956
|
const id = await this._createNodeId(isLeaf);
|
|
1842
1957
|
const node = {
|
|
1843
1958
|
id,
|
|
@@ -1848,40 +1963,37 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1848
1963
|
next,
|
|
1849
1964
|
prev
|
|
1850
1965
|
};
|
|
1851
|
-
this.
|
|
1966
|
+
await this.bufferForNodeCreate(node);
|
|
1852
1967
|
return node;
|
|
1853
1968
|
}
|
|
1854
1969
|
async _deleteEntry(node, key, value) {
|
|
1855
1970
|
if (!node.leaf) {
|
|
1971
|
+
let keyIndex = -1;
|
|
1856
1972
|
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
node.keys.splice(i, 1);
|
|
1860
|
-
this.bufferForNodeUpdate(node);
|
|
1973
|
+
if (node.keys[i] === key) {
|
|
1974
|
+
keyIndex = i;
|
|
1861
1975
|
break;
|
|
1862
1976
|
}
|
|
1863
1977
|
}
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
break;
|
|
1870
|
-
}
|
|
1978
|
+
if (keyIndex !== -1) {
|
|
1979
|
+
node.keys.splice(keyIndex, 1);
|
|
1980
|
+
const valueIndex = keyIndex > 0 ? keyIndex - 1 : 0;
|
|
1981
|
+
node.values.splice(valueIndex, 1);
|
|
1982
|
+
await this.bufferForNodeUpdate(node);
|
|
1871
1983
|
}
|
|
1872
1984
|
}
|
|
1873
1985
|
if (this.rootId === node.id && node.keys.length === 1 && !node.leaf) {
|
|
1874
1986
|
const keys = node.keys;
|
|
1875
|
-
this.bufferForNodeDelete(node);
|
|
1987
|
+
await this.bufferForNodeDelete(node);
|
|
1876
1988
|
const newRoot = await this.getNode(keys[0]);
|
|
1877
1989
|
this.rootId = newRoot.id;
|
|
1878
1990
|
newRoot.parent = null;
|
|
1879
1991
|
this.strategy.head.root = this.rootId;
|
|
1880
|
-
this.bufferForNodeUpdate(newRoot);
|
|
1992
|
+
await this.bufferForNodeUpdate(newRoot);
|
|
1881
1993
|
return;
|
|
1882
1994
|
} else if (this.rootId === node.id) {
|
|
1883
1995
|
const root = await this.getNode(this.rootId);
|
|
1884
|
-
this.bufferForNodeUpdate(root);
|
|
1996
|
+
await this.bufferForNodeUpdate(root);
|
|
1885
1997
|
return;
|
|
1886
1998
|
} else if (node.keys.length < Math.ceil(this.order / 2) && !node.leaf || node.values.length < Math.ceil((this.order - 1) / 2) && node.leaf) {
|
|
1887
1999
|
if (node.parent === null) {
|
|
@@ -1942,7 +2054,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1942
2054
|
if (pointer.next) {
|
|
1943
2055
|
const n = await this.getNode(pointer.next);
|
|
1944
2056
|
n.prev = pointer.id;
|
|
1945
|
-
this.bufferForNodeUpdate(n);
|
|
2057
|
+
await this.bufferForNodeUpdate(n);
|
|
1946
2058
|
}
|
|
1947
2059
|
}
|
|
1948
2060
|
pointer.values.push(...node.values);
|
|
@@ -1951,12 +2063,12 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1951
2063
|
for (const key2 of keys) {
|
|
1952
2064
|
const n = await this.getNode(key2);
|
|
1953
2065
|
n.parent = pointer.id;
|
|
1954
|
-
this.bufferForNodeUpdate(n);
|
|
2066
|
+
await this.bufferForNodeUpdate(n);
|
|
1955
2067
|
}
|
|
1956
2068
|
}
|
|
1957
2069
|
await this._deleteEntry(await this.getNode(node.parent), node.id, guess);
|
|
1958
|
-
this.bufferForNodeUpdate(pointer);
|
|
1959
|
-
this.bufferForNodeDelete(node);
|
|
2070
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2071
|
+
await this.bufferForNodeDelete(node);
|
|
1960
2072
|
} else {
|
|
1961
2073
|
if (isPredecessor) {
|
|
1962
2074
|
let pointerPm;
|
|
@@ -1967,13 +2079,10 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1967
2079
|
node.keys = [pointerPm, ...node.keys];
|
|
1968
2080
|
node.values = [guess, ...node.values];
|
|
1969
2081
|
parentNode = await this.getNode(node.parent);
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
this.bufferForNodeUpdate(parentNode);
|
|
1975
|
-
break;
|
|
1976
|
-
}
|
|
2082
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
2083
|
+
if (nodeIndex > 0) {
|
|
2084
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
2085
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
1977
2086
|
}
|
|
1978
2087
|
} else {
|
|
1979
2088
|
pointerPm = pointer.keys.splice(-1)[0];
|
|
@@ -1981,17 +2090,14 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
1981
2090
|
node.keys = [pointerPm, ...node.keys];
|
|
1982
2091
|
node.values = [pointerKm, ...node.values];
|
|
1983
2092
|
parentNode = await this.getNode(node.parent);
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
this.bufferForNodeUpdate(parentNode);
|
|
1989
|
-
break;
|
|
1990
|
-
}
|
|
2093
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
2094
|
+
if (nodeIndex > 0) {
|
|
2095
|
+
parentNode.values[nodeIndex - 1] = pointerKm;
|
|
2096
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
1991
2097
|
}
|
|
1992
2098
|
}
|
|
1993
|
-
this.bufferForNodeUpdate(node);
|
|
1994
|
-
this.bufferForNodeUpdate(pointer);
|
|
2099
|
+
await this.bufferForNodeUpdate(node);
|
|
2100
|
+
await this.bufferForNodeUpdate(pointer);
|
|
1995
2101
|
} else {
|
|
1996
2102
|
let pointerP0;
|
|
1997
2103
|
let pointerK0;
|
|
@@ -2001,13 +2107,10 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2001
2107
|
node.keys = [...node.keys, pointerP0];
|
|
2002
2108
|
node.values = [...node.values, guess];
|
|
2003
2109
|
parentNode = await this.getNode(node.parent);
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2009
|
-
break;
|
|
2010
|
-
}
|
|
2110
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
2111
|
+
if (pointerIndex > 0) {
|
|
2112
|
+
parentNode.values[pointerIndex - 1] = pointerK0;
|
|
2113
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2011
2114
|
}
|
|
2012
2115
|
} else {
|
|
2013
2116
|
pointerP0 = pointer.keys.splice(0, 1)[0];
|
|
@@ -2015,24 +2118,21 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2015
2118
|
node.keys = [...node.keys, pointerP0];
|
|
2016
2119
|
node.values = [...node.values, pointerK0];
|
|
2017
2120
|
parentNode = await this.getNode(node.parent);
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2023
|
-
break;
|
|
2024
|
-
}
|
|
2121
|
+
const pointerIndex = parentNode.keys.indexOf(pointer.id);
|
|
2122
|
+
if (pointerIndex > 0) {
|
|
2123
|
+
parentNode.values[pointerIndex - 1] = pointer.values[0];
|
|
2124
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2025
2125
|
}
|
|
2026
2126
|
}
|
|
2027
|
-
this.bufferForNodeUpdate(node);
|
|
2028
|
-
this.bufferForNodeUpdate(pointer);
|
|
2127
|
+
await this.bufferForNodeUpdate(node);
|
|
2128
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2029
2129
|
}
|
|
2030
2130
|
if (!pointer.leaf) {
|
|
2031
2131
|
const keys = pointer.keys;
|
|
2032
2132
|
for (const key2 of keys) {
|
|
2033
2133
|
const n = await this.getNode(key2);
|
|
2034
2134
|
n.parent = pointer.id;
|
|
2035
|
-
this.bufferForNodeUpdate(n);
|
|
2135
|
+
await this.bufferForNodeUpdate(n);
|
|
2036
2136
|
}
|
|
2037
2137
|
}
|
|
2038
2138
|
if (!node.leaf) {
|
|
@@ -2040,7 +2140,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2040
2140
|
for (const key2 of keys) {
|
|
2041
2141
|
const n = await this.getNode(key2);
|
|
2042
2142
|
n.parent = node.id;
|
|
2043
|
-
this.bufferForNodeUpdate(n);
|
|
2143
|
+
await this.bufferForNodeUpdate(n);
|
|
2044
2144
|
}
|
|
2045
2145
|
}
|
|
2046
2146
|
if (!parentNode.leaf) {
|
|
@@ -2048,10 +2148,12 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2048
2148
|
for (const key2 of keys) {
|
|
2049
2149
|
const n = await this.getNode(key2);
|
|
2050
2150
|
n.parent = parentNode.id;
|
|
2051
|
-
this.bufferForNodeUpdate(n);
|
|
2151
|
+
await this.bufferForNodeUpdate(n);
|
|
2052
2152
|
}
|
|
2053
2153
|
}
|
|
2054
2154
|
}
|
|
2155
|
+
} else {
|
|
2156
|
+
await this.bufferForNodeUpdate(node);
|
|
2055
2157
|
}
|
|
2056
2158
|
}
|
|
2057
2159
|
async _insertInParent(node, value, pointer) {
|
|
@@ -2062,43 +2164,39 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2062
2164
|
node.parent = root.id;
|
|
2063
2165
|
pointer.parent = root.id;
|
|
2064
2166
|
if (pointer.leaf) {
|
|
2065
|
-
|
|
2066
|
-
|
|
2167
|
+
const nNode = node;
|
|
2168
|
+
nNode.next = pointer.id;
|
|
2169
|
+
const nPointer = pointer;
|
|
2170
|
+
nPointer.prev = node.id;
|
|
2067
2171
|
}
|
|
2068
|
-
this.bufferForNodeUpdate(node);
|
|
2069
|
-
this.bufferForNodeUpdate(pointer);
|
|
2172
|
+
await this.bufferForNodeUpdate(node);
|
|
2173
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2070
2174
|
return;
|
|
2071
2175
|
}
|
|
2072
2176
|
const parentNode = await this.getNode(node.parent);
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
insertIndex = i + 1;
|
|
2077
|
-
} else {
|
|
2078
|
-
break;
|
|
2079
|
-
}
|
|
2177
|
+
const nodeIndex = parentNode.keys.indexOf(node.id);
|
|
2178
|
+
if (nodeIndex === -1) {
|
|
2179
|
+
throw new Error(`Node ${node.id} not found in parent ${parentNode.id}`);
|
|
2080
2180
|
}
|
|
2181
|
+
const insertIndex = nodeIndex;
|
|
2081
2182
|
parentNode.values.splice(insertIndex, 0, value);
|
|
2082
2183
|
parentNode.keys.splice(insertIndex + 1, 0, pointer.id);
|
|
2083
2184
|
pointer.parent = parentNode.id;
|
|
2084
2185
|
if (pointer.leaf) {
|
|
2085
|
-
const
|
|
2086
|
-
const
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
this.
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
}
|
|
2100
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2101
|
-
this.bufferForNodeUpdate(pointer);
|
|
2186
|
+
const leftSibling = node;
|
|
2187
|
+
const oldNextId = leftSibling.next;
|
|
2188
|
+
pointer.prev = leftSibling.id;
|
|
2189
|
+
pointer.next = oldNextId;
|
|
2190
|
+
leftSibling.next = pointer.id;
|
|
2191
|
+
await this.bufferForNodeUpdate(leftSibling);
|
|
2192
|
+
if (oldNextId) {
|
|
2193
|
+
const oldNext = await this.getNode(oldNextId);
|
|
2194
|
+
oldNext.prev = pointer.id;
|
|
2195
|
+
await this.bufferForNodeUpdate(oldNext);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2199
|
+
await this.bufferForNodeUpdate(pointer);
|
|
2102
2200
|
if (parentNode.keys.length > this.order) {
|
|
2103
2201
|
const parentPointer = await this._createNode(false, [], []);
|
|
2104
2202
|
parentPointer.parent = parentNode.parent;
|
|
@@ -2111,18 +2209,19 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2111
2209
|
for (const k of parentNode.keys) {
|
|
2112
2210
|
const n = await this.getNode(k);
|
|
2113
2211
|
n.parent = parentNode.id;
|
|
2114
|
-
this.bufferForNodeUpdate(n);
|
|
2212
|
+
await this.bufferForNodeUpdate(n);
|
|
2115
2213
|
}
|
|
2116
2214
|
for (const k of parentPointer.keys) {
|
|
2117
2215
|
const n = await this.getNode(k);
|
|
2118
2216
|
n.parent = parentPointer.id;
|
|
2119
|
-
this.bufferForNodeUpdate(n);
|
|
2217
|
+
await this.bufferForNodeUpdate(n);
|
|
2120
2218
|
}
|
|
2121
2219
|
await this._insertInParent(parentNode, midValue, parentPointer);
|
|
2122
|
-
this.bufferForNodeUpdate(parentNode);
|
|
2220
|
+
await this.bufferForNodeUpdate(parentNode);
|
|
2123
2221
|
}
|
|
2124
2222
|
}
|
|
2125
2223
|
async init() {
|
|
2224
|
+
this.clear();
|
|
2126
2225
|
const head = await this.strategy.readHead();
|
|
2127
2226
|
if (head === null) {
|
|
2128
2227
|
this.order = this.strategy.order;
|
|
@@ -2153,18 +2252,35 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2153
2252
|
}
|
|
2154
2253
|
async insertableNode(value) {
|
|
2155
2254
|
let node = await this.getNode(this.rootId);
|
|
2255
|
+
if (node.parent !== null) {
|
|
2256
|
+
node.parent = null;
|
|
2257
|
+
await this.bufferForNodeUpdate(node);
|
|
2258
|
+
}
|
|
2156
2259
|
while (!node.leaf) {
|
|
2260
|
+
const parentId = node.id;
|
|
2157
2261
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2158
2262
|
const nValue = node.values[i];
|
|
2159
2263
|
const k = node.keys;
|
|
2160
2264
|
if (this.comparator.isSame(value, nValue)) {
|
|
2161
2265
|
node = await this.getNode(node.keys[i + 1]);
|
|
2266
|
+
if (node.parent !== parentId) {
|
|
2267
|
+
node.parent = parentId;
|
|
2268
|
+
await this.bufferForNodeUpdate(node);
|
|
2269
|
+
}
|
|
2162
2270
|
break;
|
|
2163
2271
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
2164
2272
|
node = await this.getNode(node.keys[i]);
|
|
2273
|
+
if (node.parent !== parentId) {
|
|
2274
|
+
node.parent = parentId;
|
|
2275
|
+
await this.bufferForNodeUpdate(node);
|
|
2276
|
+
}
|
|
2165
2277
|
break;
|
|
2166
2278
|
} else if (i + 1 === node.values.length) {
|
|
2167
2279
|
node = await this.getNode(node.keys[i + 1]);
|
|
2280
|
+
if (node.parent !== parentId) {
|
|
2281
|
+
node.parent = parentId;
|
|
2282
|
+
await this.bufferForNodeUpdate(node);
|
|
2283
|
+
}
|
|
2168
2284
|
break;
|
|
2169
2285
|
}
|
|
2170
2286
|
}
|
|
@@ -2173,18 +2289,35 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2173
2289
|
}
|
|
2174
2290
|
async insertableNodeByPrimary(value) {
|
|
2175
2291
|
let node = await this.getNode(this.rootId);
|
|
2292
|
+
if (node.parent !== null) {
|
|
2293
|
+
node.parent = null;
|
|
2294
|
+
await this.bufferForNodeUpdate(node);
|
|
2295
|
+
}
|
|
2176
2296
|
while (!node.leaf) {
|
|
2297
|
+
const parentId = node.id;
|
|
2177
2298
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2178
2299
|
const nValue = node.values[i];
|
|
2179
2300
|
const k = node.keys;
|
|
2180
2301
|
if (this.comparator.isPrimarySame(value, nValue)) {
|
|
2181
2302
|
node = await this.getNode(node.keys[i]);
|
|
2303
|
+
if (node.parent !== parentId) {
|
|
2304
|
+
node.parent = parentId;
|
|
2305
|
+
await this.bufferForNodeUpdate(node);
|
|
2306
|
+
}
|
|
2182
2307
|
break;
|
|
2183
2308
|
} else if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
2184
2309
|
node = await this.getNode(node.keys[i]);
|
|
2310
|
+
if (node.parent !== parentId) {
|
|
2311
|
+
node.parent = parentId;
|
|
2312
|
+
await this.bufferForNodeUpdate(node);
|
|
2313
|
+
}
|
|
2185
2314
|
break;
|
|
2186
2315
|
} else if (i + 1 === node.values.length) {
|
|
2187
2316
|
node = await this.getNode(node.keys[i + 1]);
|
|
2317
|
+
if (node.parent !== parentId) {
|
|
2318
|
+
node.parent = parentId;
|
|
2319
|
+
await this.bufferForNodeUpdate(node);
|
|
2320
|
+
}
|
|
2188
2321
|
break;
|
|
2189
2322
|
}
|
|
2190
2323
|
}
|
|
@@ -2193,16 +2326,29 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2193
2326
|
}
|
|
2194
2327
|
async insertableRightestNodeByPrimary(value) {
|
|
2195
2328
|
let node = await this.getNode(this.rootId);
|
|
2329
|
+
if (node.parent !== null) {
|
|
2330
|
+
node.parent = null;
|
|
2331
|
+
await this.bufferForNodeUpdate(node);
|
|
2332
|
+
}
|
|
2196
2333
|
while (!node.leaf) {
|
|
2334
|
+
const parentId = node.id;
|
|
2197
2335
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2198
2336
|
const nValue = node.values[i];
|
|
2199
2337
|
const k = node.keys;
|
|
2200
2338
|
if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
2201
2339
|
node = await this.getNode(node.keys[i]);
|
|
2340
|
+
if (node.parent !== parentId) {
|
|
2341
|
+
node.parent = parentId;
|
|
2342
|
+
await this.bufferForNodeUpdate(node);
|
|
2343
|
+
}
|
|
2202
2344
|
break;
|
|
2203
2345
|
}
|
|
2204
2346
|
if (i + 1 === node.values.length) {
|
|
2205
2347
|
node = await this.getNode(node.keys[i + 1]);
|
|
2348
|
+
if (node.parent !== parentId) {
|
|
2349
|
+
node.parent = parentId;
|
|
2350
|
+
await this.bufferForNodeUpdate(node);
|
|
2351
|
+
}
|
|
2206
2352
|
break;
|
|
2207
2353
|
}
|
|
2208
2354
|
}
|
|
@@ -2237,17 +2383,35 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2237
2383
|
}
|
|
2238
2384
|
async leftestNode() {
|
|
2239
2385
|
let node = await this.getNode(this.rootId);
|
|
2386
|
+
if (node.parent !== null) {
|
|
2387
|
+
node.parent = null;
|
|
2388
|
+
await this.bufferForNodeUpdate(node);
|
|
2389
|
+
}
|
|
2240
2390
|
while (!node.leaf) {
|
|
2391
|
+
const parentId = node.id;
|
|
2241
2392
|
const keys = node.keys;
|
|
2242
2393
|
node = await this.getNode(node.keys[0]);
|
|
2394
|
+
if (node.parent !== parentId) {
|
|
2395
|
+
node.parent = parentId;
|
|
2396
|
+
await this.bufferForNodeUpdate(node);
|
|
2397
|
+
}
|
|
2243
2398
|
}
|
|
2244
2399
|
return node;
|
|
2245
2400
|
}
|
|
2246
2401
|
async rightestNode() {
|
|
2247
2402
|
let node = await this.getNode(this.rootId);
|
|
2403
|
+
if (node.parent !== null) {
|
|
2404
|
+
node.parent = null;
|
|
2405
|
+
await this.bufferForNodeUpdate(node);
|
|
2406
|
+
}
|
|
2248
2407
|
while (!node.leaf) {
|
|
2408
|
+
const parentId = node.id;
|
|
2249
2409
|
const keys = node.keys;
|
|
2250
2410
|
node = await this.getNode(node.keys[node.keys.length - 1]);
|
|
2411
|
+
if (node.parent !== parentId) {
|
|
2412
|
+
node.parent = parentId;
|
|
2413
|
+
await this.bufferForNodeUpdate(node);
|
|
2414
|
+
}
|
|
2251
2415
|
}
|
|
2252
2416
|
return node;
|
|
2253
2417
|
}
|
|
@@ -2407,7 +2571,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2407
2571
|
async insert(key, value) {
|
|
2408
2572
|
await this.writeLock(async () => {
|
|
2409
2573
|
const before = await this.insertableNode(value);
|
|
2410
|
-
this._insertAtLeaf(before, key, value);
|
|
2574
|
+
await this._insertAtLeaf(before, key, value);
|
|
2411
2575
|
if (before.values.length === this.order) {
|
|
2412
2576
|
const after = await this._createNode(
|
|
2413
2577
|
true,
|
|
@@ -2424,7 +2588,7 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2424
2588
|
before.values = before.values.slice(0, mid + 1);
|
|
2425
2589
|
before.keys = before.keys.slice(0, mid + 1);
|
|
2426
2590
|
await this._insertInParent(before, after.values[0], after);
|
|
2427
|
-
this.bufferForNodeUpdate(before);
|
|
2591
|
+
await this.bufferForNodeUpdate(before);
|
|
2428
2592
|
}
|
|
2429
2593
|
await this.commitHeadBuffer();
|
|
2430
2594
|
await this.commitNodeCreateBuffer();
|
|
@@ -2447,11 +2611,13 @@ var BPTreeAsyncBase = class extends BPTree {
|
|
|
2447
2611
|
node.values.splice(i, 1);
|
|
2448
2612
|
}
|
|
2449
2613
|
await this._deleteEntry(node, key, value);
|
|
2614
|
+
await this.bufferForNodeUpdate(node);
|
|
2450
2615
|
break;
|
|
2451
2616
|
}
|
|
2452
2617
|
}
|
|
2453
2618
|
}
|
|
2454
2619
|
await this.commitHeadBuffer();
|
|
2620
|
+
await this.commitNodeCreateBuffer();
|
|
2455
2621
|
await this.commitNodeUpdateBuffer();
|
|
2456
2622
|
await this.commitNodeDeleteBuffer();
|
|
2457
2623
|
});
|
|
@@ -2577,23 +2743,37 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2577
2743
|
realBaseTree;
|
|
2578
2744
|
realBaseStrategy;
|
|
2579
2745
|
txNodes = /* @__PURE__ */ new Map();
|
|
2580
|
-
dirtyIds
|
|
2581
|
-
createdInTx
|
|
2746
|
+
dirtyIds;
|
|
2747
|
+
createdInTx;
|
|
2748
|
+
deletedIds;
|
|
2582
2749
|
initialRootId;
|
|
2583
2750
|
transactionRootId;
|
|
2584
2751
|
constructor(baseTree) {
|
|
2585
2752
|
super(baseTree.strategy, baseTree.comparator, baseTree.option);
|
|
2586
2753
|
this.realBaseTree = baseTree;
|
|
2587
2754
|
this.realBaseStrategy = baseTree.strategy;
|
|
2755
|
+
this.order = baseTree.getOrder();
|
|
2588
2756
|
this.initialRootId = "";
|
|
2589
2757
|
this.transactionRootId = "";
|
|
2758
|
+
this.dirtyIds = /* @__PURE__ */ new Set();
|
|
2759
|
+
this.createdInTx = /* @__PURE__ */ new Set();
|
|
2760
|
+
this.deletedIds = /* @__PURE__ */ new Set();
|
|
2590
2761
|
}
|
|
2591
2762
|
/**
|
|
2592
2763
|
* Initializes the transaction by capturing the current state of the tree.
|
|
2593
2764
|
*/
|
|
2594
2765
|
async initTransaction() {
|
|
2595
2766
|
const head = await this.realBaseStrategy.readHead();
|
|
2596
|
-
|
|
2767
|
+
if (head) {
|
|
2768
|
+
this.order = head.order;
|
|
2769
|
+
this.initialRootId = head.root;
|
|
2770
|
+
} else {
|
|
2771
|
+
this.initialRootId = this.realBaseTree.getRootId();
|
|
2772
|
+
}
|
|
2773
|
+
if (!this.initialRootId) {
|
|
2774
|
+
const root = await this._createNode(true, [], [], true);
|
|
2775
|
+
this.initialRootId = root.id;
|
|
2776
|
+
}
|
|
2597
2777
|
this.transactionRootId = this.initialRootId;
|
|
2598
2778
|
this.rootId = this.transactionRootId;
|
|
2599
2779
|
const snapshotStrategy = new BPTreeAsyncSnapshotStrategy(this.realBaseStrategy, this.initialRootId);
|
|
@@ -2601,34 +2781,76 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2601
2781
|
this.txNodes.clear();
|
|
2602
2782
|
this.dirtyIds.clear();
|
|
2603
2783
|
this.createdInTx.clear();
|
|
2784
|
+
this.deletedIds.clear();
|
|
2604
2785
|
}
|
|
2605
2786
|
async getNode(id) {
|
|
2606
2787
|
if (this.txNodes.has(id)) {
|
|
2607
2788
|
return this.txNodes.get(id);
|
|
2608
2789
|
}
|
|
2790
|
+
if (this.deletedIds.has(id)) {
|
|
2791
|
+
throw new Error(`The tree attempted to reference deleted node '${id}'`);
|
|
2792
|
+
}
|
|
2609
2793
|
const baseNode = await this.realBaseStrategy.read(id);
|
|
2610
2794
|
const clone = JSON.parse(JSON.stringify(baseNode));
|
|
2611
2795
|
this.txNodes.set(id, clone);
|
|
2612
2796
|
return clone;
|
|
2613
2797
|
}
|
|
2614
2798
|
async bufferForNodeUpdate(node) {
|
|
2799
|
+
if (this.dirtyIds.has(node.id) && this.txNodes.has(node.id) && node._p) {
|
|
2800
|
+
this.txNodes.set(node.id, node);
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
node._p = true;
|
|
2615
2804
|
this.txNodes.set(node.id, node);
|
|
2616
2805
|
this.dirtyIds.add(node.id);
|
|
2806
|
+
if (node.leaf) {
|
|
2807
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
2808
|
+
try {
|
|
2809
|
+
await this.bufferForNodeUpdate(await this.getNode(node.next));
|
|
2810
|
+
} catch (e) {
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2813
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
2814
|
+
try {
|
|
2815
|
+
await this.bufferForNodeUpdate(await this.getNode(node.prev));
|
|
2816
|
+
} catch (e) {
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2617
2820
|
await this.markPathDirty(node);
|
|
2821
|
+
delete node._p;
|
|
2618
2822
|
}
|
|
2619
2823
|
async bufferForNodeCreate(node) {
|
|
2620
2824
|
this.txNodes.set(node.id, node);
|
|
2621
2825
|
this.dirtyIds.add(node.id);
|
|
2622
2826
|
this.createdInTx.add(node.id);
|
|
2827
|
+
if (node.leaf) {
|
|
2828
|
+
if (node.next && !this.dirtyIds.has(node.next) && !this.deletedIds.has(node.next)) {
|
|
2829
|
+
try {
|
|
2830
|
+
await this.bufferForNodeUpdate(await this.getNode(node.next));
|
|
2831
|
+
} catch (e) {
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
if (node.prev && !this.dirtyIds.has(node.prev) && !this.deletedIds.has(node.prev)) {
|
|
2835
|
+
try {
|
|
2836
|
+
await this.bufferForNodeUpdate(await this.getNode(node.prev));
|
|
2837
|
+
} catch (e) {
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2623
2841
|
await this.markPathDirty(node);
|
|
2624
2842
|
}
|
|
2625
2843
|
async bufferForNodeDelete(node) {
|
|
2626
2844
|
this.txNodes.delete(node.id);
|
|
2627
2845
|
this.dirtyIds.add(node.id);
|
|
2846
|
+
this.deletedIds.add(node.id);
|
|
2628
2847
|
}
|
|
2629
2848
|
async markPathDirty(node) {
|
|
2630
2849
|
let curr = node;
|
|
2631
2850
|
while (curr.parent) {
|
|
2851
|
+
if (this.deletedIds.has(curr.parent)) {
|
|
2852
|
+
break;
|
|
2853
|
+
}
|
|
2632
2854
|
if (this.dirtyIds.has(curr.parent) && this.txNodes.has(curr.parent)) {
|
|
2633
2855
|
break;
|
|
2634
2856
|
}
|
|
@@ -2640,13 +2862,13 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2640
2862
|
this.transactionRootId = curr.id;
|
|
2641
2863
|
}
|
|
2642
2864
|
}
|
|
2643
|
-
async _createNode(isLeaf, keys, values, leaf =
|
|
2644
|
-
const id = await this.
|
|
2865
|
+
async _createNode(isLeaf, keys, values, leaf = isLeaf, parent = null, next = null, prev = null) {
|
|
2866
|
+
const id = await this.strategy.id(isLeaf);
|
|
2645
2867
|
const node = {
|
|
2646
2868
|
id,
|
|
2647
2869
|
keys,
|
|
2648
2870
|
values,
|
|
2649
|
-
leaf
|
|
2871
|
+
leaf,
|
|
2650
2872
|
parent,
|
|
2651
2873
|
next,
|
|
2652
2874
|
prev
|
|
@@ -2704,9 +2926,9 @@ var BPTreeAsyncTransaction = class extends BPTreeAsyncBase {
|
|
|
2704
2926
|
finalNodes.push(node);
|
|
2705
2927
|
newCreatedIds.push(newId);
|
|
2706
2928
|
}
|
|
2707
|
-
let newRootId = this.
|
|
2708
|
-
if (idMapping.has(this.
|
|
2709
|
-
newRootId = idMapping.get(this.
|
|
2929
|
+
let newRootId = this.rootId;
|
|
2930
|
+
if (idMapping.has(this.rootId)) {
|
|
2931
|
+
newRootId = idMapping.get(this.rootId);
|
|
2710
2932
|
}
|
|
2711
2933
|
for (const node of finalNodes) {
|
|
2712
2934
|
await this.realBaseStrategy.write(node.id, node);
|