Permalink
Browse files

implement initial condenseTree: doesn't reinsert non-leaf entries pro…

…perly
  • Loading branch information...
1 parent af97807 commit 3436def23d076b86a8374658eebb25612c8f03d4 @dhconnelly committed Apr 1, 2012
Showing with 70 additions and 1 deletion.
  1. +45 −1 rtree.go
  2. +25 −0 rtree_test.go
View
@@ -330,7 +330,51 @@ func (tree *Rtree) findLeaf(n *node, obj Spatial) *node {
return nil
}
+func items(n *node) chan Spatial {
+ ch := make(chan Spatial)
+ go func() {
+ for _, e := range n.entries {
+ if n.leaf {
+ ch <- e.obj
+ } else {
+ for obj := range items(e.child) {
+ ch <- obj
+ }
+ }
+ }
+ close(ch)
+ }()
+ return ch
+}
+
// condenseTree deletes underflowing nodes and propagates the changes upwards.
func (tree *Rtree) condenseTree(n *node) *node {
- return nil
+ deleted := []*node{}
+
+ for n != tree.root {
+ if len(n.entries) < tree.MinChildren {
+ // remove n from parent entries
+ deleted = append(deleted, n)
+ entries := []entry{}
+ for _, e := range n.parent.entries {
+ if e.child != n {
+ entries = append(entries, e)
+ }
+ }
+ n.parent.entries = entries
+ } else {
+ // just a child entry deletion, no underflow
+ n.getEntry().bb = n.computeBoundingBox()
+ }
+ n = n.parent
+ }
+
+ // TODO higher-level nodes must be higher in the tree?
+ for _, n := range deleted {
+ for obj := range items(n) {
+ tree.Insert(obj)
+ }
+ }
+
+ return n
}
View
@@ -439,3 +439,28 @@ func TestFindLeaf(t *testing.T) {
t.Errorf("Failed to locate leaf containing %v", obj)
}
}
+
+func TestCondenseTreeEliminate(t *testing.T) {
+ rt := NewTree(2, 3, 3)
+ things := []*Rect{
+ mustRect(Point{0, 0}, []float64{2, 1}),
+ mustRect(Point{3, 1}, []float64{1, 2}),
+ mustRect(Point{1, 2}, []float64{2, 2}),
+ mustRect(Point{8, 6}, []float64{1, 1}),
+ mustRect(Point{10, 3}, []float64{1, 2}),
+ mustRect(Point{11, 7}, []float64{1, 1}),
+ mustRect(Point{0, 6}, []float64{1, 2}),
+ mustRect(Point{1, 6}, []float64{1, 2}),
+ mustRect(Point{0, 8}, []float64{1, 2}),
+ mustRect(Point{1, 8}, []float64{1, 2}),
+ }
+ for _, thing := range things {
+ rt.Insert(thing)
+ }
+
+ // delete entry 2 from parent entries
+ printNode(rt.root, 0)
+ parent := rt.root.entries[0].child.entries[1].child
+ parent.entries = append(parent.entries[:2], parent.entries[3:]...)
+ printNode(rt.condenseTree(parent), 0)
+}

0 comments on commit 3436def

Please sign in to comment.