serializable-bptree 8.1.7 → 8.3.0

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/README.md CHANGED
@@ -158,7 +158,7 @@ const others = candidates.filter((c) => driver.tree !== c.tree)
158
158
  // 2. Execute query using the selected driver
159
159
  let keys = driver.tree.keys(driver.condition)
160
160
  for (const { tree, condition } of others) {
161
- keys = tree.keys(condition, keys)
161
+ keys = tree.keys(condition, { filterValues: keys })
162
162
  }
163
163
 
164
164
  console.log('Found: ', keys)
@@ -2154,17 +2154,24 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2154
2154
  }
2155
2155
  return void 0;
2156
2156
  }
2157
- *keysStream(condition, filterValues, limit, order = "asc") {
2158
- const stream = this.whereStream(condition, limit, order);
2157
+ *keysStream(condition, options) {
2158
+ const { filterValues, limit, order = "asc" } = options ?? {};
2159
+ const stream = this.whereStream(condition, options);
2159
2160
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2161
+ let count = 0;
2160
2162
  for (const [key] of stream) {
2161
2163
  if (intersection && !intersection.has(key)) {
2162
2164
  continue;
2163
2165
  }
2164
2166
  yield key;
2167
+ count++;
2168
+ if (limit !== void 0 && count >= limit) {
2169
+ break;
2170
+ }
2165
2171
  }
2166
2172
  }
2167
- *whereStream(condition, limit, order = "asc") {
2173
+ *whereStream(condition, options) {
2174
+ const { filterValues, limit, order = "asc" } = options ?? {};
2168
2175
  const driverKey = this.getDriverKey(condition);
2169
2176
  if (!driverKey) return;
2170
2177
  const value = condition[driverKey];
@@ -2187,8 +2194,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2187
2194
  earlyTerminate
2188
2195
  );
2189
2196
  let count = 0;
2197
+ const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2190
2198
  for (const pair of generator) {
2191
2199
  const [k, v] = pair;
2200
+ if (intersection && !intersection.has(k)) {
2201
+ continue;
2202
+ }
2192
2203
  let isMatch = true;
2193
2204
  for (const key in condition) {
2194
2205
  if (key === driverKey) continue;
@@ -2208,16 +2219,16 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2208
2219
  }
2209
2220
  }
2210
2221
  }
2211
- keys(condition, filterValues, order = "asc") {
2222
+ keys(condition, options) {
2212
2223
  const set = /* @__PURE__ */ new Set();
2213
- for (const key of this.keysStream(condition, filterValues, void 0, order)) {
2224
+ for (const key of this.keysStream(condition, options)) {
2214
2225
  set.add(key);
2215
2226
  }
2216
2227
  return set;
2217
2228
  }
2218
- where(condition, order = "asc") {
2229
+ where(condition, options) {
2219
2230
  const map = /* @__PURE__ */ new Map();
2220
- for (const [key, value] of this.whereStream(condition, void 0, order)) {
2231
+ for (const [key, value] of this.whereStream(condition, options)) {
2221
2232
  map.set(key, value);
2222
2233
  }
2223
2234
  return map;
@@ -2245,6 +2256,33 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2245
2256
  this._insertInParent(before, after.values[0], after);
2246
2257
  }
2247
2258
  }
2259
+ batchInsert(entries) {
2260
+ if (entries.length === 0) return;
2261
+ const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
2262
+ for (const [key, value] of sorted) {
2263
+ let before = this.insertableNode(value);
2264
+ before = this._insertAtLeaf(before, key, value);
2265
+ if (before.values.length === this.order) {
2266
+ let after = this._createNode(
2267
+ true,
2268
+ [],
2269
+ [],
2270
+ before.parent,
2271
+ null,
2272
+ null
2273
+ );
2274
+ const mid = Math.ceil(this.order / 2) - 1;
2275
+ after = this._cloneNode(after);
2276
+ after.values = before.values.slice(mid + 1);
2277
+ after.keys = before.keys.slice(mid + 1);
2278
+ before.values = before.values.slice(0, mid + 1);
2279
+ before.keys = before.keys.slice(0, mid + 1);
2280
+ this._updateNode(before);
2281
+ this._updateNode(after);
2282
+ this._insertInParent(before, after.values[0], after);
2283
+ }
2284
+ }
2285
+ }
2248
2286
  _deleteEntry(node, key) {
2249
2287
  if (!node.leaf) {
2250
2288
  let keyIndex = -1;
@@ -2600,6 +2638,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
2600
2638
  throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
2601
2639
  }
2602
2640
  }
2641
+ batchInsert(entries) {
2642
+ const tx = this.createTransaction();
2643
+ tx.batchInsert(entries);
2644
+ const result = tx.commit();
2645
+ if (!result.success) {
2646
+ throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
2647
+ }
2648
+ }
2603
2649
  };
2604
2650
 
2605
2651
  // node_modules/ryoiki/dist/esm/index.mjs
@@ -3229,17 +3275,24 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3229
3275
  }
3230
3276
  return void 0;
3231
3277
  }
3232
- async *keysStream(condition, filterValues, limit, order = "asc") {
3233
- const stream = this.whereStream(condition, limit, order);
3278
+ async *keysStream(condition, options) {
3279
+ const { filterValues, limit, order = "asc" } = options ?? {};
3280
+ const stream = this.whereStream(condition, options);
3234
3281
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
3282
+ let count = 0;
3235
3283
  for await (const [key] of stream) {
3236
3284
  if (intersection && !intersection.has(key)) {
3237
3285
  continue;
3238
3286
  }
3239
3287
  yield key;
3288
+ count++;
3289
+ if (limit !== void 0 && count >= limit) {
3290
+ break;
3291
+ }
3240
3292
  }
3241
3293
  }
3242
- async *whereStream(condition, limit, order = "asc") {
3294
+ async *whereStream(condition, options) {
3295
+ const { filterValues, limit, order = "asc" } = options ?? {};
3243
3296
  const driverKey = this.getDriverKey(condition);
3244
3297
  if (!driverKey) return;
3245
3298
  const value = condition[driverKey];
@@ -3262,8 +3315,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3262
3315
  earlyTerminate
3263
3316
  );
3264
3317
  let count = 0;
3318
+ const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
3265
3319
  for await (const pair of generator) {
3266
3320
  const [k, v] = pair;
3321
+ if (intersection && !intersection.has(k)) {
3322
+ continue;
3323
+ }
3267
3324
  let isMatch = true;
3268
3325
  for (const key in condition) {
3269
3326
  if (key === driverKey) continue;
@@ -3283,16 +3340,16 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3283
3340
  }
3284
3341
  }
3285
3342
  }
3286
- async keys(condition, filterValues, order = "asc") {
3343
+ async keys(condition, options) {
3287
3344
  const set = /* @__PURE__ */ new Set();
3288
- for await (const key of this.keysStream(condition, filterValues, void 0, order)) {
3345
+ for await (const key of this.keysStream(condition, options)) {
3289
3346
  set.add(key);
3290
3347
  }
3291
3348
  return set;
3292
3349
  }
3293
- async where(condition, order = "asc") {
3350
+ async where(condition, options) {
3294
3351
  const map = /* @__PURE__ */ new Map();
3295
- for await (const [key, value] of this.whereStream(condition, void 0, order)) {
3352
+ for await (const [key, value] of this.whereStream(condition, options)) {
3296
3353
  map.set(key, value);
3297
3354
  }
3298
3355
  return map;
@@ -3322,6 +3379,35 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3322
3379
  }
3323
3380
  });
3324
3381
  }
3382
+ async batchInsert(entries) {
3383
+ if (entries.length === 0) return;
3384
+ return this.writeLock(0, async () => {
3385
+ const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
3386
+ for (const [key, value] of sorted) {
3387
+ let before = await this.insertableNode(value);
3388
+ before = await this._insertAtLeaf(before, key, value);
3389
+ if (before.values.length === this.order) {
3390
+ let after = await this._createNode(
3391
+ true,
3392
+ [],
3393
+ [],
3394
+ before.parent,
3395
+ null,
3396
+ null
3397
+ );
3398
+ const mid = Math.ceil(this.order / 2) - 1;
3399
+ after = this._cloneNode(after);
3400
+ after.values = before.values.slice(mid + 1);
3401
+ after.keys = before.keys.slice(mid + 1);
3402
+ before.values = before.values.slice(0, mid + 1);
3403
+ before.keys = before.keys.slice(0, mid + 1);
3404
+ await this._updateNode(before);
3405
+ await this._updateNode(after);
3406
+ await this._insertInParent(before, after.values[0], after);
3407
+ }
3408
+ }
3409
+ });
3410
+ }
3325
3411
  async _deleteEntry(node, key) {
3326
3412
  if (!node.leaf) {
3327
3413
  let keyIndex = -1;
@@ -3683,6 +3769,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
3683
3769
  }
3684
3770
  });
3685
3771
  }
3772
+ async batchInsert(entries) {
3773
+ return this.writeLock(1, async () => {
3774
+ const tx = await this.createTransaction();
3775
+ await tx.batchInsert(entries);
3776
+ const result = await tx.commit();
3777
+ if (!result.success) {
3778
+ throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
3779
+ }
3780
+ });
3781
+ }
3686
3782
  };
