dataply 0.0.26-alpha.10 → 0.0.26-alpha.12

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
@@ -2191,13 +2191,7 @@ function insertOp(ops, ctx, key, value, comparator) {
2191
2191
  }
2192
2192
  function deleteEntry(ops, ctx, node, key, comparator) {
2193
2193
  if (!node.leaf) {
2194
- let keyIndex = -1;
2195
- for (let i = 0, len = node.keys.length; i < len; i++) {
2196
- if (node.keys[i] === key) {
2197
- keyIndex = i;
2198
- break;
2199
- }
2200
- }
2194
+ let keyIndex = node.keys.indexOf(key);
2201
2195
  if (keyIndex !== -1) {
2202
2196
  node = cloneNode(node);
2203
2197
  node.keys.splice(keyIndex, 1);
@@ -2236,17 +2230,15 @@ function deleteEntry(ops, ctx, node, key, comparator) {
2236
2230
  let nextNode = null;
2237
2231
  let prevValue = null;
2238
2232
  let postValue = null;
2239
- for (let i = 0, len = parentNode.keys.length; i < len; i++) {
2240
- const nKey = parentNode.keys[i];
2241
- if (nKey === node.id) {
2242
- if (i > 0) {
2243
- prevNode = ops.getNode(parentNode.keys[i - 1]);
2244
- prevValue = parentNode.values[i - 1];
2245
- }
2246
- if (i < parentNode.keys.length - 1) {
2247
- nextNode = ops.getNode(parentNode.keys[i + 1]);
2248
- postValue = parentNode.values[i];
2249
- }
2233
+ let keyIndex = parentNode.keys.indexOf(node.id);
2234
+ if (keyIndex !== -1) {
2235
+ if (keyIndex > 0) {
2236
+ prevNode = ops.getNode(parentNode.keys[keyIndex - 1]);
2237
+ prevValue = parentNode.values[keyIndex - 1];
2238
+ }
2239
+ if (keyIndex < parentNode.keys.length - 1) {
2240
+ nextNode = ops.getNode(parentNode.keys[keyIndex + 1]);
2241
+ postValue = parentNode.values[keyIndex];
2250
2242
  }
2251
2243
  }
2252
2244
  let siblingNode;
@@ -2279,7 +2271,7 @@ function deleteEntry(ops, ctx, node, key, comparator) {
2279
2271
  siblingNode = node;
2280
2272
  node = pTemp;
2281
2273
  }
2282
- siblingNode.keys.push(...node.keys);
2274
+ siblingNode.keys = siblingNode.keys.concat(node.keys);
2283
2275
  if (!node.leaf) {
2284
2276
  siblingNode.values.push(guess);
2285
2277
  } else {
@@ -2290,7 +2282,7 @@ function deleteEntry(ops, ctx, node, key, comparator) {
2290
2282
  ops.updateNode(n);
2291
2283
  }
2292
2284
  }
2293
- siblingNode.values.push(...node.values);
2285
+ siblingNode.values = siblingNode.values.concat(node.values);
2294
2286
  if (!siblingNode.leaf) {
2295
2287
  const keys = siblingNode.keys;
2296
2288
  for (let i = 0, len = keys.length; i < len; i++) {
@@ -2338,8 +2330,8 @@ function deleteEntry(ops, ctx, node, key, comparator) {
2338
2330
  if (!node.leaf) {
2339
2331
  pointerP0 = siblingNode.keys.splice(0, 1)[0];
2340
2332
  pointerK0 = siblingNode.values.splice(0, 1)[0];
2341
- node.keys = [...node.keys, pointerP0];
2342
- node.values = [...node.values, guess];
2333
+ node.keys = node.keys.concat(pointerP0);
2334
+ node.values = node.values.concat(guess);
2343
2335
  parentNode = cloneNode(ops.getNode(node.parent));
2344
2336
  const pointerIndex = parentNode.keys.indexOf(siblingNode.id);
2345
2337
  if (pointerIndex > 0) {
@@ -2349,8 +2341,8 @@ function deleteEntry(ops, ctx, node, key, comparator) {
2349
2341
  } else {
2350
2342
  pointerP0 = siblingNode.keys.splice(0, 1)[0];
2351
2343
  pointerK0 = siblingNode.values.splice(0, 1)[0];
2352
- node.keys = [...node.keys, pointerP0];
2353
- node.values = [...node.values, pointerK0];
2344
+ node.keys = node.keys.concat(pointerP0);
2345
+ node.values = node.values.concat(pointerK0);
2354
2346
  parentNode = cloneNode(ops.getNode(node.parent));
2355
2347
  const pointerIndex = parentNode.keys.indexOf(siblingNode.id);
2356
2348
  if (pointerIndex > 0) {
@@ -4221,13 +4213,7 @@ async function insertOpAsync(ops, ctx, key, value, comparator) {
4221
4213
  }
4222
4214
  async function deleteEntryAsync(ops, ctx, node, key, comparator) {
4223
4215
  if (!node.leaf) {
4224
- let keyIndex = -1;
4225
- for (let i = 0, len = node.keys.length; i < len; i++) {
4226
- if (node.keys[i] === key) {
4227
- keyIndex = i;
4228
- break;
4229
- }
4230
- }
4216
+ let keyIndex = node.keys.indexOf(key);
4231
4217
  if (keyIndex !== -1) {
4232
4218
  node = cloneNode(node);
4233
4219
  node.keys.splice(keyIndex, 1);
@@ -4256,16 +4242,15 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
4256
4242
  let nextNode = null;
4257
4243
  let prevValue = null;
4258
4244
  let postValue = null;
4259
- for (let i = 0, len = parentNode.keys.length; i < len; i++) {
4260
- if (parentNode.keys[i] === node.id) {
4261
- if (i > 0) {
4262
- prevNode = await ops.getNode(parentNode.keys[i - 1]);
4263
- prevValue = parentNode.values[i - 1];
4264
- }
4265
- if (i < parentNode.keys.length - 1) {
4266
- nextNode = await ops.getNode(parentNode.keys[i + 1]);
4267
- postValue = parentNode.values[i];
4268
- }
4245
+ let keyIndex = parentNode.keys.indexOf(node.id);
4246
+ if (keyIndex !== -1) {
4247
+ if (keyIndex > 0) {
4248
+ prevNode = await ops.getNode(parentNode.keys[keyIndex - 1]);
4249
+ prevValue = parentNode.values[keyIndex - 1];
4250
+ }
4251
+ if (keyIndex < parentNode.keys.length - 1) {
4252
+ nextNode = await ops.getNode(parentNode.keys[keyIndex + 1]);
4253
+ postValue = parentNode.values[keyIndex];
4269
4254
  }
4270
4255
  }
4271
4256
  let siblingNode;
@@ -4292,11 +4277,11 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
4292
4277
  siblingNode = cloneNode(siblingNode);
4293
4278
  if (node.values.length + siblingNode.values.length < ctx.order) {
4294
4279
  if (!isPredecessor) {
4295
- const t = siblingNode;
4280
+ const pTemp = siblingNode;
4296
4281
  siblingNode = node;
4297
- node = t;
4282
+ node = pTemp;
4298
4283
  }
4299
- siblingNode.keys.push(...node.keys);
4284
+ siblingNode.keys = siblingNode.keys.concat(node.keys);
4300
4285
  if (!node.leaf) {
4301
4286
  siblingNode.values.push(guess);
4302
4287
  } else {
@@ -4307,7 +4292,7 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
4307
4292
  await ops.updateNode(n);
4308
4293
  }
4309
4294
  }
4310
- siblingNode.values.push(...node.values);
4295
+ siblingNode.values = siblingNode.values.concat(node.values);
4311
4296
  if (!siblingNode.leaf) {
4312
4297
  for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
4313
4298
  const n = cloneNode(await ops.getNode(siblingNode.keys[i]));
@@ -4351,8 +4336,8 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
4351
4336
  if (!node.leaf) {
4352
4337
  pointerP0 = siblingNode.keys.splice(0, 1)[0];
4353
4338
  pointerK0 = siblingNode.values.splice(0, 1)[0];
4354
- node.keys = [...node.keys, pointerP0];
4355
- node.values = [...node.values, guess];
4339
+ node.keys = node.keys.concat(pointerP0);
4340
+ node.values = node.values.concat(guess);
4356
4341
  parentNode = cloneNode(await ops.getNode(node.parent));
4357
4342
  const pi = parentNode.keys.indexOf(siblingNode.id);
4358
4343
  if (pi > 0) {
@@ -4362,8 +4347,8 @@ async function deleteEntryAsync(ops, ctx, node, key, comparator) {
4362
4347
  } else {
4363
4348
  pointerP0 = siblingNode.keys.splice(0, 1)[0];
4364
4349
  pointerK0 = siblingNode.values.splice(0, 1)[0];
4365
- node.keys = [...node.keys, pointerP0];
4366
- node.values = [...node.values, pointerK0];
4350
+ node.keys = node.keys.concat(pointerP0);
4351
+ node.values = node.values.concat(pointerK0);
4367
4352
  parentNode = cloneNode(await ops.getNode(node.parent));
4368
4353
  const pi = parentNode.keys.indexOf(siblingNode.id);
4369
4354
  if (pi > 0) {
@@ -5023,9 +5008,14 @@ var BPTreePureSync = class {
5023
5008
  }
5024
5009
  _createReadOps() {
5025
5010
  const strategy = this.strategy;
5011
+ const readBuffer = /* @__PURE__ */ new Map();
5026
5012
  return {
5027
5013
  getNode(id) {
5028
- return strategy.read(id);
5014
+ const buffered = readBuffer.get(id);
5015
+ if (buffered) return buffered;
5016
+ const node = strategy.read(id);
5017
+ readBuffer.set(id, node);
5018
+ return node;
5029
5019
  },
5030
5020
  createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5031
5021
  const id = strategy.id(leaf);
@@ -5045,6 +5035,7 @@ var BPTreePureSync = class {
5045
5035
  }
5046
5036
  _createBufferedOps() {
5047
5037
  const strategy = this.strategy;
5038
+ const readBuffer = /* @__PURE__ */ new Map();
5048
5039
  const writeBuffer = /* @__PURE__ */ new Map();
5049
5040
  const deleteBuffer = /* @__PURE__ */ new Set();
5050
5041
  let headBuffer = null;
@@ -5052,7 +5043,11 @@ var BPTreePureSync = class {
5052
5043
  getNode(id) {
5053
5044
  const buffered = writeBuffer.get(id);
5054
5045
  if (buffered) return buffered;
5055
- return strategy.read(id);
5046
+ const read = readBuffer.get(id);
5047
+ if (read) return read;
5048
+ const node = strategy.read(id);
5049
+ readBuffer.set(id, node);
5050
+ return node;
5056
5051
  },
5057
5052
  createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5058
5053
  const id = strategy.id(leaf);
@@ -5085,6 +5080,10 @@ var BPTreePureSync = class {
5085
5080
  if (headBuffer) {
5086
5081
  strategy.writeHead(headBuffer);
5087
5082
  }
5083
+ readBuffer.clear();
5084
+ writeBuffer.clear();
5085
+ deleteBuffer.clear();
5086
+ headBuffer = null;
5088
5087
  }
5089
5088
  return { ops, flush };
5090
5089
  }
@@ -5266,9 +5265,14 @@ var BPTreePureAsync = class {
5266
5265
  }
5267
5266
  _createReadOps() {
5268
5267
  const strategy = this.strategy;
5268
+ const readBuffer = /* @__PURE__ */ new Map();
5269
5269
  return {
5270
5270
  async getNode(id) {
5271
- return await strategy.read(id);
5271
+ const buffered = readBuffer.get(id);
5272
+ if (buffered) return buffered;
5273
+ const node = await strategy.read(id);
5274
+ readBuffer.set(id, node);
5275
+ return node;
5272
5276
  },
5273
5277
  async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5274
5278
  const id = await strategy.id(leaf);
@@ -5288,6 +5292,7 @@ var BPTreePureAsync = class {
5288
5292
  }
5289
5293
  _createBufferedOps() {
5290
5294
  const strategy = this.strategy;
5295
+ const readBuffer = /* @__PURE__ */ new Map();
5291
5296
  const writeBuffer = /* @__PURE__ */ new Map();
5292
5297
  const deleteBuffer = /* @__PURE__ */ new Set();
5293
5298
  let headBuffer = null;
@@ -5295,7 +5300,11 @@ var BPTreePureAsync = class {
5295
5300
  async getNode(id) {
5296
5301
  const buffered = writeBuffer.get(id);
5297
5302
  if (buffered) return buffered;
5298
- return await strategy.read(id);
5303
+ const read = readBuffer.get(id);
5304
+ if (read) return read;
5305
+ const node = await strategy.read(id);
5306
+ readBuffer.set(id, node);
5307
+ return node;
5299
5308
  },
5300
5309
  async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5301
5310
  const id = await strategy.id(leaf);
@@ -5328,6 +5337,10 @@ var BPTreePureAsync = class {
5328
5337
  if (headBuffer) {
5329
5338
  await strategy.writeHead(headBuffer);
5330
5339
  }
5340
+ readBuffer.clear();
5341
+ writeBuffer.clear();
5342
+ deleteBuffer.clear();
5343
+ headBuffer = null;
5331
5344
  }
5332
5345
  return { ops, flush };
5333
5346
  }
@@ -9916,7 +9929,7 @@ var PageFileSystem = class {
9916
9929
  * @param tx Transaction
9917
9930
  */
9918
9931
  async updateBitmap(pageId, isFree, tx) {
9919
- const metadata = await this.getMetadata(tx);
9932
+ const metadata = await this.getMetadata(false, tx);
9920
9933
  const metadataManager = this.pageFactory.getManager(metadata);
9921
9934
  const bitmapPageId = metadataManager.getBitmapPageId(metadata);
9922
9935
  const headerSize = PageManager.CONSTANT.SIZE_PAGE_HEADER;
@@ -9924,7 +9937,7 @@ var PageFileSystem = class {
9924
9937
  let currentBitmapPageId = bitmapPageId;
9925
9938
  let targetBitIndex = pageId;
9926
9939
  while (targetBitIndex >= capacityPerBitmapPage) {
9927
- const currentBitmapPage = await this.get(currentBitmapPageId, tx);
9940
+ const currentBitmapPage = await this.get(currentBitmapPageId, true, tx);
9928
9941
  const manager = this.pageFactory.getManager(currentBitmapPage);
9929
9942
  targetBitIndex -= capacityPerBitmapPage;
9930
9943
  const nextPageId = manager.getNextPageId(currentBitmapPage);
@@ -9941,7 +9954,7 @@ var PageFileSystem = class {
9941
9954
  }
9942
9955
  }
9943
9956
  await tx.__acquireWriteLock(currentBitmapPageId);
9944
- const targetBitmapPage = await this.get(currentBitmapPageId, tx);
9957
+ const targetBitmapPage = await this.get(currentBitmapPageId, true, tx);
9945
9958
  const bitmapManager = this.pageFactory.getManager(targetBitmapPage);
9946
9959
  bitmapManager.setBit(targetBitmapPage, targetBitIndex, isFree);
9947
9960
  await this.setPage(currentBitmapPageId, targetBitmapPage, tx);
@@ -9960,20 +9973,22 @@ var PageFileSystem = class {
9960
9973
  }
9961
9974
  /**
9962
9975
  * @param pageIndex 페이지 인덱스
9976
+ * @param copy Copy-on-Read
9963
9977
  * @param tx 트랜잭션
9964
9978
  * @returns 페이지 버퍼
9965
9979
  */
9966
- async get(pageIndex, tx) {
9967
- return tx.__readPage(pageIndex);
9980
+ async get(pageIndex, copy, tx) {
9981
+ return tx.__readPage(pageIndex, copy);
9968
9982
  }
9969
9983
  /**
9970
9984
  * Reads the page header.
9971
9985
  * @param pageIndex Page index
9986
+ * @param copy Copy-on-Read
9972
9987
  * @param tx Transaction
9973
9988
  * @returns Page header buffer
9974
9989
  */
9975
- async getHeader(pageIndex, tx) {
9976
- const page = await this.get(pageIndex, tx);
9990
+ async getHeader(pageIndex, copy, tx) {
9991
+ const page = await this.get(pageIndex, copy, tx);
9977
9992
  return page.subarray(0, PageManager.CONSTANT.SIZE_PAGE_HEADER);
9978
9993
  }
9979
9994
  /**
@@ -9984,7 +9999,7 @@ var PageFileSystem = class {
9984
9999
  * @returns Page body buffer
9985
10000
  */
9986
10001
  async getBody(pageIndex, recursive = false, tx) {
9987
- const page = await this.get(pageIndex, tx);
10002
+ const page = await this.get(pageIndex, false, tx);
9988
10003
  const manager = this.pageFactory.getManager(page);
9989
10004
  const fullBody = manager.getBody(page);
9990
10005
  if (!recursive) {
@@ -10002,11 +10017,12 @@ var PageFileSystem = class {
10002
10017
  }
10003
10018
  /**
10004
10019
  * Returns the metadata page.
10020
+ * @param copy Copy-on-Read
10005
10021
  * @param tx Transaction
10006
10022
  * @returns Metadata page
10007
10023
  */
10008
- async getMetadata(tx) {
10009
- const page = await this.get(0, tx);
10024
+ async getMetadata(copy, tx) {
10025
+ const page = await this.get(0, copy, tx);
10010
10026
  if (!MetadataPageManager.IsMetadataPage(page)) {
10011
10027
  throw new Error("Invalid metadata page");
10012
10028
  }
@@ -10018,20 +10034,21 @@ var PageFileSystem = class {
10018
10034
  * @returns Number of pages
10019
10035
  */
10020
10036
  async getPageCount(tx) {
10021
- const metadata = await this.getMetadata(tx);
10037
+ const metadata = await this.getMetadata(false, tx);
10022
10038
  const manager = this.pageFactory.getManager(metadata);
10023
10039
  return manager.getPageCount(metadata);
10024
10040
  }
10025
10041
  /**
10026
10042
  * Returns the root index page.
10043
+ * @param copy Copy-on-Read
10027
10044
  * @param tx Transaction
10028
10045
  * @returns Root index page
10029
10046
  */
10030
- async getRootIndex(tx) {
10031
- const metadata = await this.getMetadata(tx);
10047
+ async getRootIndex(copy, tx) {
10048
+ const metadata = await this.getMetadata(false, tx);
10032
10049
  const manager = this.pageFactory.getManager(metadata);
10033
10050
  const rootIndexPageId = manager.getRootIndexPageId(metadata);
10034
- const rootIndexPage = await this.get(rootIndexPageId, tx);
10051
+ const rootIndexPage = await this.get(rootIndexPageId, copy, tx);
10035
10052
  if (!IndexPageManager.IsIndexPage(rootIndexPage)) {
10036
10053
  throw new Error("Invalid root index page");
10037
10054
  }
@@ -10066,12 +10083,12 @@ var PageFileSystem = class {
10066
10083
  async appendNewPage(pageType = PageManager.CONSTANT.PAGE_TYPE_EMPTY, tx) {
10067
10084
  this.logger.debug(`Appending new page of type ${pageType}`);
10068
10085
  await tx.__acquireWriteLock(0);
10069
- const metadata = await this.getMetadata(tx);
10086
+ const metadata = await this.getMetadata(true, tx);
10070
10087
  const metadataManager = this.pageFactory.getManager(metadata);
10071
10088
  const freePageId = metadataManager.getFreePageId(metadata);
10072
10089
  if (freePageId !== -1) {
10073
10090
  const reusedPageId = freePageId;
10074
- const reusedPage = await this.get(reusedPageId, tx);
10091
+ const reusedPage = await this.get(reusedPageId, false, tx);
10075
10092
  const reusedPageManager = this.pageFactory.getManager(reusedPage);
10076
10093
  const nextFreePageId = reusedPageManager.getNextPageId(reusedPage);
10077
10094
  metadataManager.setFreePageId(metadata, nextFreePageId);
@@ -10116,7 +10133,7 @@ var PageFileSystem = class {
10116
10133
  let currentOffset = offset;
10117
10134
  let dataOffset = 0;
10118
10135
  while (dataOffset < data.length) {
10119
- const page = await this.get(currentPageId, tx);
10136
+ const page = await this.get(currentPageId, true, tx);
10120
10137
  const manager = this.pageFactory.getManager(page);
10121
10138
  const bodyStart = PageManager.CONSTANT.SIZE_PAGE_HEADER;
10122
10139
  const bodySize = this.pageSize - bodyStart;
@@ -10176,7 +10193,7 @@ var PageFileSystem = class {
10176
10193
  break;
10177
10194
  }
10178
10195
  visited.add(currentPageId);
10179
- const page = await this.get(currentPageId, tx);
10196
+ const page = await this.get(currentPageId, false, tx);
10180
10197
  const nextPageId = this.pageFactory.getManager(page).getNextPageId(page);
10181
10198
  await this.setFreePage(currentPageId, tx);
10182
10199
  currentPageId = nextPageId;
@@ -10192,7 +10209,7 @@ var PageFileSystem = class {
10192
10209
  if (pageId <= 0) return;
10193
10210
  await tx.__acquireWriteLock(0);
10194
10211
  await tx.__acquireWriteLock(pageId);
10195
- const metadata = await this.getMetadata(tx);
10212
+ const metadata = await this.getMetadata(true, tx);
10196
10213
  const metadataManager = this.pageFactory.getManager(metadata);
10197
10214
  const currentHeadFreePageId = metadataManager.getFreePageId(metadata);
10198
10215
  const emptyPageManager = this.pageFactory.getManagerFromType(PageManager.CONSTANT.PAGE_TYPE_EMPTY);
@@ -10275,12 +10292,12 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
10275
10292
  async id(isLeaf) {
10276
10293
  const tx = this.txContext.get();
10277
10294
  await tx.__acquireWriteLock(0);
10278
- const metadata = await this.pfs.getMetadata(tx);
10295
+ const metadata = await this.pfs.getMetadata(true, tx);
10279
10296
  const metadataManager = this.factory.getManager(metadata);
10280
10297
  const freePageId = metadataManager.getFreePageId(metadata);
10281
10298
  let pageId;
10282
10299
  if (freePageId !== -1) {
10283
- const freePage = await this.pfs.get(freePageId, tx);
10300
+ const freePage = await this.pfs.get(freePageId, false, tx);
10284
10301
  const freePageManager = this.factory.getManager(freePage);
10285
10302
  const nextFreePageId = freePageManager.getNextPageId(freePage);
10286
10303
  metadataManager.setFreePageId(metadata, nextFreePageId);
@@ -10296,7 +10313,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
10296
10313
  async read(id) {
10297
10314
  const tx = this.txContext.get();
10298
10315
  const pageId = +id;
10299
- const page = await this.pfs.get(pageId, tx);
10316
+ const page = await this.pfs.get(pageId, false, tx);
10300
10317
  if (!IndexPageManager.IsIndexPage(page)) {
10301
10318
  throw new Error(`Node ${id} does not exist - not a valid index page`);
10302
10319
  }
@@ -10331,7 +10348,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
10331
10348
  async write(id, node) {
10332
10349
  const tx = this.txContext.get();
10333
10350
  const pageId = +id;
10334
- let page = await this.pfs.get(pageId, tx);
10351
+ let page = await this.pfs.get(pageId, true, tx);
10335
10352
  if (!IndexPageManager.IsIndexPage(page)) {
10336
10353
  page = this.indexPageManger.create(this.pfs.pageSize, pageId);
10337
10354
  }
@@ -10379,7 +10396,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
10379
10396
  }
10380
10397
  async readHead() {
10381
10398
  const tx = this.txContext.get();
10382
- const metadataPage = await this.pfs.getMetadata(tx);
10399
+ const metadataPage = await this.pfs.getMetadata(false, tx);
10383
10400
  const manager = this.factory.getManager(metadataPage);
10384
10401
  const rootIndexPageId = manager.getRootIndexPageId(metadataPage);
10385
10402
  if (rootIndexPageId === -1) {
@@ -10399,7 +10416,7 @@ var RowIdentifierStrategy = class extends SerializeStrategyAsync {
10399
10416
  if (root === null) {
10400
10417
  throw new Error("");
10401
10418
  }
10402
- const metadataPage = await this.pfs.getMetadata(tx);
10419
+ const metadataPage = await this.pfs.getMetadata(true, tx);
10403
10420
  const manager = this.factory.getManager(metadataPage);
10404
10421
  manager.setRootIndexPageId(metadataPage, +root);
10405
10422
  manager.setRootIndexOrder(metadataPage, order);
@@ -10560,7 +10577,7 @@ var RowTableEngine = class {
10560
10577
  if (!this.initialized) {
10561
10578
  throw new Error("RowTableEngine instance is not initialized");
10562
10579
  }
10563
- const metadataPage = await this.pfs.getMetadata(tx);
10580
+ const metadataPage = await this.pfs.getMetadata(false, tx);
10564
10581
  const manager = this.factory.getManagerFromType(MetadataPageManager.CONSTANT.PAGE_TYPE_METADATA);
10565
10582
  const pageSize = manager.getPageSize(metadataPage);
10566
10583
  const pageCount = manager.getPageCount(metadataPage);
@@ -10588,10 +10605,10 @@ var RowTableEngine = class {
10588
10605
  }
10589
10606
  await tx.__acquireWriteLock(0);
10590
10607
  const pks = [];
10591
- const metadataPage = await this.pfs.getMetadata(tx);
10608
+ const metadataPage = await this.pfs.getMetadata(false, tx);
10592
10609
  let lastPk = this.metadataPageManager.getLastRowPk(metadataPage);
10593
10610
  let lastInsertDataPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
10594
- let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, tx);
10611
+ let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, true, tx);
10595
10612
  if (!this.factory.isDataPage(lastInsertDataPage)) {
10596
10613
  throw new Error(`Last insert page is not data page`);
10597
10614
  }
@@ -10613,7 +10630,7 @@ var RowTableEngine = class {
10613
10630
  await this.pfs.setPage(lastInsertDataPageId, lastInsertDataPage, tx);
10614
10631
  } else {
10615
10632
  const newPageId = await this.pfs.appendNewPage(this.dataPageManager.pageType, tx);
10616
- const newPage = await this.pfs.get(newPageId, tx);
10633
+ const newPage = await this.pfs.get(newPageId, true, tx);
10617
10634
  this.dataPageManager.insert(newPage, row);
10618
10635
  this.setRID(newPageId, 0);
10619
10636
  lastInsertDataPageId = newPageId;
@@ -10628,7 +10645,7 @@ var RowTableEngine = class {
10628
10645
  this.rowManager.setBody(row, data);
10629
10646
  if (slotIndex === -1) {
10630
10647
  const newPageId = await this.pfs.appendNewPage(this.dataPageManager.pageType, tx);
10631
- const newPage = await this.pfs.get(newPageId, tx);
10648
+ const newPage = await this.pfs.get(newPageId, true, tx);
10632
10649
  this.dataPageManager.insert(newPage, row);
10633
10650
  this.setRID(newPageId, 0);
10634
10651
  lastInsertDataPageId = newPageId;
@@ -10644,7 +10661,7 @@ var RowTableEngine = class {
10644
10661
  pks.push(pk);
10645
10662
  }
10646
10663
  await this.bptree.batchInsert(batchInsertData);
10647
- const freshMetadataPage = await this.pfs.getMetadata(tx);
10664
+ const freshMetadataPage = await this.pfs.getMetadata(true, tx);
10648
10665
  this.metadataPageManager.setLastInsertPageId(freshMetadataPage, lastInsertDataPageId);
10649
10666
  this.metadataPageManager.setLastRowPk(freshMetadataPage, lastPk);
10650
10667
  if (incrementRowCount) {
@@ -10690,7 +10707,7 @@ var RowTableEngine = class {
10690
10707
  this.keyManager.setBufferFromKey(rid, this.ridBuffer);
10691
10708
  const pageId = this.keyManager.getPageId(this.ridBuffer);
10692
10709
  const slotIndex = this.keyManager.getSlotIndex(this.ridBuffer);
10693
- const page = await this.pfs.get(pageId, tx);
10710
+ const page = await this.pfs.get(pageId, true, tx);
10694
10711
  if (!this.factory.isDataPage(page)) {
10695
10712
  throw new Error(`RID not found for PK: ${pk}`);
10696
10713
  }
@@ -10726,22 +10743,22 @@ var RowTableEngine = class {
10726
10743
  this.rowManager.setBodySize(newRow, newBodySize);
10727
10744
  this.rowManager.setBody(newRow, data);
10728
10745
  await tx.__acquireWriteLock(0);
10729
- const metadataPage = await this.pfs.getMetadata(tx);
10746
+ const metadataPage = await this.pfs.getMetadata(false, tx);
10730
10747
  let lastInsertDataPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
10731
- let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, tx);
10748
+ let lastInsertDataPage = await this.pfs.get(lastInsertDataPageId, true, tx);
10732
10749
  if (!this.factory.isDataPage(lastInsertDataPage)) {
10733
10750
  throw new Error("Last insert page is not data page");
10734
10751
  }
10735
10752
  let newSlotIndex = this.dataPageManager.getNextSlotIndex(lastInsertDataPage, newRow);
10736
10753
  if (newSlotIndex === -1) {
10737
10754
  const newPageId = await this.pfs.appendNewPage(this.dataPageManager.pageType, tx);
10738
- lastInsertDataPage = await this.pfs.get(newPageId, tx);
10755
+ lastInsertDataPage = await this.pfs.get(newPageId, true, tx);
10739
10756
  lastInsertDataPageId = newPageId;
10740
10757
  newSlotIndex = 0;
10741
10758
  }
10742
10759
  this.dataPageManager.insert(lastInsertDataPage, newRow);
10743
10760
  await this.pfs.setPage(lastInsertDataPageId, lastInsertDataPage, tx);
10744
- const targetPage = await this.pfs.get(pageId, tx);
10761
+ const targetPage = await this.pfs.get(pageId, true, tx);
10745
10762
  if (!this.factory.isDataPage(targetPage)) {
10746
10763
  throw new Error("Target page is not data page");
10747
10764
  }
@@ -10754,7 +10771,7 @@ var RowTableEngine = class {
10754
10771
  const newRidNumeric = this.getRID();
10755
10772
  await this.bptree.delete(oldRidNumeric, pk);
10756
10773
  await this.bptree.insert(newRidNumeric, pk);
10757
- const freshMetadataPage = await this.pfs.getMetadata(tx);
10774
+ const freshMetadataPage = await this.pfs.getMetadata(true, tx);
10758
10775
  this.metadataPageManager.setLastInsertPageId(freshMetadataPage, lastInsertDataPageId);
10759
10776
  await this.pfs.setMetadata(freshMetadataPage, tx);
10760
10777
  }
@@ -10774,7 +10791,7 @@ var RowTableEngine = class {
10774
10791
  this.keyManager.setBufferFromKey(rid, this.ridBuffer);
10775
10792
  const pageId = this.keyManager.getPageId(this.ridBuffer);
10776
10793
  const slotIndex = this.keyManager.getSlotIndex(this.ridBuffer);
10777
- const page = await this.pfs.get(pageId, tx);
10794
+ const page = await this.pfs.get(pageId, true, tx);
10778
10795
  if (!this.factory.isDataPage(page)) {
10779
10796
  throw new Error(`RID not found for PK: ${pk}`);
10780
10797
  }
@@ -10790,14 +10807,14 @@ var RowTableEngine = class {
10790
10807
  await this.pfs.setPage(pageId, page, tx);
10791
10808
  await this.bptree.delete(rid, pk);
10792
10809
  if (decrementRowCount) {
10793
- const metadataPage2 = await this.pfs.getMetadata(tx);
10810
+ const metadataPage2 = await this.pfs.getMetadata(true, tx);
10794
10811
  const currentRowCount = this.metadataPageManager.getRowCount(metadataPage2);
10795
10812
  this.metadataPageManager.setRowCount(metadataPage2, currentRowCount - 1);
10796
10813
  await this.pfs.setMetadata(metadataPage2, tx);
10797
10814
  }
10798
10815
  const insertedRowCount = this.dataPageManager.getInsertedRowCount(page);
10799
10816
  let allDeleted = true;
10800
- const metadataPage = await this.pfs.getMetadata(tx);
10817
+ const metadataPage = await this.pfs.getMetadata(false, tx);
10801
10818
  const lastInsertPageId = this.metadataPageManager.getLastInsertPageId(metadataPage);
10802
10819
  if (pageId === lastInsertPageId) {
10803
10820
  allDeleted = false;
@@ -10903,7 +10920,7 @@ var RowTableEngine = class {
10903
10920
  const sortedPageIds = Array.from(collections.keys()).sort((a, b) => a - b);
10904
10921
  await Promise.all(sortedPageIds.map(async (pageId) => {
10905
10922
  const items = collections.get(pageId);
10906
- const page = await this.pfs.get(pageId, tx);
10923
+ const page = await this.pfs.get(pageId, false, tx);
10907
10924
  if (!this.factory.isDataPage(page)) {
10908
10925
  throw new Error(`Page ${pageId} is not a data page`);
10909
10926
  }
@@ -10928,7 +10945,7 @@ var RowTableEngine = class {
10928
10945
  this.keyManager.setBufferFromKey(rid, this.ridBuffer);
10929
10946
  const pageId = this.keyManager.getPageId(this.ridBuffer);
10930
10947
  const slotIndex = this.keyManager.getSlotIndex(this.ridBuffer);
10931
- const page = await this.pfs.get(pageId, tx);
10948
+ const page = await this.pfs.get(pageId, false, tx);
10932
10949
  if (!this.factory.isDataPage(page)) {
10933
10950
  throw new Error(`RID not found for PK: ${pk}`);
10934
10951
  }
@@ -10938,7 +10955,7 @@ var RowTableEngine = class {
10938
10955
  return null;
10939
10956
  } else if (this.rowManager.getOverflowFlag(row)) {
10940
10957
  const overflowPageId = bytesToNumber(this.rowManager.getBody(row));
10941
- const overflowPage = await this.pfs.get(overflowPageId, tx);
10958
+ const overflowPage = await this.pfs.get(overflowPageId, false, tx);
10942
10959
  if (!this.factory.isOverflowPage(overflowPage)) {
10943
10960
  throw new Error(`Overflow page not found for RID: ${rid}`);
10944
10961
  }
@@ -10952,7 +10969,7 @@ var RowTableEngine = class {
10952
10969
  * @returns Row count
10953
10970
  */
10954
10971
  async getRowCount(tx) {
10955
- const metadataPage = await this.pfs.getMetadata(tx);
10972
+ const metadataPage = await this.pfs.getMetadata(false, tx);
10956
10973
  return this.metadataPageManager.getRowCount(metadataPage);
10957
10974
  }
10958
10975
  };
@@ -11063,16 +11080,20 @@ var Transaction = class {
11063
11080
  /**
11064
11081
  * Reads a page through the MVCC transaction.
11065
11082
  * @param pageId Page ID
11083
+ * @param copy Copy-on-Read
11066
11084
  * @returns Page data
11067
11085
  */
11068
- async __readPage(pageId) {
11086
+ async __readPage(pageId, copy) {
11069
11087
  const data = await this.mvccTx.read(pageId);
11070
11088
  if (data === null) {
11071
11089
  return new Uint8Array(this.pfs.pageSize);
11072
11090
  }
11073
- const copy = new Uint8Array(data.length);
11074
- copy.set(data);
11075
- return copy;
11091
+ if (copy) {
11092
+ const copy2 = new Uint8Array(data.length);
11093
+ copy2.set(data);
11094
+ return copy2;
11095
+ }
11096
+ return data;
11076
11097
  }
11077
11098
  /**
11078
11099
  * Writes a page through the MVCC transaction.
@@ -11082,9 +11103,7 @@ var Transaction = class {
11082
11103
  async __writePage(pageId, data) {
11083
11104
  const exists = await this.mvccTx.exists(pageId);
11084
11105
  if (exists) {
11085
- const copy = new Uint8Array(data.length);
11086
- copy.set(data);
11087
- await this.mvccTx.write(pageId, copy);
11106
+ await this.mvccTx.write(pageId, data);
11088
11107
  } else {
11089
11108
  await this.mvccTx.create(pageId, data);
11090
11109
  }
@@ -11490,7 +11509,7 @@ var DataplyAPI = class {
11490
11509
  * @returns The result of the callback.
11491
11510
  */
11492
11511
  async withWriteTransaction(callback, tx) {
11493
- this.logger.debug("Running with default write transaction");
11512
+ this.logger.debug("Running with write transaction");
11494
11513
  if (!tx) {
11495
11514
  const release = await this.acquireWriteLock();
11496
11515
  const internalTx = this.createTransaction();
@@ -11514,7 +11533,7 @@ var DataplyAPI = class {
11514
11533
  return result;
11515
11534
  }
11516
11535
  async withReadTransaction(callback, tx) {
11517
- this.logger.debug("Running with default transaction");
11536
+ this.logger.debug("Running with read transaction");
11518
11537
  const isInternalTx = !tx;
11519
11538
  if (!tx) {
11520
11539
  tx = this.createTransaction();
@@ -62,17 +62,19 @@ export declare class PageFileSystem {
62
62
  get strategy(): PageMVCCStrategy;
63
63
  /**
64
64
  * @param pageIndex 페이지 인덱스
65
+ * @param copy Copy-on-Read
65
66
  * @param tx 트랜잭션
66
67
  * @returns 페이지 버퍼
67
68
  */
68
- get(pageIndex: number, tx: Transaction): Promise<Uint8Array>;
69
+ get(pageIndex: number, copy: boolean, tx: Transaction): Promise<Uint8Array>;
69
70
  /**
70
71
  * Reads the page header.
71
72
  * @param pageIndex Page index
73
+ * @param copy Copy-on-Read
72
74
  * @param tx Transaction
73
75
  * @returns Page header buffer
74
76
  */
75
- getHeader(pageIndex: number, tx: Transaction): Promise<Uint8Array>;
77
+ getHeader(pageIndex: number, copy: boolean, tx: Transaction): Promise<Uint8Array>;
76
78
  /**
77
79
  * Reads the page body.
78
80
  * @param pageIndex Page index
@@ -83,10 +85,11 @@ export declare class PageFileSystem {
83
85
  getBody(pageIndex: number, recursive: boolean | undefined, tx: Transaction): Promise<Uint8Array>;
84
86
  /**
85
87
  * Returns the metadata page.
88
+ * @param copy Copy-on-Read
86
89
  * @param tx Transaction
87
90
  * @returns Metadata page
88
91
  */
89
- getMetadata(tx: Transaction): Promise<MetadataPage>;
92
+ getMetadata(copy: boolean, tx: Transaction): Promise<MetadataPage>;
90
93
  /**
91
94
  * Returns the number of pages stored in the database.
92
95
  * @param tx Transaction
@@ -95,10 +98,11 @@ export declare class PageFileSystem {
95
98
  getPageCount(tx: Transaction): Promise<number>;
96
99
  /**
97
100
  * Returns the root index page.
101
+ * @param copy Copy-on-Read
98
102
  * @param tx Transaction
99
103
  * @returns Root index page
100
104
  */
101
- getRootIndex(tx: Transaction): Promise<IndexPage>;
105
+ getRootIndex(copy: boolean, tx: Transaction): Promise<IndexPage>;
102
106
  /**
103
107
  * Sets the metadata page.
104
108
  * @param metadataPage Metadata page
@@ -51,9 +51,10 @@ export declare class Transaction {
51
51
  /**
52
52
  * Reads a page through the MVCC transaction.
53
53
  * @param pageId Page ID
54
+ * @param copy Copy-on-Read
54
55
  * @returns Page data
55
56
  */
56
- __readPage(pageId: number): Promise<Uint8Array>;
57
+ __readPage(pageId: number, copy: boolean): Promise<Uint8Array>;
57
58
  /**
58
59
  * Writes a page through the MVCC transaction.
59
60
  * @param pageId Page ID
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataply",
3
- "version": "0.0.26-alpha.10",
3
+ "version": "0.0.26-alpha.12",
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>",
@@ -49,6 +49,6 @@
49
49
  "hookall": "^2.2.0",
50
50
  "mvcc-api": "^1.3.7",
51
51
  "ryoiki": "^1.2.0",
52
- "serializable-bptree": "^9.0.3"
52
+ "serializable-bptree": "^9.0.4-alpha.1"
53
53
  }
54
54
  }