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.
@@ -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 = false, parent = null, next = null, prev = null) {
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._nodeCreateBuffer.set(id, node);
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
- const nKey = node.keys[i];
861
- if (nKey === key) {
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
- for (let i = 0, len = node.values.length; i < len; i++) {
868
- const nValue = node.values[i];
869
- if (this.comparator.isSame(value, nValue)) {
870
- node.values.splice(i, 1);
871
- this.bufferForNodeUpdate(node);
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
974
- const nValue = parentNode.values[i];
975
- if (this.comparator.isSame(guess, nValue)) {
976
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
988
- const nValue = parentNode.values[i];
989
- if (this.comparator.isSame(guess, nValue)) {
990
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
1008
- const nValue = parentNode.values[i];
1009
- if (this.comparator.isSame(guess, nValue)) {
1010
- parentNode.values[i] = pointerK0;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
1022
- const nValue = parentNode.values[i];
1023
- if (this.comparator.isSame(guess, nValue)) {
1024
- parentNode.values[i] = pointer.values[0];
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
- let insertIndex = 0;
1074
- for (let i = 0; i < parentNode.values.length; i++) {
1075
- if (this.comparator.asc(value, parentNode.values[i]) > 0) {
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 leftSiblingId = parentNode.keys[insertIndex];
1086
- const rightSiblingId = parentNode.keys[insertIndex + 2];
1087
- if (leftSiblingId) {
1088
- const leftSibling = this.getNode(leftSiblingId);
1089
- pointer.prev = leftSibling.id;
1090
- pointer.next = leftSibling.next;
1091
- leftSibling.next = pointer.id;
1092
- this.bufferForNodeUpdate(leftSibling);
1093
- }
1094
- if (rightSiblingId) {
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 = /* @__PURE__ */ new Set();
1590
- createdInTx = /* @__PURE__ */ new Set();
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
- this.initialRootId = head?.root ?? this.realBaseTree.rootId;
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 = false, parent = null, next = null, prev = null) {
1653
- const id = this.realBaseStrategy.id(isLeaf);
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: isLeaf,
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.transactionRootId;
1717
- if (idMapping.has(this.transactionRootId)) {
1718
- newRootId = idMapping.get(this.transactionRootId);
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 = false, parent = null, next = null, prev = null) {
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._nodeCreateBuffer.set(id, node);
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
- const nKey = node.keys[i];
1894
- if (nKey === key) {
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
- for (let i = 0, len = node.values.length; i < len; i++) {
1901
- const nValue = node.values[i];
1902
- if (this.comparator.isSame(value, nValue)) {
1903
- node.values.splice(i, 1);
1904
- this.bufferForNodeUpdate(node);
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
2007
- const nValue = parentNode.values[i];
2008
- if (this.comparator.isSame(guess, nValue)) {
2009
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
2021
- const nValue = parentNode.values[i];
2022
- if (this.comparator.isSame(guess, nValue)) {
2023
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
2041
- const nValue = parentNode.values[i];
2042
- if (this.comparator.isSame(guess, nValue)) {
2043
- parentNode.values[i] = pointerK0;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
2055
- const nValue = parentNode.values[i];
2056
- if (this.comparator.isSame(guess, nValue)) {
2057
- parentNode.values[i] = pointer.values[0];
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
- node.next = pointer.id;
2102
- pointer.prev = node.id;
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
- let insertIndex = 0;
2110
- for (let i = 0; i < parentNode.values.length; i++) {
2111
- if (this.comparator.asc(value, parentNode.values[i]) > 0) {
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 leftSiblingId = parentNode.keys[insertIndex];
2122
- const rightSiblingId = parentNode.keys[insertIndex + 2];
2123
- if (leftSiblingId) {
2124
- const leftSibling = await this.getNode(leftSiblingId);
2125
- pointer.prev = leftSibling.id;
2126
- pointer.next = leftSibling.next;
2127
- leftSibling.next = pointer.id;
2128
- this.bufferForNodeUpdate(leftSibling);
2129
- }
2130
- if (rightSiblingId) {
2131
- const rightSibling = await this.getNode(rightSiblingId);
2132
- rightSibling.prev = pointer.id;
2133
- this.bufferForNodeUpdate(rightSibling);
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 = /* @__PURE__ */ new Set();
2617
- createdInTx = /* @__PURE__ */ new Set();
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
- this.initialRootId = head?.root ?? this.realBaseTree.rootId;
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 = false, parent = null, next = null, prev = null) {
2680
- const id = await this.realBaseStrategy.id(isLeaf);
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: isLeaf,
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.transactionRootId;
2744
- if (idMapping.has(this.transactionRootId)) {
2745
- newRootId = idMapping.get(this.transactionRootId);
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);