3687
3783
 
3688
3784
  // src/base/SerializeStrategy.ts
@@ -2118,17 +2118,24 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2118
2118
  }
2119
2119
  return void 0;
2120
2120
  }
2121
- *keysStream(condition, filterValues, limit, order = "asc") {
2122
- const stream = this.whereStream(condition, limit, order);
2121
+ *keysStream(condition, options) {
2122
+ const { filterValues, limit, order = "asc" } = options ?? {};
2123
+ const stream = this.whereStream(condition, options);
2123
2124
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2125
+ let count = 0;
2124
2126
  for (const [key] of stream) {
2125
2127
  if (intersection && !intersection.has(key)) {
2126
2128
  continue;
2127
2129
  }
2128
2130
  yield key;
2131
+ count++;
2132
+ if (limit !== void 0 && count >= limit) {
2133
+ break;
2134
+ }
2129
2135
  }
2130
2136
  }
2131
- *whereStream(condition, limit, order = "asc") {
2137
+ *whereStream(condition, options) {
2138
+ const { filterValues, limit, order = "asc" } = options ?? {};
2132
2139
  const driverKey = this.getDriverKey(condition);
2133
2140
  if (!driverKey) return;
2134
2141
  const value = condition[driverKey];
@@ -2151,8 +2158,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2151
2158
  earlyTerminate
2152
2159
  );
2153
2160
  let count = 0;
2161
+ const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2154
2162
  for (const pair of generator) {
2155
2163
  const [k, v] = pair;
2164
+ if (intersection && !intersection.has(k)) {
2165
+ continue;
2166
+ }
2156
2167
  let isMatch = true;
2157
2168
  for (const key in condition) {
2158
2169
  if (key === driverKey) continue;
@@ -2172,16 +2183,16 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2172
2183
  }
2173
2184
  }
2174
2185
  }
2175
- keys(condition, filterValues, order = "asc") {
2186
+ keys(condition, options) {
2176
2187
  const set = /* @__PURE__ */ new Set();
2177
- for (const key of this.keysStream(condition, filterValues, void 0, order)) {
2188
+ for (const key of this.keysStream(condition, options)) {
2178
2189
  set.add(key);
2179
2190
  }
2180
2191
  return set;
2181
2192
  }
2182
- where(condition, order = "asc") {
2193
+ where(condition, options) {
2183
2194
  const map = /* @__PURE__ */ new Map();
2184
- for (const [key, value] of this.whereStream(condition, void 0, order)) {
2195
+ for (const [key, value] of this.whereStream(condition, options)) {
2185
2196
  map.set(key, value);
2186
2197
  }
2187
2198
  return map;
@@ -2209,6 +2220,33 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2209
2220
  this._insertInParent(before, after.values[0], after);
2210
2221
  }
2211
2222
  }
2223
+ batchInsert(entries) {
2224
+ if (entries.length === 0) return;
2225
+ const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
2226
+ for (const [key, value] of sorted) {
2227
+ let before = this.insertableNode(value);
2228
+ before = this._insertAtLeaf(before, key, value);
2229
+ if (before.values.length === this.order) {
2230
+ let after = this._createNode(
2231
+ true,
2232
+ [],
2233
+ [],
2234
+ before.parent,
2235
+ null,
2236
+ null
2237
+ );
2238
+ const mid = Math.ceil(this.order / 2) - 1;
2239
+ after = this._cloneNode(after);
2240
+ after.values = before.values.slice(mid + 1);
2241
+ after.keys = before.keys.slice(mid + 1);
2242
+ before.values = before.values.slice(0, mid + 1);
2243
+ before.keys = before.keys.slice(0, mid + 1);
2244
+ this._updateNode(before);
2245
+ this._updateNode(after);
2246
+ this._insertInParent(before, after.values[0], after);
2247
+ }
2248
+ }
2249
+ }
2212
2250
  _deleteEntry(node, key) {
2213
2251
  if (!node.leaf) {
2214
2252
  let keyIndex = -1;
@@ -2564,6 +2602,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
2564
2602
  throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
2565
2603
  }
2566
2604
  }
2605
+ batchInsert(entries) {
2606
+ const tx = this.createTransaction();
2607
+ tx.batchInsert(entries);
2608
+ const result = tx.commit();
2609
+ if (!result.success) {
2610
+ throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
2611
+ }
2612
+ }
2567
2613
  };
2568
2614
 
2569
2615
  // node_modules/ryoiki/dist/esm/index.mjs
@@ -3193,17 +3239,24 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3193
3239
  }
3194
3240
  return void 0;
3195
3241
  }
3196
- async *keysStream(condition, filterValues, limit, order = "asc") {
3197
- const stream = this.whereStream(condition, limit, order);
3242
+ async *keysStream(condition, options) {
3243
+ const { filterValues, limit, order = "asc" } = options ?? {};
3244
+ const stream = this.whereStream(condition, options);
3198
3245
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
3246
+ let count = 0;
3199
3247
  for await (const [key] of stream) {
3200
3248
  if (intersection && !intersection.has(key)) {
3201
3249
  continue;
3202
3250
  }
3203
3251
  yield key;
3252
+ count++;
3253
+ if (limit !== void 0 && count >= limit) {
3254
+ break;
3255
+ }
3204
3256
  }
3205
3257
  }
3206
- async *whereStream(condition, limit, order = "asc") {
3258
+ async *whereStream(condition, options) {
3259
+ const { filterValues, limit, order = "asc" } = options ?? {};
3207
3260
  const driverKey = this.getDriverKey(condition);
3208
3261
  if (!driverKey) return;
3209
3262
  const value = condition[driverKey];
@@ -3226,8 +3279,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3226
3279
  earlyTerminate
3227
3280
  );
3228
3281
  let count = 0;
3282
+ const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
3229
3283
  for await (const pair of generator) {
3230
3284
  const [k, v] = pair;
3285
+ if (intersection && !intersection.has(k)) {
3286
+ continue;
3287
+ }
3231
3288
  let isMatch = true;
3232
3289
  for (const key in condition) {
3233
3290
  if (key === driverKey) continue;
@@ -3247,16 +3304,16 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3247
3304
  }
3248
3305
  }
3249
3306
  }
3250
- async keys(condition, filterValues, order = "asc") {
3307
+ async keys(condition, options) {
3251
3308
  const set = /* @__PURE__ */ new Set();
3252
- for await (const key of this.keysStream(condition, filterValues, void 0, order)) {
3309
+ for await (const key of this.keysStream(condition, options)) {
3253
3310
  set.add(key);
3254
3311
  }
3255
3312
  return set;
3256
3313
  }
3257
- async where(condition, order = "asc") {
3314
+ async where(condition, options) {
3258
3315
  const map = /* @__PURE__ */ new Map();
3259
- for await (const [key, value] of this.whereStream(condition, void 0, order)) {
3316
+ for await (const [key, value] of this.whereStream(condition, options)) {
3260
3317
  map.set(key, value);
3261
3318
  }
3262
3319
  return map;
@@ -3286,6 +3343,35 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3286
3343
  }
3287
3344
  });
3288
3345
  }
3346
+ async batchInsert(entries) {
3347
+ if (entries.length === 0) return;
3348
+ return this.writeLock(0, async () => {
3349
+ const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
3350
+ for (const [key, value] of sorted) {
3351
+ let before = await this.insertableNode(value);
3352
+ before = await this._insertAtLeaf(before, key, value);
3353
+ if (before.values.length === this.order) {
3354
+ let after = await this._createNode(
3355
+ true,
3356
+ [],
3357
+ [],
3358
+ before.parent,
3359
+ null,
3360
+ null
3361
+ );
3362
+ const mid = Math.ceil(this.order / 2) - 1;
3363
+ after = this._cloneNode(after);
3364
+ after.values = before.values.slice(mid + 1);
3365
+ after.keys = before.keys.slice(mid + 1);
3366
+ before.values = before.values.slice(0, mid + 1);
3367
+ before.keys = before.keys.slice(0, mid + 1);
3368
+ await this._updateNode(before);
3369
+ await this._updateNode(after);
3370
+ await this._insertInParent(before, after.values[0], after);
3371
+ }
3372
+ }
3373
+ });
3374
+ }
3289
3375
  async _deleteEntry(node, key) {
3290
3376
  if (!node.leaf) {
3291
3377
  let keyIndex = -1;
@@ -3647,6 +3733,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
3647
3733
  }
3648
3734
  });
3649
3735
  }
3736
+ async batchInsert(entries) {
3737
+ return this.writeLock(1, async () => {
3738
+ const tx = await this.createTransaction();
3739
+ await tx.batchInsert(entries);
3740
+ const result = await tx.commit();
3741
+ if (!result.success) {
3742
+ throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
3743
+ }
3744
+ });
3745
+ }
3650
3746
  };
