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.
@@ -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 = false, parent = null, next = null, prev = null) {
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._nodeCreateBuffer.set(id, node);
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
- const nKey = node.keys[i];
825
- if (nKey === key) {
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
- for (let i = 0, len = node.values.length; i < len; i++) {
832
- const nValue = node.values[i];
833
- if (this.comparator.isSame(value, nValue)) {
834
- node.values.splice(i, 1);
835
- this.bufferForNodeUpdate(node);
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
938
- const nValue = parentNode.values[i];
939
- if (this.comparator.isSame(guess, nValue)) {
940
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
952
- const nValue = parentNode.values[i];
953
- if (this.comparator.isSame(guess, nValue)) {
954
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
972
- const nValue = parentNode.values[i];
973
- if (this.comparator.isSame(guess, nValue)) {
974
- parentNode.values[i] = pointerK0;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
986
- const nValue = parentNode.values[i];
987
- if (this.comparator.isSame(guess, nValue)) {
988
- parentNode.values[i] = pointer.values[0];
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
- let insertIndex = 0;
1038
- for (let i = 0; i < parentNode.values.length; i++) {
1039
- if (this.comparator.asc(value, parentNode.values[i]) > 0) {
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 leftSiblingId = parentNode.keys[insertIndex];
1050
- const rightSiblingId = parentNode.keys[insertIndex + 2];
1051
- if (leftSiblingId) {
1052
- const leftSibling = this.getNode(leftSiblingId);
1053
- pointer.prev = leftSibling.id;
1054
- pointer.next = leftSibling.next;
1055
- leftSibling.next = pointer.id;
1056
- this.bufferForNodeUpdate(leftSibling);
1057
- }
1058
- if (rightSiblingId) {
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 = /* @__PURE__ */ new Set();
1554
- createdInTx = /* @__PURE__ */ new Set();
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
- this.initialRootId = head?.root ?? this.realBaseTree.rootId;
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 = false, parent = null, next = null, prev = null) {
1617
- const id = this.realBaseStrategy.id(isLeaf);
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: isLeaf,
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.transactionRootId;
1681
- if (idMapping.has(this.transactionRootId)) {
1682
- newRootId = idMapping.get(this.transactionRootId);
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 = false, parent = null, next = null, prev = null) {
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._nodeCreateBuffer.set(id, node);
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
- const nKey = node.keys[i];
1858
- if (nKey === key) {
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
- for (let i = 0, len = node.values.length; i < len; i++) {
1865
- const nValue = node.values[i];
1866
- if (this.comparator.isSame(value, nValue)) {
1867
- node.values.splice(i, 1);
1868
- this.bufferForNodeUpdate(node);
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
1971
- const nValue = parentNode.values[i];
1972
- if (this.comparator.isSame(guess, nValue)) {
1973
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
1985
- const nValue = parentNode.values[i];
1986
- if (this.comparator.isSame(guess, nValue)) {
1987
- parentNode.values[i] = pointerKm;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
2005
- const nValue = parentNode.values[i];
2006
- if (this.comparator.isSame(guess, nValue)) {
2007
- parentNode.values[i] = pointerK0;
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
- for (let i = 0, len = parentNode.values.length; i < len; i++) {
2019
- const nValue = parentNode.values[i];
2020
- if (this.comparator.isSame(guess, nValue)) {
2021
- parentNode.values[i] = pointer.values[0];
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
- node.next = pointer.id;
2066
- pointer.prev = node.id;
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
- let insertIndex = 0;
2074
- for (let i = 0; i < parentNode.values.length; i++) {
2075
- if (this.comparator.asc(value, parentNode.values[i]) > 0) {
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 leftSiblingId = parentNode.keys[insertIndex];
2086
- const rightSiblingId = parentNode.keys[insertIndex + 2];
2087
- if (leftSiblingId) {
2088
- const leftSibling = await this.getNode(leftSiblingId);
2089
- pointer.prev = leftSibling.id;
2090
- pointer.next = leftSibling.next;
2091
- leftSibling.next = pointer.id;
2092
- this.bufferForNodeUpdate(leftSibling);
2093
- }
2094
- if (rightSiblingId) {
2095
- const rightSibling = await this.getNode(rightSiblingId);
2096
- rightSibling.prev = pointer.id;
2097
- this.bufferForNodeUpdate(rightSibling);
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 = /* @__PURE__ */ new Set();
2581
- createdInTx = /* @__PURE__ */ new Set();
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
- this.initialRootId = head?.root ?? this.realBaseTree.rootId;
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 = false, parent = null, next = null, prev = null) {
2644
- const id = await this.realBaseStrategy.id(isLeaf);
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: isLeaf,
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.transactionRootId;
2708
- if (idMapping.has(this.transactionRootId)) {
2709
- newRootId = idMapping.get(this.transactionRootId);
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);