dataply 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -782,6 +782,9 @@ var BPTreeSync = class extends BPTree {
782
782
  guess = prevValue;
783
783
  }
784
784
  }
785
+ if (!pointer) {
786
+ return;
787
+ }
785
788
  if (node.values.length + pointer.values.length < this.order) {
786
789
  if (!isPredecessor) {
787
790
  const pTemp = pointer;
@@ -921,45 +924,66 @@ var BPTreeSync = class extends BPTree {
921
924
  this.strategy.head.root = root.id;
922
925
  node.parent = root.id;
923
926
  pointer.parent = root.id;
927
+ if (pointer.leaf) {
928
+ node.next = pointer.id;
929
+ pointer.prev = node.id;
930
+ }
924
931
  this.bufferForNodeUpdate(node);
925
932
  this.bufferForNodeUpdate(pointer);
926
933
  return;
927
934
  }
928
935
  const parentNode = this.getNode(node.parent);
929
- for (let i = 0, len = parentNode.keys.length; i < len; i++) {
930
- const nKeys = parentNode.keys[i];
931
- if (nKeys === node.id) {
932
- parentNode.values.splice(i, 0, value);
933
- parentNode.keys.splice(i + 1, 0, pointer.id);
934
- this.bufferForNodeUpdate(parentNode);
935
- if (parentNode.keys.length > this.order) {
936
- const parentPointer = this._createNode(false, [], []);
937
- parentPointer.parent = parentNode.parent;
938
- const mid = Math.ceil(this.order / 2) - 1;
939
- parentPointer.values = parentNode.values.slice(mid + 1);
940
- parentPointer.keys = parentNode.keys.slice(mid + 1);
941
- const midValue = parentNode.values[mid];
942
- if (mid === 0) {
943
- parentNode.values = parentNode.values.slice(0, mid + 1);
944
- } else {
945
- parentNode.values = parentNode.values.slice(0, mid);
946
- }
947
- parentNode.keys = parentNode.keys.slice(0, mid + 1);
948
- for (const k of parentNode.keys) {
949
- const node2 = this.getNode(k);
950
- node2.parent = parentNode.id;
951
- this.bufferForNodeUpdate(node2);
952
- }
953
- for (const k of parentPointer.keys) {
954
- const node2 = this.getNode(k);
955
- node2.parent = parentPointer.id;
956
- this.bufferForNodeUpdate(node2);
957
- }
958
- this._insertInParent(parentNode, midValue, parentPointer);
959
- this.bufferForNodeUpdate(parentNode);
960
- }
936
+ let insertIndex = 0;
937
+ for (let i = 0; i < parentNode.values.length; i++) {
938
+ if (this.comparator.asc(value, parentNode.values[i]) > 0) {
939
+ insertIndex = i + 1;
940
+ } else {
941
+ break;
942
+ }
943
+ }
944
+ parentNode.values.splice(insertIndex, 0, value);
945
+ parentNode.keys.splice(insertIndex + 1, 0, pointer.id);
946
+ pointer.parent = parentNode.id;
947
+ if (pointer.leaf) {
948
+ const leftSiblingId = parentNode.keys[insertIndex];
949
+ const rightSiblingId = parentNode.keys[insertIndex + 2];
950
+ if (leftSiblingId) {
951
+ const leftSibling = this.getNode(leftSiblingId);
952
+ pointer.prev = leftSibling.id;
953
+ pointer.next = leftSibling.next;
954
+ leftSibling.next = pointer.id;
955
+ this.bufferForNodeUpdate(leftSibling);
956
+ }
957
+ if (rightSiblingId) {
958
+ const rightSibling = this.getNode(rightSiblingId);
959
+ rightSibling.prev = pointer.id;
960
+ this.bufferForNodeUpdate(rightSibling);
961
961
  }
962
962
  }
963
+ this.bufferForNodeUpdate(parentNode);
964
+ this.bufferForNodeUpdate(pointer);
965
+ if (parentNode.keys.length > this.order) {
966
+ const parentPointer = this._createNode(false, [], []);
967
+ parentPointer.parent = parentNode.parent;
968
+ const mid = Math.ceil(this.order / 2) - 1;
969
+ parentPointer.values = parentNode.values.slice(mid + 1);
970
+ parentPointer.keys = parentNode.keys.slice(mid + 1);
971
+ const midValue = parentNode.values[mid];
972
+ parentNode.values = parentNode.values.slice(0, mid);
973
+ parentNode.keys = parentNode.keys.slice(0, mid + 1);
974
+ for (const k of parentNode.keys) {
975
+ const node2 = this.getNode(k);
976
+ node2.parent = parentNode.id;
977
+ this.bufferForNodeUpdate(node2);
978
+ }
979
+ for (const k of parentPointer.keys) {
980
+ const node2 = this.getNode(k);
981
+ node2.parent = parentPointer.id;
982
+ this.bufferForNodeUpdate(node2);
983
+ }
984
+ this._insertInParent(parentNode, midValue, parentPointer);
985
+ this.bufferForNodeUpdate(parentNode);
986
+ }
963
987
  }
964
988
  init() {
965
989
  const head = this.strategy.readHead();
@@ -980,6 +1004,9 @@ var BPTreeSync = class extends BPTree {
980
1004
  }
981
1005
  }
982
1006
  getNode(id) {
1007
+ if (this._nodeUpdateBuffer.has(id)) {
1008
+ return this._nodeUpdateBuffer.get(id);
1009
+ }
983
1010
  if (this._nodeCreateBuffer.has(id)) {
984
1011
  return this._nodeCreateBuffer.get(id);
985
1012
  }
@@ -987,7 +1014,7 @@ var BPTreeSync = class extends BPTree {
987
1014
  return cache.raw;
988
1015
  }
989
1016
  insertableNode(value) {
990
- let node = this.root;
1017
+ let node = this.getNode(this.root.id);
991
1018
  while (!node.leaf) {
992
1019
  for (let i = 0, len = node.values.length; i < len; i++) {
993
1020
  const nValue = node.values[i];
@@ -1124,21 +1151,14 @@ var BPTreeSync = class extends BPTree {
1124
1151
  [],
1125
1152
  true,
1126
1153
  before.parent,
1127
- before.next,
1128
- before.id
1154
+ null,
1155
+ null
1129
1156
  );
1130
1157
  const mid = Math.ceil(this.order / 2) - 1;
1131
- const beforeNext = before.next;
1132
1158
  after.values = before.values.slice(mid + 1);
1133
1159
  after.keys = before.keys.slice(mid + 1);
1134
1160
  before.values = before.values.slice(0, mid + 1);
1135
1161
  before.keys = before.keys.slice(0, mid + 1);
1136
- before.next = after.id;
1137
- if (beforeNext) {
1138
- const node = this.getNode(beforeNext);
1139
- node.prev = after.id;
1140
- this.bufferForNodeUpdate(node);
1141
- }
1142
1162
  this._insertInParent(before, after.values[0], after);
1143
1163
  this.bufferForNodeUpdate(before);
1144
1164
  }
@@ -1648,6 +1668,9 @@ var BPTreeAsync = class extends BPTree {
1648
1668
  guess = prevValue;
1649
1669
  }
1650
1670
  }
1671
+ if (!pointer) {
1672
+ return;
1673
+ }
1651
1674
  if (node.values.length + pointer.values.length < this.order) {
1652
1675
  if (!isPredecessor) {
1653
1676
  const pTemp = pointer;
@@ -1787,45 +1810,66 @@ var BPTreeAsync = class extends BPTree {
1787
1810
  this.strategy.head.root = root.id;
1788
1811
  node.parent = root.id;
1789
1812
  pointer.parent = root.id;
1813
+ if (pointer.leaf) {
1814
+ node.next = pointer.id;
1815
+ pointer.prev = node.id;
1816
+ }
1790
1817
  this.bufferForNodeUpdate(node);
1791
1818
  this.bufferForNodeUpdate(pointer);
1792
1819
  return;
1793
1820
  }
1794
1821
  const parentNode = await this.getNode(node.parent);
1795
- for (let i = 0, len = parentNode.keys.length; i < len; i++) {
1796
- const nKeys = parentNode.keys[i];
1797
- if (nKeys === node.id) {
1798
- parentNode.values.splice(i, 0, value);
1799
- parentNode.keys.splice(i + 1, 0, pointer.id);
1800
- this.bufferForNodeUpdate(parentNode);
1801
- if (parentNode.keys.length > this.order) {
1802
- const parentPointer = await this._createNode(false, [], []);
1803
- parentPointer.parent = parentNode.parent;
1804
- const mid = Math.ceil(this.order / 2) - 1;
1805
- parentPointer.values = parentNode.values.slice(mid + 1);
1806
- parentPointer.keys = parentNode.keys.slice(mid + 1);
1807
- const midValue = parentNode.values[mid];
1808
- if (mid === 0) {
1809
- parentNode.values = parentNode.values.slice(0, mid + 1);
1810
- } else {
1811
- parentNode.values = parentNode.values.slice(0, mid);
1812
- }
1813
- parentNode.keys = parentNode.keys.slice(0, mid + 1);
1814
- for (const k of parentNode.keys) {
1815
- const node2 = await this.getNode(k);
1816
- node2.parent = parentNode.id;
1817
- this.bufferForNodeUpdate(node2);
1818
- }
1819
- for (const k of parentPointer.keys) {
1820
- const node2 = await this.getNode(k);
1821
- node2.parent = parentPointer.id;
1822
- this.bufferForNodeUpdate(node2);
1823
- }
1824
- await this._insertInParent(parentNode, midValue, parentPointer);
1825
- this.bufferForNodeUpdate(parentNode);
1826
- }
1822
+ let insertIndex = 0;
1823
+ for (let i = 0; i < parentNode.values.length; i++) {
1824
+ if (this.comparator.asc(value, parentNode.values[i]) > 0) {
1825
+ insertIndex = i + 1;
1826
+ } else {
1827
+ break;
1828
+ }
1829
+ }
1830
+ parentNode.values.splice(insertIndex, 0, value);
1831
+ parentNode.keys.splice(insertIndex + 1, 0, pointer.id);
1832
+ pointer.parent = parentNode.id;
1833
+ if (pointer.leaf) {
1834
+ const leftSiblingId = parentNode.keys[insertIndex];
1835
+ const rightSiblingId = parentNode.keys[insertIndex + 2];
1836
+ if (leftSiblingId) {
1837
+ const leftSibling = await this.getNode(leftSiblingId);
1838
+ pointer.prev = leftSibling.id;
1839
+ pointer.next = leftSibling.next;
1840
+ leftSibling.next = pointer.id;
1841
+ this.bufferForNodeUpdate(leftSibling);
1842
+ }
1843
+ if (rightSiblingId) {
1844
+ const rightSibling = await this.getNode(rightSiblingId);
1845
+ rightSibling.prev = pointer.id;
1846
+ this.bufferForNodeUpdate(rightSibling);
1827
1847
  }
1828
1848
  }
1849
+ this.bufferForNodeUpdate(parentNode);
1850
+ this.bufferForNodeUpdate(pointer);
1851
+ if (parentNode.keys.length > this.order) {
1852
+ const parentPointer = await this._createNode(false, [], []);
1853
+ parentPointer.parent = parentNode.parent;
1854
+ const mid = Math.ceil(this.order / 2) - 1;
1855
+ parentPointer.values = parentNode.values.slice(mid + 1);
1856
+ parentPointer.keys = parentNode.keys.slice(mid + 1);
1857
+ const midValue = parentNode.values[mid];
1858
+ parentNode.values = parentNode.values.slice(0, mid);
1859
+ parentNode.keys = parentNode.keys.slice(0, mid + 1);
1860
+ for (const k of parentNode.keys) {
1861
+ const node2 = await this.getNode(k);
1862
+ node2.parent = parentNode.id;
1863
+ this.bufferForNodeUpdate(node2);
1864
+ }
1865
+ for (const k of parentPointer.keys) {
1866
+ const node2 = await this.getNode(k);
1867
+ node2.parent = parentPointer.id;
1868
+ this.bufferForNodeUpdate(node2);
1869
+ }
1870
+ await this._insertInParent(parentNode, midValue, parentPointer);
1871
+ this.bufferForNodeUpdate(parentNode);
1872
+ }
1829
1873
  }
1830
1874
  async init() {
1831
1875
  const head = await this.strategy.readHead();
@@ -1846,6 +1890,9 @@ var BPTreeAsync = class extends BPTree {
1846
1890
  }
1847
1891
  }
1848
1892
  async getNode(id) {
1893
+ if (this._nodeUpdateBuffer.has(id)) {
1894
+ return this._nodeUpdateBuffer.get(id);
1895
+ }
1849
1896
  if (this._nodeCreateBuffer.has(id)) {
1850
1897
  return this._nodeCreateBuffer.get(id);
1851
1898
  }
@@ -1853,7 +1900,7 @@ var BPTreeAsync = class extends BPTree {
1853
1900
  return cache.raw;
1854
1901
  }
1855
1902
  async insertableNode(value) {
1856
- let node = this.root;
1903
+ let node = await this.getNode(this.root.id);
1857
1904
  while (!node.leaf) {
1858
1905
  for (let i = 0, len = node.values.length; i < len; i++) {
1859
1906
  const nValue = node.values[i];
@@ -1995,21 +2042,14 @@ var BPTreeAsync = class extends BPTree {
1995
2042
  [],
1996
2043
  true,
1997
2044
  before.parent,
1998
- before.next,
1999
- before.id
2045
+ null,
2046
+ null
2000
2047
  );
2001
2048
  const mid = Math.ceil(this.order / 2) - 1;
2002
- const beforeNext = before.next;
2003
2049
  after.values = before.values.slice(mid + 1);
2004
2050
  after.keys = before.keys.slice(mid + 1);
2005
2051
  before.values = before.values.slice(0, mid + 1);
2006
2052
  before.keys = before.keys.slice(0, mid + 1);
2007
- before.next = after.id;
2008
- if (beforeNext) {
2009
- const node = await this.getNode(beforeNext);
2010
- node.prev = after.id;
2011
- this.bufferForNodeUpdate(node);
2012
- }
2013
2053
  await this._insertInParent(before, after.values[0], after);
2014
2054
  this.bufferForNodeUpdate(before);
2015
2055
  }
@@ -5290,11 +5330,8 @@ var PageFileSystem = class {
5290
5330
  const chunk = data.subarray(dataOffset, dataOffset + writeSize);
5291
5331
  page.set(chunk, bodyStart + currentOffset);
5292
5332
  const currentUsedSize = currentOffset + writeSize;
5293
- const currentRemaining = manager.getRemainingCapacity(page);
5294
5333
  const newRemaining = bodySize - currentUsedSize;
5295
- if (newRemaining < currentRemaining) {
5296
- manager.setRemainingCapacity(page, newRemaining);
5297
- }
5334
+ manager.setRemainingCapacity(page, newRemaining);
5298
5335
  await this.setPage(currentPageId, page, tx);
5299
5336
  dataOffset += writeSize;
5300
5337
  currentOffset = 0;
@@ -5308,6 +5345,20 @@ var PageFileSystem = class {
5308
5345
  } else {
5309
5346
  currentPageId = nextPageId;
5310
5347
  }
5348
+ } else {
5349
+ let nextPageId = manager.getNextPageId(page);
5350
+ if (nextPageId !== -1) {
5351
+ let pendingFreePageId = nextPageId;
5352
+ while (pendingFreePageId !== -1) {
5353
+ const pendingPage = await this.get(pendingFreePageId, tx);
5354
+ const pendingManager = this.pageFactory.getManager(pendingPage);
5355
+ const next = pendingManager.getNextPageId(pendingPage);
5356
+ await this.setFreePage(pendingFreePageId, tx);
5357
+ pendingFreePageId = next;
5358
+ }
5359
+ manager.setNextPageId(page, -1);
5360
+ await this.setPage(currentPageId, page, tx);
5361
+ }
5311
5362
  }
5312
5363
  }
5313
5364
  }
@@ -5409,7 +5460,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
5409
5460
  const values = this.indexPageManger.getValues(page);
5410
5461
  let res;
5411
5462
  if (isLeaf) res = {
5412
- leaf: isLeaf,
5463
+ leaf: true,
5413
5464
  id: indexId + "",
5414
5465
  parent: parentIndexId ? parentIndexId + "" : null,
5415
5466
  next: nextIndexId ? nextIndexId + "" : null,
@@ -5418,7 +5469,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
5418
5469
  values
5419
5470
  };
5420
5471
  else res = {
5421
- leaf: isLeaf,
5472
+ leaf: false,
5422
5473
  id: indexId + "",
5423
5474
  parent: parentIndexId ? parentIndexId + "" : null,
5424
5475
  next: nextIndexId ? nextIndexId + "" : null,
@@ -5465,7 +5516,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
5465
5516
  }
5466
5517
  async delete(id) {
5467
5518
  const tx = TxContext.get();
5468
- const manager = this.factory.getManagerFromType(PageManager.CONSTANT.PAGE_TYPE_EMPTY);
5519
+ const manager = this.factory.getManagerFromType(PageManager.CONSTANT.PAGE_TYPE_INDEX);
5469
5520
  let pageId = +id;
5470
5521
  while (true) {
5471
5522
  const page = await this.pfs.get(pageId, tx);
@@ -6220,7 +6271,7 @@ var DataplyAPI = class {
6220
6271
  * @param fileHandle File handle
6221
6272
  */
6222
6273
  initializeFile(file, fileHandle, options) {
6223
- const fileData = this.hook.sync.trigger("create", new Uint8Array(), (prepareFileData) => {
6274
+ this.hook.sync.trigger("create", void 0, () => {
6224
6275
  const metadataPageManager = new MetadataPageManager();
6225
6276
  const bitmapPageManager = new BitmapPageManager();
6226
6277
  const dataPageManager = new DataPageManager();
@@ -6255,14 +6306,12 @@ var DataplyAPI = class {
6255
6306
  -1,
6256
6307
  options.pageSize - DataPageManager.CONSTANT.SIZE_PAGE_HEADER
6257
6308
  );
6258
- return new Uint8Array([
6259
- ...prepareFileData,
6309
+ import_node_fs3.default.appendFileSync(fileHandle, new Uint8Array([
6260
6310
  ...metadataPage,
6261
6311
  ...bitmapPage,
6262
6312
  ...dataPage
6263
- ]);
6313
+ ]));
6264
6314
  }, file, fileHandle, options);
6265
- import_node_fs3.default.appendFileSync(fileHandle, fileData);
6266
6315
  }
6267
6316
  /**
6268
6317
  * Opens the database file. If the file does not exist, it initializes it.
@@ -6,7 +6,7 @@ import { TextCodec } from '../utils/TextCodec';
6
6
  import { LockManager } from './transaction/LockManager';
7
7
  import { Transaction } from './transaction/Transaction';
8
8
  interface DataplyAPISyncHook {
9
- create: (fileData: Uint8Array, file: string, fileHandle: number, options: Required<DataplyOptions>) => Uint8Array;
9
+ create: (_: void, file: string, fileHandle: number, options: Required<DataplyOptions>) => void;
10
10
  }
11
11
  interface DataplyAPIAsyncHook {
12
12
  init: () => Promise<void>;
@@ -36,13 +36,13 @@ export declare class DataplyAPI {
36
36
  * @param fileHandle File handle
37
37
  * @returns Whether the page file is a valid Dataply file
38
38
  */
39
- private verifyFormat;
39
+ protected verifyFormat(fileHandle: number): boolean;
40
40
  /**
41
41
  * Fills missing options with default values.
42
42
  * @param options Options
43
43
  * @returns Options filled without omissions
44
44
  */
45
- private verboseOptions;
45
+ protected verboseOptions(options?: DataplyOptions): Required<DataplyOptions>;
46
46
  /**
47
47
  * Initializes the database file.
48
48
  * The first page is initialized as the metadata page.
@@ -50,14 +50,14 @@ export declare class DataplyAPI {
50
50
  * @param file Database file path
51
51
  * @param fileHandle File handle
52
52
  */
53
- private initializeFile;
53
+ protected initializeFile(file: string, fileHandle: number, options: Required<DataplyOptions>): void;
54
54
  /**
55
55
  * Opens the database file. If the file does not exist, it initializes it.
56
56
  * @param file Database file path
57
57
  * @param options Options
58
58
  * @returns File handle
59
59
  */
60
- private createOrOpen;
60
+ protected createOrOpen(file: string, options: Required<DataplyOptions>): number;
61
61
  /**
62
62
  * Initializes the dataply instance.
63
63
  * Must be called before using the dataply instance.
@@ -80,7 +80,7 @@ export declare class DataplyAPI {
80
80
  * @param tx The transaction to use. If not provided, a new transaction is created.
81
81
  * @returns The result of the callback function.
82
82
  */
83
- private runWithDefault;
83
+ protected runWithDefault<T>(callback: (tx: Transaction) => Promise<T>, tx?: Transaction): Promise<T>;
84
84
  /**
85
85
  * Retrieves metadata from the dataply.
86
86
  * @returns Metadata of the dataply.
@@ -0,0 +1,6 @@
1
+ import { BPTreeAsync } from 'serializable-bptree';
2
+ export declare class RowIndexBPTree<K, V, C> extends BPTreeAsync<K, V> {
3
+ private _bindContext?;
4
+ bindContext(context?: C): void;
5
+ getContext(): C | undefined;
6
+ }
@@ -2,6 +2,7 @@ export * from 'serializable-bptree';
2
2
  export * from 'ryoiki';
3
3
  export * from 'cache-entanglement';
4
4
  export type { DataplyOptions } from './types';
5
+ export type * from './core/Page';
5
6
  export { Dataply } from './core/Dataply';
6
7
  export { DataplyAPI } from './core/DataplyAPI';
7
8
  export { Transaction } from './core/transaction/Transaction';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataply",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "A lightweight storage engine for Node.js with support for MVCC, WAL.",
5
5
  "license": "MIT",
6
6
  "author": "izure <admin@izure.org>",
@@ -47,6 +47,6 @@
47
47
  "cache-entanglement": "^1.7.1",
48
48
  "hookall": "^2.2.0",
49
49
  "ryoiki": "^1.2.0",
50
- "serializable-bptree": "^5.2.1"
50
+ "serializable-bptree": "^6.0.2"
51
51
  }
52
- }
52
+ }