3651
3747
 
3652
3748
  // src/base/SerializeStrategy.ts
@@ -11,4 +11,5 @@ export declare class BPTreeAsync<K, V> extends BPTreeAsyncTransaction<K, V> {
11
11
  createTransaction(): Promise<BPTreeAsyncTransaction<K, V>>;
12
12
  insert(key: K, value: V): Promise<void>;
13
13
  delete(key: K, value?: V): Promise<void>;
14
+ batchInsert(entries: [K, V][]): Promise<void>;
14
15
  }
@@ -11,4 +11,5 @@ export declare class BPTreeSync<K, V> extends BPTreeSyncTransaction<K, V> {
11
11
  createTransaction(): BPTreeSyncTransaction<K, V>;
12
12
  insert(key: K, value: V): void;
13
13
  delete(key: K, value?: V): void;
14
+ batchInsert(entries: [K, V][]): void;
14
15
  }
@@ -1,5 +1,5 @@
1
1
  import type { TransactionEntry, TransactionResult } from 'mvcc-api';
2
- import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, Deferred, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData, BPTreeNode, BPTreeMVCC } from '../types';
2
+ import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, Deferred, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData, BPTreeNode, BPTreeMVCC, BPTreeSearchOption } from '../types';
3
3
  import { ValueComparator } from './ValueComparator';
