From dee2392225b1d26da1819c9fb3a3c9acfc2bf856 Mon Sep 17 00:00:00 2001 From: sliterok <12751644+sliterok@users.noreply.github.com> Date: Sat, 9 Mar 2024 20:06:51 +0100 Subject: [PATCH] implement limit in bptree --- src/db/index.ts | 2 +- src/impl/bptree/BPTree.ts | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/db/index.ts b/src/db/index.ts index 8cbed73..b675f1e 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -161,7 +161,7 @@ export class OPFSDB { if (!tree) throw new Error('No such index found') const query = queries[key]! - const queryIndexes = await tree.keys(query) + const queryIndexes = await tree.keys(query, options?.limit) if (options?.isAnd) { indexes = indexes.size ? new Set([...indexes].filter(el => queryIndexes.has(el))) : queryIndexes } else { diff --git a/src/impl/bptree/BPTree.ts b/src/impl/bptree/BPTree.ts index 3948000..e253ed6 100644 --- a/src/impl/bptree/BPTree.ts +++ b/src/impl/bptree/BPTree.ts @@ -337,13 +337,16 @@ export class BPTree { value: V, startNode: BPTreeLeafNode, fullSearch: boolean, - comparator: (nodeValue: V, value: V) => boolean + comparator: (nodeValue: V, value: V) => boolean, + limit?: number ): Promise[]> { const pairs = [] let node = startNode let done = false let found = false - while (!done) { + let count = 0 + + while (!done && (!limit || count < limit)) { let i = node.values.length while (i--) { const nValue = node.values[i] @@ -353,6 +356,7 @@ export class BPTree { let j = keys.length while (j--) { pairs.push({ key: keys[j], value: nValue }) + count++ } } else if (found && !fullSearch) { done = true @@ -372,13 +376,16 @@ export class BPTree { value: V, startNode: BPTreeLeafNode, fullSearch: boolean, - comparator: (nodeValue: V, value: V) => boolean + comparator: (nodeValue: V, value: V) => boolean, + limit?: number ): Promise[]> { const pairs = [] let node = startNode let done = false let found = false - while (!done) { + let count = 0 + + while (!done && (!limit || count < limit)) { for (let i = 0, len = node.values.length; i < len; i++) { const nValue = node.values[i] const keys = node.keys[i] @@ -386,6 +393,7 @@ export class BPTree { found = true for (const key of keys) { pairs.push({ key, value: nValue }) + count++ } } else if (found && !fullSearch) { done = true @@ -406,13 +414,14 @@ export class BPTree { startNode: BPTreeLeafNode, fullSearch: boolean, comparator: (nodeValue: V, value: V) => boolean, - direction: -1 | 1 + direction: -1 | 1, + limit?: number ): Promise[]> { switch (direction) { case -1: - return await this._getPairsRightToLeft(value, startNode, fullSearch, comparator) + return await this._getPairsRightToLeft(value, startNode, fullSearch, comparator, limit) case +1: - return await this._getPairsLeftToRight(value, startNode, fullSearch, comparator) + return await this._getPairsLeftToRight(value, startNode, fullSearch, comparator, limit) default: throw new Error(`Direction must be -1 or 1. but got a ${direction}`) } @@ -424,7 +433,7 @@ export class BPTree { * This method operates much faster than first searching with `where` and then retrieving only the key list. * @param condition You can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements. */ - async keys(condition: BPTreeCondition): Promise> { + async keys(condition: BPTreeCondition, limit?: number): Promise> { let result: K[] | null = null for (const k in condition) { const key = k as keyof BPTreeCondition @@ -433,7 +442,7 @@ export class BPTree { const direction = this._verifierDirection[key] const fullSearch = this._verifierFullSearch[key] const comparator = this._verifierMap[key] - const pairs = await this.getPairs(value, startNode, fullSearch, comparator, direction) + const pairs = await this.getPairs(value, startNode, fullSearch, comparator, direction, limit) if (result === null) { result = pairs.map(pair => pair.key) } else {