tile38/pkg/index/index_test.go

234 lines
5.2 KiB
Go
Raw Normal View History

2016-03-05 02:08:16 +03:00
package index
import (
"fmt"
"math/rand"
"runtime"
"testing"
"time"
)
func randf(min, max float64) float64 {
return rand.Float64()*(max-min) + min
}
func randPoint() (lat float64, lon float64) {
2016-04-03 17:59:23 +03:00
// intentionally go out of range.
return randf(-100, 100), randf(-190, 190)
2016-03-05 02:08:16 +03:00
}
func randRect() (swLat, swLon, neLat, neLon float64) {
swLat, swLon = randPoint()
2016-04-03 17:59:23 +03:00
// intentionally go out of range even more.
2016-03-05 02:08:16 +03:00
neLat = randf(swLat-10, swLat+10)
neLon = randf(swLon-10, swLon+10)
return
}
func wp(swLat, swLon, neLat, neLon float64) *FlexItem {
return &FlexItem{
MinX: swLon,
MinY: swLat,
MaxX: neLon,
MaxY: neLat,
}
}
func TestRandomInserts(t *testing.T) {
2016-04-03 17:59:23 +03:00
rand.Seed(time.Now().UnixNano())
l := 200000
2016-03-05 02:08:16 +03:00
tr := New()
start := time.Now()
i := 0
for ; i < l/2; i++ {
swLat, swLon := randPoint()
tr.Insert(wp(swLat, swLon, swLat, swLon))
}
inspdur := time.Now().Sub(start)
start = time.Now()
for ; i < l; i++ {
swLat, swLon, neLat, neLon := randRect()
tr.Insert(wp(swLat, swLon, neLat, neLon))
}
insrdur := time.Now().Sub(start)
2016-04-03 17:59:23 +03:00
count := 0
2016-03-05 02:08:16 +03:00
2016-04-03 17:59:23 +03:00
count = tr.Count()
2016-03-05 02:08:16 +03:00
if count != l {
t.Fatalf("count == %d, expect %d", count, l)
}
count = 0
2016-04-03 17:59:23 +03:00
items := make([]Item, 0, l)
2017-08-11 03:32:40 +03:00
tr.Search(-90, -180, 90, 180, 0, 0, func(item interface{}) bool {
2016-03-05 02:08:16 +03:00
count++
2017-08-11 03:32:40 +03:00
items = append(items, item.(Item))
2016-03-05 02:08:16 +03:00
return true
})
if count != l {
t.Fatalf("count == %d, expect %d", count, l)
}
start = time.Now()
2016-04-03 17:59:23 +03:00
count1 := 0
2017-08-11 03:32:40 +03:00
tr.Search(33, -115, 34, -114, 0, 0, func(item interface{}) bool {
2016-04-03 17:59:23 +03:00
count1++
return true
})
searchdur1 := time.Now().Sub(start)
start = time.Now()
count2 := 0
2017-08-11 03:32:40 +03:00
tr.Search(33-180, -115-360, 34-180, -114-360, 0, 0, func(item interface{}) bool {
2016-04-03 17:59:23 +03:00
count2++
return true
})
searchdur2 := time.Now().Sub(start)
start = time.Now()
count3 := 0
2017-08-11 03:32:40 +03:00
tr.Search(-10, 170, 20, 200, 0, 0, func(item interface{}) bool {
2016-04-03 17:59:23 +03:00
count3++
2016-03-05 02:08:16 +03:00
return true
})
2016-04-03 17:59:23 +03:00
searchdur3 := time.Now().Sub(start)
2016-03-05 02:08:16 +03:00
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())
2016-04-03 17:59:23 +03:00
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())
2017-08-11 03:32:40 +03:00
tr.Search(-10, 170, 20, 200, 0, 0, func(item interface{}) bool {
lat1, lon1, _, lat2, lon2, _ := item.(Item).Rect()
2016-04-03 17:59:23 +03:00
if lat1 == lat2 && lon1 == lon2 {
return false
}
return true
})
2017-08-11 03:32:40 +03:00
tr.Search(-10, 170, 20, 200, 0, 0, func(item interface{}) bool {
lat1, lon1, _, lat2, lon2, _ := item.(Item).Rect()
2016-04-03 17:59:23 +03:00
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()
2016-08-19 17:47:39 +03:00
/* if tr.getQTreeItem(nil) != nil {
t.Fatal("getQTreeItem(nil) should return nil")
}
*/
2016-04-03 17:59:23 +03:00
if tr.getRTreeItem(nil) != nil {
t.Fatal("getRTreeItem(nil) should return nil")
}
2016-03-05 02:08:16 +03:00
}
func TestMemory(t *testing.T) {
rand.Seed(0)
l := 100000
tr := New()
for i := 0; i < l; i++ {
swLat, swLon, neLat, neLon := randRect()
if rand.Int()%2 == 0 { // one in three chance that the rect is actually a point.
neLat, neLon = swLat, swLon
}
tr.Insert(wp(swLat, swLon, neLat, neLon))
}
runtime.GC()
var m runtime.MemStats
runtime.ReadMemStats(&m)
const PtrSize = 32 << uintptr(uint64(^uintptr(0))>>63)
fmt.Printf("Memory consumption is %d bytes/object. Pointers are %d bytes.\n", int(m.HeapAlloc)/tr.Count(), PtrSize/8)
}
func TestInsertVarious(t *testing.T) {
var count int
tr := New()
item := wp(33, -115, 33, -115)
tr.Insert(item)
count = tr.Count()
if count != 1 {
t.Fatalf("count = %d, expect 1", count)
}
tr.Remove(item)
count = tr.Count()
if count != 0 {
t.Fatalf("count = %d, expect 0", count)
}
tr.Insert(item)
count = tr.Count()
if count != 1 {
t.Fatalf("count = %d, expect 1", count)
}
found := false
2017-08-11 03:32:40 +03:00
tr.Search(-90, -180, 90, 180, 0, 0, func(item2 interface{}) bool {
if item2.(Item) == item {
2016-03-05 02:08:16 +03:00
found = true
}
return true
})
if !found {
t.Fatal("did not find item")
}
}
func BenchmarkInsertRect(b *testing.B) {
rand.Seed(time.Now().UnixNano())
tr := New()
for i := 0; i < b.N; i++ {
swLat, swLon, neLat, neLon := randRect()
tr.Insert(wp(swLat, swLon, neLat, neLon))
}
}
func BenchmarkInsertPoint(b *testing.B) {
rand.Seed(time.Now().UnixNano())
tr := New()
for i := 0; i < b.N; i++ {
swLat, swLon, _, _ := randRect()
tr.Insert(wp(swLat, swLon, swLat, swLon))
}
}
func BenchmarkInsertEither(b *testing.B) {
rand.Seed(time.Now().UnixNano())
tr := New()
for i := 0; i < b.N; i++ {
swLat, swLon, neLat, neLon := randRect()
if rand.Int()%3 == 0 { // one in three chance that the rect is actually a point.
neLat, neLon = swLat, swLon
}
tr.Insert(wp(swLat, swLon, neLat, neLon))
}
}
// func BenchmarkSearchRect(b *testing.B) {
// rand.Seed(time.Now().UnixNano())
// tr := New()
// for i := 0; i < 100000; i++ {
// swLat, swLon, neLat, neLon := randRect()
// tr.Insert(swLat, swLon, neLat, neLon)
// }
// b.ResetTimer()
// count := 0
// //for i := 0; i < b.N; i++ {
// tr.Search(0, -180, 90, 180, func(id int) bool {
// count++
// return true
// })
// //}
// println(count)
// }