Skip to content

Commit c73ea7b

Browse files
committed
feat: add insert_many_points support to rust core
1 parent b731a3b commit c73ea7b

File tree

4 files changed

+34
-28
lines changed

4 files changed

+34
-28
lines changed

benchmarks/quadtree_bench/engines.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ def _create_fastquadtree_engine(
101101

102102
def build(points):
103103
qt = RustQuadTree(bounds, max_points, max_depth=max_depth)
104-
for p in points:
105-
qt.insert(p)
104+
qt.insert_many_points(points)
106105
return qt
107106

108107
def query(qt, queries):

pysrc/fastquadtree/__init__.py

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, Iterable, Literal, Tuple, overload
3+
from typing import Any, Literal, Tuple, overload
44

55
from ._bimap import BiMap # type: ignore[attr-defined]
66
from ._item import Item
@@ -103,37 +103,33 @@ def insert(self, xy: Point, *, id_: int | None = None, obj: Any = None) -> int:
103103
self._count += 1
104104
return id_
105105

106-
def insert_many_points(self, points: Iterable[Point]) -> int:
106+
def insert_many_points(self, points: list[Point]) -> int:
107107
"""
108108
Bulk insert points with auto-assigned ids.
109109
110110
Args:
111-
points: Iterable of (x, y) points.
111+
points: List of (x, y) points.
112112
113113
Returns:
114-
Number of points successfully inserted.
115-
116-
Raises:
117-
ValueError: If any point is outside tree bounds.
114+
The number of points inserted
118115
"""
119-
ins = self._native.insert
120-
nid = self._next_id
121-
inserted = 0
122-
bx0, by0, bx1, by1 = self._bounds
123-
for xy in points:
124-
id_ = nid
125-
nid += 1
126-
if not ins(id_, xy):
127-
x, y = xy
128-
raise ValueError(
129-
f"Point ({x}, {y}) is outside bounds ({bx0}, {by0}, {bx1}, {by1})"
130-
)
131-
inserted += 1
132-
if self._items is not None:
133-
self._items.add(Item(id_, xy[0], xy[1], None))
134-
self._next_id = nid
135-
self._count += inserted
136-
return inserted
116+
start_id = self._next_id
117+
last_id = self._native.insert_many_points(start_id, points)
118+
119+
num_inserted = last_id - start_id + 1
120+
121+
if num_inserted < len(points):
122+
raise ValueError("One or more points are outside tree bounds")
123+
124+
self._next_id = last_id + 1
125+
126+
# Update the item tracker if needed
127+
if self._items is not None:
128+
for i, id_ in enumerate(range(start_id, last_id + 1)):
129+
x, y = points[i]
130+
self._items.add(Item(id_, x, y, None))
131+
132+
return num_inserted
137133

138134
def attach(self, id_: int, obj: Any) -> None:
139135
"""

pysrc/fastquadtree/__init__.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ class QuadTree:
3131
# Inserts
3232
def insert(self, xy: Point, *, id_: int | None = ..., obj: Any = ...) -> int: ...
3333
def insert_many_points(self, points: Iterable[Point]) -> int: ...
34-
def insert_many(self, items: Iterable[tuple[Point, Any]]) -> int: ...
3534
def attach(self, id_: int, obj: Any) -> None: ...
3635

3736
# Deletions

src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ impl PyQuadTree {
3636
self.inner.insert(Item { id, point: Point { x, y } })
3737
}
3838

39+
// Insert many points with auto ids starting at `start_id`: [(x, y), ...]
40+
// Returns the last id used
41+
pub fn insert_many_points(&mut self, start_id: u64, points: Vec<(f32, f32)>) -> u64 {
42+
let mut id = start_id;
43+
for (x, y) in points {
44+
if self.inner.insert(Item { id, point: Point { x, y } }) {
45+
id += 1;
46+
}
47+
}
48+
id - 1 // -1 because id was incremented after last successful insert
49+
}
50+
3951
pub fn delete(&mut self, id: u64, xy: (f32, f32)) -> bool {
4052
let (x, y) = xy;
4153
self.inner.delete(id, Point { x, y })

0 commit comments

Comments
 (0)