From 740a981685b63c83096b0c6dc1690982e8982366 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 30 Aug 2022 09:00:41 -0500 Subject: [PATCH 1/7] bump devdeps --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5f631d9..b21efdb 100644 --- a/package.json +++ b/package.json @@ -42,11 +42,11 @@ }, "devDependencies": { "@rollup/plugin-node-resolve": "^13.3.0", - "eslint": "^8.15.0", + "eslint": "^8.23.0", "eslint-config-mourner": "^3.0.0", "rbush": "^3.0.1", "rbush-knn": "^3.0.1", - "rollup": "^2.72.1", - "tape": "^5.5.3" + "rollup": "^2.78.1", + "tape": "^5.6.0" } } From e58b06b07d6d5ddc1ef6711e7e6fc5021fac99b1 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 30 Aug 2022 09:05:30 -0500 Subject: [PATCH 2/7] move constructor body to an init() helper --- index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/index.js b/index.js index 5937e7f..35ada48 100644 --- a/index.js +++ b/index.js @@ -28,6 +28,10 @@ export default class Flatbush { } constructor(numItems, nodeSize = 16, ArrayType = Float64Array, data) { + this.init(numItems, nodeSize, ArrayType, data); + } + + init(numItems, nodeSize = 16, ArrayType = Float64Array, data) { if (numItems === undefined) throw new Error('Missing required argument: numItems.'); if (isNaN(numItems) || numItems <= 0) throw new Error(`Unpexpected numItems value: ${numItems}.`); From 76b2944fb1b4cbf2ec73be054544d7041a49f4d8 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 30 Aug 2022 09:18:05 -0500 Subject: [PATCH 3/7] add auto-trim to finish() --- index.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 35ada48..39555b3 100644 --- a/index.js +++ b/index.js @@ -106,8 +106,29 @@ export default class Flatbush { return index; } + trim() { + const {_boxes, _indices, _pos, minX, minY, maxX, maxY, nodeSize, ArrayType} = this; + const numItems = _pos >> 2; + + this.init(numItems, nodeSize, ArrayType); + + this._boxes.set(_boxes.slice(0, this._boxes.length)); + this._indices.set(_indices.slice(0, this._indices.length)); + + this._pos = _pos; + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + finish() { - if (this._pos >> 2 !== this.numItems) { + const numAdded = this._pos >> 2; + + if (numAdded < this.numItems) { + this.trim(); + + } else if (numAdded > this.numItems) { throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`); } const boxes = this._boxes; From f60e55808536e1a3d0efb54310952b443e80c6c3 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 30 Aug 2022 09:21:57 -0500 Subject: [PATCH 4/7] move FlatQueue init to finish() --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 39555b3..cf55992 100644 --- a/index.js +++ b/index.js @@ -84,9 +84,6 @@ export default class Flatbush { new Uint16Array(this.data, 2, 1)[0] = nodeSize; new Uint32Array(this.data, 4, 1)[0] = numItems; } - - // a priority queue for k-nearest-neighbors queries - this._queue = new FlatQueue(); } add(minX, minY, maxX, maxY) { @@ -133,6 +130,9 @@ export default class Flatbush { } const boxes = this._boxes; + // a priority queue for k-nearest-neighbors queries + this._queue = new FlatQueue(); + if (this.numItems <= this.nodeSize) { // only one node, skip sorting and just fill the root box boxes[this._pos++] = this.minX; From dacca3e58786bbfce559c265d11c45d379664afc Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Fri, 13 Jan 2023 21:17:20 -0600 Subject: [PATCH 5/7] bump devdeps --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index b21efdb..7c81ae4 100644 --- a/package.json +++ b/package.json @@ -41,12 +41,12 @@ "flatqueue": "^2.0.3" }, "devDependencies": { - "@rollup/plugin-node-resolve": "^13.3.0", - "eslint": "^8.23.0", + "@rollup/plugin-node-resolve": "^15.0.1", + "eslint": "^8.31.0", "eslint-config-mourner": "^3.0.0", "rbush": "^3.0.1", "rbush-knn": "^3.0.1", - "rollup": "^2.78.1", - "tape": "^5.6.0" + "rollup": "^3.10.0", + "tape": "^5.6.1" } } From 9d64e494fcca217b7983eb8a8a3e325a55689620 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Tue, 17 Jan 2023 00:33:17 -0600 Subject: [PATCH 6/7] esm build, bump devdeps --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7c81ae4..4652005 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "pretest": "eslint index.js test.js bench.js", "test": "node test.js", "build": "rollup index.js -o flatbush.js -n Flatbush -f umd -p node-resolve", + "build:esm": "rollup index.js -o flatbush.esm.js -n Flatbush -f esm -p node-resolve", "prepublishOnly": "npm run build" }, "files": [ @@ -42,11 +43,11 @@ }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.1", - "eslint": "^8.31.0", + "eslint": "^8.32.0", "eslint-config-mourner": "^3.0.0", "rbush": "^3.0.1", "rbush-knn": "^3.0.1", "rollup": "^3.10.0", - "tape": "^5.6.1" + "tape": "^5.6.3" } } From 11830ccba068e0fd00c480464fbab829265c8c3b Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Mon, 24 Apr 2023 23:13:34 -0500 Subject: [PATCH 7/7] wip --- index.js | 49 +++++++++++++++++++++++++++++++++++++++++++++---- test.js | 8 ++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 86aa723..5d15c01 100644 --- a/index.js +++ b/index.js @@ -44,6 +44,18 @@ export default class Flatbush { * @param {ArrayBuffer | SharedArrayBuffer} [data] (Only used internally) */ constructor(numItems, nodeSize = 16, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data) { + this.init(numItems, nodeSize, ArrayType, ArrayBufferType, data); + } + + /** + * Create a Flatbush index that will hold a given number of items. + * @param {number} numItems + * @param {number} [nodeSize=16] Size of the tree node (16 by default). + * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default). + * @param {ArrayBufferConstructor | SharedArrayBufferConstructor} [ArrayBufferType=ArrayBuffer] The array buffer type used to store data (`ArrayBuffer` by default). + * @param {ArrayBuffer | SharedArrayBuffer} [data] (Only used internally) + */ + init(numItems, nodeSize = 16, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data) { if (numItems === undefined) throw new Error('Missing required argument: numItems.'); if (isNaN(numItems) || numItems <= 0) throw new Error(`Unexpected numItems value: ${numItems}.`); @@ -103,6 +115,27 @@ export default class Flatbush { this._queue = new FlatQueue(); } + /** + * Trim index to number of added rectangles. + */ + trim() { + const {_boxes, _indices, _pos, minX, minY, maxX, maxY, nodeSize, ArrayType} = this; + const numAdded = _pos >> 2; + + if (numAdded < this.numItems) { + this.init(numAdded, nodeSize, ArrayType, this.data.constructor); + + this._pos = _pos; + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + + this._boxes.set(_boxes.slice(0, this._boxes.length)); + this._indices.set(_indices.slice(0, this._indices.length)); + } + } + /** * Add a given rectangle to the index. * @param {number} minX @@ -128,11 +161,19 @@ export default class Flatbush { return index; } - /** Perform indexing of the added rectangles. */ - finish() { - if (this._pos >> 2 !== this.numItems) { - throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`); + /** + * Perform indexing of the added rectangles. + * @param {boolean} trim Whether to auto-trim index when number of added rectangles is less than numItems (`false` by default). + */ + finish(trim = false) { + const numAdded = this._pos >> 2; + + if (numAdded < this.numItems && trim) { + this.trim(); + } else if (numAdded !== this.numItems) { + throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`); } + const boxes = this._boxes; if (this.numItems <= this.nodeSize) { diff --git a/test.js b/test.js index a626691..9b31494 100644 --- a/test.js +++ b/test.js @@ -124,6 +124,14 @@ test('throws an error if added less items than the index size', () => { }); }); +test('does not throw an error if added less items than the index size and trim = true', () => { + assert.doesNotThrow(() => { + const index = new Flatbush(data.length / 4); + index.add(data[0], data[1], data[2], data[3]); + index.finish(true); + }); +}); + test('throws an error if searching before indexing', () => { assert.throws(() => { const index = new Flatbush(data.length / 4);