From c0836dd1ac7721ccda567c6f8ad99b34558d6ff2 Mon Sep 17 00:00:00 2001 From: Josh Baker Date: Sun, 3 Apr 2016 07:59:23 -0700 Subject: [PATCH] added coverage --- .gitignore | 1 + Makefile | 2 ++ build.sh | 11 +++++++ index/index.go | 12 +++---- index/index_test.go | 74 +++++++++++++++++++++++++++++++++++++++----- index/rtree/rtree.go | 21 +++++++++++++ 6 files changed, 107 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index d5a1d1aa..e6117223 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ tile38-* !cmd/tile38-* data*/ +coverage.out \ No newline at end of file diff --git a/Makefile b/Makefile index 41fa8afa..73e5d911 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,8 @@ clean: rm -f tile38-cli test: @./build.sh test +cover: + @./build.sh cover install: all cp tile38-server /usr/local/bin cp tile38-cli /usr/local/bin diff --git a/build.sh b/build.sh index 5213e796..78495526 100755 --- a/build.sh +++ b/build.sh @@ -108,3 +108,14 @@ if [ "$1" == "test" ]; then go test $(go list ./... | grep -v /vendor/) fi +# cover if requested +if [ "$1" == "cover" ]; then + $OD/tile38-server -p 9876 -d "$TMP" -q & + PID=$! + function testend { + kill $PID & + } + trap testend EXIT + go test -cover $(go list ./... | grep -v /vendor/) +fi + diff --git a/index/index.go b/index/index.go index b8184808..5c2c479d 100644 --- a/index/index.go +++ b/index/index.go @@ -201,8 +201,6 @@ func (ix *Index) Search(cursor uint64, swLat, swLon, neLat, neLon float64, itera idm[iitm] = true active = iterator(iitm) } - } else { - active = iterator(iitm) } } idx++ @@ -217,12 +215,14 @@ func (ix *Index) Search(cursor uint64, swLat, swLon, neLat, neLon float64, itera if idx >= cursor { iitm := ix.getRTreeItem(item) if iitm != nil { - if !idm[iitm] { - idm[iitm] = true + if ix.mulm[iitm] { + if !idm[iitm] { + idm[iitm] = true + active = iterator(iitm) + } + } else { active = iterator(iitm) } - } else { - active = iterator(iitm) } } idx++ diff --git a/index/index_test.go b/index/index_test.go index 40018161..da1d1eb7 100644 --- a/index/index_test.go +++ b/index/index_test.go @@ -13,11 +13,13 @@ func randf(min, max float64) float64 { } func randPoint() (lat float64, lon float64) { - return randf(-90, 90), randf(-180, 180) + // intentionally go out of range. + return randf(-100, 100), randf(-190, 190) } func randRect() (swLat, swLon, neLat, neLon float64) { swLat, swLon = randPoint() + // intentionally go out of range even more. neLat = randf(swLat-10, swLat+10) neLon = randf(swLon-10, swLon+10) return @@ -33,8 +35,8 @@ func wp(swLat, swLon, neLat, neLon float64) *FlexItem { } func TestRandomInserts(t *testing.T) { - rand.Seed(0) //time.Now().UnixNano()) - l := 1000000 + rand.Seed(time.Now().UnixNano()) + l := 200000 tr := New() start := time.Now() i := 0 @@ -50,30 +52,86 @@ func TestRandomInserts(t *testing.T) { tr.Insert(wp(swLat, swLon, neLat, neLon)) } insrdur := time.Now().Sub(start) + count := 0 - count := tr.Count() + count = tr.Count() if count != l { t.Fatalf("count == %d, expect %d", count, l) } count = 0 + items := make([]Item, 0, l) tr.Search(0, -90, -180, 90, 180, func(item Item) bool { count++ + items = append(items, item) return true }) if count != l { t.Fatalf("count == %d, expect %d", count, l) } start = time.Now() - count = 0 + count1 := 0 tr.Search(0, 33, -115, 34, -114, func(item Item) bool { - count++ + count1++ return true }) - searchdur := time.Now().Sub(start) + searchdur1 := time.Now().Sub(start) + + start = time.Now() + count2 := 0 + + tr.Search(0, 33-180, -115-360, 34-180, -114-360, func(item Item) bool { + count2++ + return true + }) + searchdur2 := time.Now().Sub(start) + + start = time.Now() + count3 := 0 + tr.Search(0, -10, 170, 20, 200, func(item Item) bool { + count3++ + return true + }) + searchdur3 := time.Now().Sub(start) fmt.Printf("Randomly inserted %d points in %s.\n", l/2, inspdur.String()) fmt.Printf("Randomly inserted %d rects in %s.\n", l/2, insrdur.String()) - fmt.Printf("Searched %d items in %s.\n", count, searchdur.String()) + fmt.Printf("Searched %d items in %s.\n", count1, searchdur1.String()) + fmt.Printf("Searched %d items in %s.\n", count2, searchdur2.String()) + fmt.Printf("Searched %d items in %s.\n", count3, searchdur3.String()) + + tr.Search(0, -10, 170, 20, 200, func(item Item) bool { + lat1, lon1, lat2, lon2 := item.Rect() + if lat1 == lat2 && lon1 == lon2 { + return false + } + return true + }) + + tr.Search(0, -10, 170, 20, 200, func(item Item) bool { + lat1, lon1, lat2, lon2 := item.Rect() + if lat1 != lat2 || lon1 != lon2 { + return false + } + return true + }) + + // Remove all of the elements + for _, item := range items { + tr.Remove(item) + } + + count = tr.Count() + if count != 0 { + t.Fatalf("count == %d, expect %d", count, 0) + } + + tr.RemoveAll() + if tr.getQTreeItem(nil) != nil { + t.Fatal("getQTreeItem(nil) should return nil") + } + if tr.getRTreeItem(nil) != nil { + t.Fatal("getRTreeItem(nil) should return nil") + } } func TestMemory(t *testing.T) { diff --git a/index/rtree/rtree.go b/index/rtree/rtree.go index 41189196..5310ff95 100644 --- a/index/rtree/rtree.go +++ b/index/rtree/rtree.go @@ -189,6 +189,9 @@ func insertRectRec(rect rectT, item Item, node *nodeT, newNode **nodeT, level in var branch branchT var otherNode *nodeT // Still above level for insertion, go down tree recursively + if node == nil { + return false + } if node.level > level { index = pickBranch(rect, node) if !insertRectRec(rect, item, node.branch[index].child, &otherNode, level) { @@ -198,6 +201,9 @@ func insertRectRec(rect rectT, item Item, node *nodeT, newNode **nodeT, level in } // Child was split node.branch[index].rect = nodeCover(node.branch[index].child) branch.child = otherNode + if branch.child == nil { + println(">> child assigned is nil") + } branch.rect = nodeCover(otherNode) return addBranch(&branch, node, newNode) } else if node.level == level { // Have reached level for insertion. Add rect, split if necessary @@ -221,14 +227,23 @@ func insertRect(rect rectT, item Item, root **nodeT, level int) bool { var newRoot *nodeT var newNode *nodeT var branch branchT + if *root == nil { + println(">> root is nil") + } if insertRectRec(rect, item, *root, &newNode, level) { // Root split newRoot = &nodeT{} // Grow tree taller and new root newRoot.level = (*root).level + 1 branch.rect = nodeCover(*root) branch.child = *root + if branch.child == nil { + println(">> child assigned is nil 2") + } addBranch(&branch, newRoot, nil) branch.rect = nodeCover(newNode) branch.child = newNode + if branch.child == nil { + println(">> child assigned is nil 3") + } addBranch(&branch, newRoot, nil) *root = newRoot return true @@ -549,6 +564,9 @@ func removeRect(rect rectT, item Item, root **nodeT) bool { // merges branches on the way back up. // Returns 1 if record not found, 0 if success. func removeRectRec(rect rectT, item Item, node *nodeT, listNode **listNodeT) bool { + if node == nil { + return true + } if node.isInternalNode() { // not a leaf node for index := 0; index < node.count; index++ { if overlap(rect, node.branch[index].rect) { @@ -599,6 +617,9 @@ func reInsert(node *nodeT, listNode **listNodeT) { // Search in an index tree or subtree for all data retangles that overlap the argument rectangle. func search(node *nodeT, rect rectT, iterator func(item Item) bool) bool { + if node == nil { + return true + } if node.isInternalNode() { // This is an internal node in the tree for index := 0; index < node.count; index++ { nrect := node.branch[index].rect