4
4
  import { SerializeStrategy } from './SerializeStrategy';
5
5
  export declare abstract class BPTreeTransaction<K, V> {
@@ -107,28 +107,44 @@ export declare abstract class BPTreeTransaction<K, V> {
107
107
  * This method is used to initialize the stored tree and recover data.
108
108
  * If it is not called, the tree will not function.
109
109
  */
110
+ abstract init(): Deferred<void>;
110
111
  /**
111
- * After creating a tree instance, it must be called.
112
- * This method is used to initialize the stored tree and recover data.
113
- * If it is not called, the tree will not function.
112
+ * Retrieves the value associated with the given key.
113
+ * @param key The key to search for.
114
+ * @returns A Deferred that resolves to the value if found, or undefined if not found.
114
115
  */
115
- abstract init(): Deferred<void>;
116
+ abstract get(key: K): Deferred<V | undefined>;
117
+ /**
118
+ * Returns a generator that yields keys satisfying the given condition.
119
+ * This is a memory-efficient way to iterate through keys when dealing with large result sets.
120
+ * @param condition The search condition (e.g., gt, lt, equal, like).
121
+ * @param options Search options including filterValues, limit, and order.
122
+ * @returns An async or synchronous generator yielding keys of type K.
123
+ */
124
+ abstract keysStream(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): AsyncGenerator<K> | Generator<K>;
125
+ /**
126
+ * Returns a generator that yields [key, value] pairs satisfying the given condition.
127
+ * This is a memory-efficient way to iterate through pairs when dealing with large result sets.
128
+ * @param condition The search condition (e.g., gt, lt, equal, like).
129
+ * @param options Search options including filterValues, limit, and order.
130
+ * @returns An async or synchronous generator yielding [K, V] tuples.
131
+ */
132
+ abstract whereStream(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): AsyncGenerator<[K, V]> | Generator<[K, V]>;
116
133
  /**
117
134
  * It searches for a key within the tree. The result is returned as an array sorted in ascending order based on the value.
118
135
  * The result is key set instance, and you can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
119
136
  * This method operates much faster than first searching with `where` and then retrieving only the key list.
120
137
  * @param condition You can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
121
- * @param filterValues The `Set` containing values to check for intersection.
122
- * Returns a `Set` containing values that are common to both the input `Set` and the intersection `Set`.
123
- * If this parameter is not provided, it searches for all keys inserted into the tree.
138
+ * @param options Search options including filterValues, limit, and order.
124
139
  */
125
- abstract keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Deferred<Set<K>>;
140
+ abstract keys(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Deferred<Set<K>>;
126
141
  /**
127
142
  * It searches for a value within the tree. The result is returned as an array sorted in ascending order based on the value.
128
143
  * The result includes the key and value attributes, and you can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
129
144
  * @param condition You can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
145
+ * @param options Search options including filterValues, limit, and order.
130
146
  */
131
- abstract where(condition: BPTreeCondition<V>): Deferred<BPTreePair<K, V>>;
147
+ abstract where(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Deferred<BPTreePair<K, V>>;
132
148
  /**
133
149
  * You enter the key and value as a pair. You can later search for the pair by value.
134
150
  * This data is stored in the tree, sorted in ascending order of value.
@@ -136,12 +152,17 @@ export declare abstract class BPTreeTransaction<K, V> {
136
152
  * @param value The value of the pair.
137
153
  */
138
154
  abstract insert(key: K, value: V): Deferred<void>;
155
+ /**
156
+ * Inserts multiple key-value pairs into the tree in a single batch operation.
157
+ * Entries are sorted by value before insertion to optimize tree traversal.
158
+ * This is more efficient than calling insert() multiple times.
159
+ * @param entries Array of [key, value] pairs to insert.
160
+ */
161
+ abstract batchInsert(entries: [K, V][]): Deferred<void>;
139
162
  /**
140
163
  * Deletes the pair that matches the key and value.
141
- *
142
164
  * @param key The key of the pair. This key must be unique.
143
165
  * @param value The value of the pair.
144
- *
145
166
  * @warning If the 'value' is not specified, a full scan will be performed to find the value associated with the key, which may lead to performance degradation.
146
167
  */
147
168
  abstract delete(key: K, value?: V): Deferred<void>;
@@ -1,5 +1,5 @@
1
1
  import type { TransactionResult } from 'mvcc-api';
2
- import type { AsyncBPTreeMVCC, BPTreeCondition, BPTreeConstructorOption, BPTreeLeafNode, BPTreeNode, BPTreeNodeKey, BPTreeOrder, BPTreePair, BPTreeUnknownNode, SerializableData, SerializeStrategyHead } from '../types';
2
+ import type { AsyncBPTreeMVCC, BPTreeCondition, BPTreeConstructorOption, BPTreeLeafNode, BPTreeNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, SerializableData, SerializeStrategyHead, BPTreeSearchOption } from '../types';
3
3
  import { Ryoiki } from 'ryoiki';
4
4
  import { BPTreeTransaction } from '../base/BPTreeTransaction';
5
5
  import { SerializeStrategyAsync } from '../SerializeStrategyAsync';
@@ -37,11 +37,12 @@ export declare class BPTreeAsyncTransaction<K, V> extends BPTreeTransaction<K, V
37
37
  protected _initInternal(): Promise<void>;
38
38
  exists(key: K, value: V): Promise<boolean>;
39
39
  get(key: K): Promise<V | undefined>;
40
- keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number, order?: BPTreeOrder): AsyncGenerator<K>;
41
- whereStream(condition: BPTreeCondition<V>, limit?: number, order?: BPTreeOrder): AsyncGenerator<[K, V]>;
42
- keys(condition: BPTreeCondition<V>, filterValues?: Set<K>, order?: BPTreeOrder): Promise<Set<K>>;
43
- where(condition: BPTreeCondition<V>, order?: BPTreeOrder): Promise<BPTreePair<K, V>>;
40
+ keysStream(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): AsyncGenerator<K>;
41
+ whereStream(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): AsyncGenerator<[K, V]>;
42
+ keys(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Promise<Set<K>>;
43
+ where(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Promise<BPTreePair<K, V>>;
44
44
  insert(key: K, value: V): Promise<void>;
45
+ batchInsert(entries: [K, V][]): Promise<void>;
45
46
  protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): Promise<BPTreeUnknownNode<K, V>>;
46
47
  delete(key: K, value?: V): Promise<void>;
47
48
  getHeadData(): Promise<SerializableData>;
@@ -1,5 +1,5 @@
1
1
  import type { TransactionResult } from 'mvcc-api';
2
- import type { BPTreeCondition, BPTreeConstructorOption, BPTreeLeafNode, BPTreeNode, BPTreeNodeKey, BPTreeOrder, BPTreePair, BPTreeUnknownNode, SerializableData, SerializeStrategyHead, SyncBPTreeMVCC } from '../types';
2
+ import type { BPTreeCondition, BPTreeConstructorOption, BPTreeLeafNode, BPTreeNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, SerializableData, SerializeStrategyHead, SyncBPTreeMVCC, BPTreeSearchOption } from '../types';
3
3
  import { BPTreeTransaction } from '../base/BPTreeTransaction';
4
4
  import { SerializeStrategySync } from '../SerializeStrategySync';
5
5
  import { ValueComparator } from '../base/ValueComparator';
@@ -34,11 +34,12 @@ export declare class BPTreeSyncTransaction<K, V> extends BPTreeTransaction<K, V>
34
34
  protected _initInternal(): void;
35
35
  exists(key: K, value: V): boolean;
36
36
  get(key: K): V | undefined;
37
- keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number, order?: BPTreeOrder): Generator<K>;
38
- whereStream(condition: BPTreeCondition<V>, limit?: number, order?: BPTreeOrder): Generator<[K, V]>;
39
- keys(condition: BPTreeCondition<V>, filterValues?: Set<K>, order?: BPTreeOrder): Set<K>;
40
- where(condition: BPTreeCondition<V>, order?: BPTreeOrder): BPTreePair<K, V>;
37
+ keysStream(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Generator<K>;
38
+ whereStream(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Generator<[K, V]>;
39
+ keys(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Set<K>;
40
+ where(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): BPTreePair<K, V>;
41
41
  insert(key: K, value: V): void;
42
+ batchInsert(entries: [K, V][]): void;
42
43
  protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): BPTreeUnknownNode<K, V>;
43
44
  delete(key: K, value?: V): void;
44
45
  getHeadData(): SerializableData;
@@ -52,6 +52,11 @@ export type BPTreeCondition<V> = Partial<{
52
52
  * - `'desc'`: Descending order - traverses from right to left
53
53
  */
54
54
  export type BPTreeOrder = 'asc' | 'desc';
55
+ export interface BPTreeSearchOption<K> {
56
+ filterValues?: Set<K>;
57
+ limit?: number;
58
+ order?: BPTreeOrder;
59
+ }
55
60
  export type BPTreePair<K, V> = Map<K, V>;
56
61
  export type BPTreeUnknownNode<K, V> = BPTreeInternalNode<K, V> | BPTreeLeafNode<K, V>;
57
62
  export interface BPTreeConstructorOption {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "8.1.7",
3
+ "version": "8.3.0",
4
4
  "description": "Store the B+tree flexibly, not only in-memory.",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "main": "./dist/cjs/index.cjs",