Skip to content

Commit f72bc81

Browse files
Merge pull request #82 from Workiva/hilbert_delete
Added delete.
2 parents 47868f5 + 44d3ba6 commit f72bc81

File tree

4 files changed

+87
-5
lines changed

4 files changed

+87
-5
lines changed

rtree/hilbert/cpu.prof

5.03 KB
Binary file not shown.

rtree/hilbert/node.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ func (ns *nodes) len() uint64 {
7777
return uint64(len(ns.list))
7878
}
7979

80+
func (ns *nodes) deleteAt(i uint64) {
81+
copy(ns.list[i:], ns.list[i+1:])
82+
ns.list = ns.list[:len(ns.list)-1]
83+
}
84+
8085
func newNodes(size uint64) *nodes {
8186
return &nodes{
8287
list: make(rtree.Rectangles, 0, size),
@@ -106,6 +111,11 @@ func (ks *keys) byPosition(i uint64) hilbert {
106111
return ks.list[i]
107112
}
108113

114+
func (ks *keys) deleteAt(i uint64) {
115+
copy(ks.list[i:], ks.list[i+1:])
116+
ks.list = ks.list[:len(ks.list)-1]
117+
}
118+
109119
func (ks *keys) delete(k hilbert) hilbert {
110120
i := ks.search(k)
111121
if i >= uint64(len(ks.list)) {
@@ -116,9 +126,7 @@ func (ks *keys) delete(k hilbert) hilbert {
116126
return -1
117127
}
118128
old := ks.list[i]
119-
120-
copy(ks.list[i:], ks.list[i+1:])
121-
ks.list = ks.list[:len(ks.list)-1]
129+
ks.deleteAt(i)
122130
return old
123131
}
124132

@@ -223,6 +231,22 @@ func (n *node) insert(kb *keyBundle) rtree.Rectangle {
223231
return nil
224232
}
225233

234+
func (n *node) delete(kb *keyBundle) rtree.Rectangle {
235+
i := n.keys.search(kb.key)
236+
if n.keys.byPosition(i) != kb.key { // hilbert value not found
237+
return nil
238+
}
239+
240+
if !equal(n.nodes.list[i], kb.left) {
241+
return nil
242+
}
243+
244+
old := n.nodes.list[i]
245+
n.keys.deleteAt(i)
246+
n.nodes.deleteAt(i)
247+
return old
248+
}
249+
226250
func (n *node) LowerLeft() (int32, int32) {
227251
return n.mbr.xlow, n.mbr.ylow
228252
}

rtree/hilbert/tree.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ func (tree *tree) applyNode(n *node, adds, deletes []*keyBundle) {
265265
break
266266
}
267267

268-
deleted := n.keys.delete(kb.key)
269-
if deleted != -1 {
268+
deleted := n.delete(kb)
269+
if deleted != nil {
270270
atomic.AddUint64(&tree.number, ^uint64(0))
271271
}
272272
}

rtree/hilbert/tree_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ func constructRandomMockPoints(num int) rtree.Rectangles {
7575
return rects
7676
}
7777

78+
func constructInfiniteRect() rtree.Rectangle {
79+
return newMockRectangle(0, 0, math.MaxInt32, math.MaxInt32)
80+
}
81+
7882
func TestSimpleInsert(t *testing.T) {
7983
r1 := newMockRectangle(0, 0, 10, 10)
8084
tree := newTree(3, 3)
@@ -87,6 +91,47 @@ func TestSimpleInsert(t *testing.T) {
8791
assert.Equal(t, rtree.Rectangles{r1}, result)
8892
}
8993

94+
func TestSimpleDelete(t *testing.T) {
95+
r1 := newMockRectangle(0, 0, 10, 10)
96+
tree := newTree(3, 3)
97+
tree.Insert(r1)
98+
99+
tree.Delete(r1)
100+
assert.Equal(t, uint64(0), tree.Len())
101+
q := newMockRectangle(5, 5, 15, 15)
102+
result := tree.Search(q)
103+
assert.Len(t, result, 0)
104+
}
105+
106+
func TestDeleteIdenticalHilbergNumber(t *testing.T) {
107+
r1 := newMockRectangle(0, 0, 20, 20)
108+
r2 := newMockRectangle(5, 5, 15, 15)
109+
tree := newTree(3, 3)
110+
tree.Insert(r1)
111+
112+
tree.Delete(r2)
113+
assert.Equal(t, uint64(1), tree.Len())
114+
result := tree.Search(r2)
115+
assert.Equal(t, rtree.Rectangles{r1}, result)
116+
117+
tree.Delete(r1)
118+
assert.Equal(t, uint64(0), tree.Len())
119+
result = tree.Search(r1)
120+
assert.Len(t, result, 0)
121+
}
122+
123+
func TestDeleteAll(t *testing.T) {
124+
points := constructRandomMockPoints(5)
125+
tree := newTree(3, 3)
126+
tree.Insert(points...)
127+
assert.Equal(t, uint64(len(points)), tree.Len())
128+
129+
tree.Delete(points...)
130+
assert.Equal(t, uint64(0), tree.Len())
131+
result := tree.Search(constructInfiniteRect())
132+
assert.Len(t, result, 0)
133+
}
134+
90135
func TestTwoInsert(t *testing.T) {
91136
r1 := newMockRectangle(0, 0, 10, 10)
92137
r2 := newMockRectangle(5, 5, 15, 15)
@@ -350,3 +395,16 @@ func BenchmarkQueryPoints(b *testing.B) {
350395
tree.Search(newMockRectangle(i, i, i+10, i+10))
351396
}
352397
}
398+
399+
func BenchmarkQueryBulkPoints(b *testing.B) {
400+
numItems := b.N
401+
points := constructMockPoints(numItems)
402+
tree := newTree(8, 8)
403+
tree.Insert(points...)
404+
405+
b.ResetTimer()
406+
407+
for i := int32(0); i < int32(b.N); i++ {
408+
tree.Search(newMockRectangle(i, i, int32(numItems), int32(numItems)))
409+
}
410+
}

0 commit comments

Comments
 (0)