From 49fc27e649c44a5c8ac0044e52070cfed272b3e3 Mon Sep 17 00:00:00 2001 From: Shalev Raz Israel Date: Wed, 27 Aug 2025 20:37:39 +0300 Subject: [PATCH 1/2] Feat: add maxResults to Index.range methdo --- README.md | 4 ++-- bench.js | 7 +++++++ index.js | 13 ++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 822c18a..48c808d 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,9 @@ you may prefer `SharedArrayBuffer` if you want to share the index between thread Adds a given point to the index. Returns a zero-based, incremental number that represents the newly added point. -#### index.range(minX, minY, maxX, maxY) +#### index.range(minX, minY, maxX, maxY, maxResults=Infinity) -Finds all items within the given bounding box and returns an array of indices that refer to the order the items were added (the values returned by `index.add(x, y)`). +Finds all items within the given bounding box and returns an array of indices that refer to the order the items were added (the values returned by `index.add(x, y)`). If set, returns at most `maxResults` results. #### index.within(x, y, radius) diff --git a/bench.js b/bench.js index be6880a..1a68045 100644 --- a/bench.js +++ b/bench.js @@ -29,6 +29,13 @@ for (let i = 0; i < 10000; i++) { } console.timeEnd('10000 small bbox queries'); +console.time('10000 small bbox queries (with maxResults)'); +for (let i = 0; i < 10000; i++) { + const p = randomPoint(1000); + index.range(p.x - 1, p.y - 1, p.x + 1, p.y + 1, 8); +} +console.timeEnd('10000 small bbox queries (with maxResults)'); + console.time('10000 small radius queries'); for (let i = 0; i < 10000; i++) { const p = randomPoint(1000); diff --git a/index.js b/index.js index eae6054..2769b34 100644 --- a/index.js +++ b/index.js @@ -124,9 +124,10 @@ export default class KDBush { * @param {number} minY * @param {number} maxX * @param {number} maxY + * @param {number} [maxResults] Limit the number of results to return (no limit by default). * @returns {number[]} An array of indices correponding to the found items. */ - range(minX, minY, maxX, maxY) { + range(minX, minY, maxX, maxY, maxResults=Infinity) { if (!this._finished) throw new Error('Data not yet indexed - call index.finish().'); const {ids, coords, nodeSize} = this; @@ -144,7 +145,10 @@ export default class KDBush { for (let i = left; i <= right; i++) { const x = coords[2 * i]; const y = coords[2 * i + 1]; - if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]); + if (x >= minX && x <= maxX && y >= minY && y <= maxY) { + result.push(ids[i]); + if (result.length === maxResults) return result; + }; } continue; } @@ -155,7 +159,10 @@ export default class KDBush { // include the middle item if it's in range const x = coords[2 * m]; const y = coords[2 * m + 1]; - if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]); + if (x >= minX && x <= maxX && y >= minY && y <= maxY) { + result.push(ids[m]); + if (result.length === maxResults) return result; + }; // queue search in halves that intersect the query if (axis === 0 ? minX <= x : minY <= y) { From 815e36103228138217b39215ec7a952c0bef36b7 Mon Sep 17 00:00:00 2001 From: Shalev Raz Israel Date: Wed, 27 Aug 2025 20:40:49 +0300 Subject: [PATCH 2/2] fix compare sign in range (not sure if needed but just in case) --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 2769b34..ff7b89e 100644 --- a/index.js +++ b/index.js @@ -147,7 +147,7 @@ export default class KDBush { const y = coords[2 * i + 1]; if (x >= minX && x <= maxX && y >= minY && y <= maxY) { result.push(ids[i]); - if (result.length === maxResults) return result; + if (result.length >= maxResults) return result; }; } continue; @@ -161,7 +161,7 @@ export default class KDBush { const y = coords[2 * m + 1]; if (x >= minX && x <= maxX && y >= minY && y <= maxY) { result.push(ids[m]); - if (result.length === maxResults) return result; + if (result.length >= maxResults) return result; }; // queue search in halves that intersect the query