2016-03-05 02:08:16 +03:00
|
|
|
package collection
|
|
|
|
|
|
|
|
import (
|
2016-12-31 00:18:28 +03:00
|
|
|
"fmt"
|
2016-03-05 02:08:16 +03:00
|
|
|
"math/rand"
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
2016-12-31 00:18:28 +03:00
|
|
|
"time"
|
2016-03-05 02:08:16 +03:00
|
|
|
|
|
|
|
"github.com/tidwall/tile38/geojson"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestCollection(t *testing.T) {
|
|
|
|
const numItems = 10000
|
|
|
|
objs := make(map[string]geojson.Object)
|
|
|
|
c := New()
|
|
|
|
for i := 0; i < numItems; i++ {
|
|
|
|
id := strconv.FormatInt(int64(i), 10)
|
|
|
|
var obj geojson.Object
|
|
|
|
p := geojson.Position{X: rand.Float64()*360 - 180, Y: rand.Float64()*180 - 90, Z: 0}
|
|
|
|
if rand.Int()%2 == 0 {
|
|
|
|
obj = geojson.Point{Coordinates: p}
|
|
|
|
} else {
|
|
|
|
minX, minY := rand.Float64()*360-180, rand.Float64()*180-90
|
|
|
|
obj = geojson.Point{Coordinates: p, BBox: &geojson.BBox{
|
|
|
|
Min: geojson.Position{X: minX, Y: minY, Z: 0},
|
|
|
|
Max: geojson.Position{X: minX + 100, Y: minY + 100, Z: 0},
|
|
|
|
}}
|
|
|
|
}
|
|
|
|
objs[id] = obj
|
|
|
|
c.ReplaceOrInsert(id, obj, nil, nil)
|
|
|
|
}
|
|
|
|
count := 0
|
|
|
|
bbox := geojson.BBox{Min: geojson.Position{X: -180, Y: -90, Z: 0}, Max: geojson.Position{X: 180, Y: 90, Z: 0}}
|
2017-07-24 18:26:10 +03:00
|
|
|
c.geoSearch(bbox, func(id string, obj geojson.Object, field []float64) bool {
|
2016-03-05 02:08:16 +03:00
|
|
|
count++
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
if count != len(objs) {
|
|
|
|
t.Fatalf("count = %d, expect %d", count, len(objs))
|
|
|
|
}
|
2016-07-13 08:03:52 +03:00
|
|
|
count = c.Count()
|
2016-03-05 02:08:16 +03:00
|
|
|
if count != len(objs) {
|
|
|
|
t.Fatalf("c.Count() = %d, expect %d", count, len(objs))
|
|
|
|
}
|
|
|
|
testCollectionVerifyContents(t, c, objs)
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCollectionVerifyContents(t *testing.T, c *Collection, objs map[string]geojson.Object) {
|
|
|
|
for id, o2 := range objs {
|
|
|
|
o1, _, ok := c.Get(id)
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("ok[%s] = false, expect true", id)
|
|
|
|
}
|
|
|
|
j1 := o1.JSON()
|
|
|
|
j2 := o2.JSON()
|
|
|
|
if j1 != j2 {
|
|
|
|
t.Fatalf("j1 == %s, expect %s", j1, j2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestManyCollections(t *testing.T) {
|
|
|
|
colsM := make(map[string]*Collection)
|
|
|
|
cols := 100
|
|
|
|
objs := 1000
|
|
|
|
k := 0
|
|
|
|
for i := 0; i < cols; i++ {
|
|
|
|
key := strconv.FormatInt(int64(i), 10)
|
|
|
|
for j := 0; j < objs; j++ {
|
|
|
|
id := strconv.FormatInt(int64(j), 10)
|
|
|
|
p := geojson.Position{X: rand.Float64()*360 - 180, Y: rand.Float64()*180 - 90, Z: 0}
|
|
|
|
obj := geojson.Object(geojson.Point{Coordinates: p})
|
|
|
|
col, ok := colsM[key]
|
|
|
|
if !ok {
|
|
|
|
col = New()
|
|
|
|
colsM[key] = col
|
|
|
|
}
|
|
|
|
col.ReplaceOrInsert(id, obj, nil, nil)
|
|
|
|
k++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
col := colsM["13"]
|
|
|
|
//println(col.Count())
|
|
|
|
bbox := geojson.BBox{Min: geojson.Position{X: -180, Y: 30, Z: 0}, Max: geojson.Position{X: 34, Y: 100, Z: 0}}
|
2017-07-24 18:26:10 +03:00
|
|
|
col.geoSearch(bbox, func(id string, obj geojson.Object, fields []float64) bool {
|
2016-03-05 02:08:16 +03:00
|
|
|
//println(id)
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
}
|
2016-12-31 00:18:28 +03:00
|
|
|
|
2016-12-31 19:29:02 +03:00
|
|
|
type testPointItem struct {
|
|
|
|
id string
|
|
|
|
object geojson.Object
|
|
|
|
}
|
|
|
|
|
2016-12-31 00:18:28 +03:00
|
|
|
func BenchmarkInsert(t *testing.B) {
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
2016-12-31 19:29:02 +03:00
|
|
|
items := make([]testPointItem, t.N)
|
|
|
|
for i := 0; i < t.N; i++ {
|
|
|
|
items[i] = testPointItem{
|
|
|
|
fmt.Sprintf("%d", i),
|
|
|
|
geojson.SimplePoint{
|
|
|
|
Y: rand.Float64()*180 - 90,
|
|
|
|
X: rand.Float64()*360 - 180,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
col := New()
|
|
|
|
t.ResetTimer()
|
|
|
|
for i := 0; i < t.N; i++ {
|
|
|
|
col.ReplaceOrInsert(items[i].id, items[i].object, nil, nil)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkReplace(t *testing.B) {
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
items := make([]testPointItem, t.N)
|
|
|
|
for i := 0; i < t.N; i++ {
|
|
|
|
items[i] = testPointItem{
|
|
|
|
fmt.Sprintf("%d", i),
|
|
|
|
geojson.SimplePoint{
|
|
|
|
Y: rand.Float64()*180 - 90,
|
|
|
|
X: rand.Float64()*360 - 180,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
col := New()
|
|
|
|
for i := 0; i < t.N; i++ {
|
|
|
|
col.ReplaceOrInsert(items[i].id, items[i].object, nil, nil)
|
|
|
|
}
|
|
|
|
t.ResetTimer()
|
|
|
|
for _, i := range rand.Perm(t.N) {
|
|
|
|
o, _, _ := col.ReplaceOrInsert(items[i].id, items[i].object, nil, nil)
|
|
|
|
if o != items[i].object {
|
|
|
|
t.Fatal("shoot!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkGet(t *testing.B) {
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
items := make([]testPointItem, t.N)
|
2016-12-31 00:18:28 +03:00
|
|
|
for i := 0; i < t.N; i++ {
|
2016-12-31 19:29:02 +03:00
|
|
|
items[i] = testPointItem{
|
|
|
|
fmt.Sprintf("%d", i),
|
|
|
|
geojson.SimplePoint{
|
|
|
|
Y: rand.Float64()*180 - 90,
|
|
|
|
X: rand.Float64()*360 - 180,
|
|
|
|
},
|
2016-12-31 00:18:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
col := New()
|
2016-12-31 19:29:02 +03:00
|
|
|
for i := 0; i < t.N; i++ {
|
|
|
|
col.ReplaceOrInsert(items[i].id, items[i].object, nil, nil)
|
|
|
|
}
|
2016-12-31 00:18:28 +03:00
|
|
|
t.ResetTimer()
|
2016-12-31 19:29:02 +03:00
|
|
|
for _, i := range rand.Perm(t.N) {
|
|
|
|
o, _, _ := col.Get(items[i].id)
|
|
|
|
if o != items[i].object {
|
|
|
|
t.Fatal("shoot!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkRemove(t *testing.B) {
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
items := make([]testPointItem, t.N)
|
2016-12-31 00:18:28 +03:00
|
|
|
for i := 0; i < t.N; i++ {
|
2016-12-31 19:29:02 +03:00
|
|
|
items[i] = testPointItem{
|
|
|
|
fmt.Sprintf("%d", i),
|
|
|
|
geojson.SimplePoint{
|
|
|
|
Y: rand.Float64()*180 - 90,
|
|
|
|
X: rand.Float64()*360 - 180,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
col := New()
|
|
|
|
for i := 0; i < t.N; i++ {
|
|
|
|
col.ReplaceOrInsert(items[i].id, items[i].object, nil, nil)
|
|
|
|
}
|
|
|
|
t.ResetTimer()
|
|
|
|
for _, i := range rand.Perm(t.N) {
|
|
|
|
o, _, _ := col.Remove(items[i].id)
|
|
|
|
if o != items[i].object {
|
|
|
|
t.Fatal("shoot!")
|
|
|
|
}
|
2016-12-31 00:18:28 +03:00
|
|
|
}
|
|
|
|
}
|