mirror of https://github.com/tidwall/tile38.git
Minimize sorting of collection fields
This commit is contained in:
parent
0997f2e82b
commit
b482206894
|
@ -2,7 +2,6 @@ package collection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/tidwall/btree"
|
"github.com/tidwall/btree"
|
||||||
"github.com/tidwall/geoindex"
|
"github.com/tidwall/geoindex"
|
||||||
|
@ -47,6 +46,7 @@ type Collection struct {
|
||||||
index *geoindex.Index // items geospatially indexed
|
index *geoindex.Index // items geospatially indexed
|
||||||
values *btree.BTree // items sorted by value+key
|
values *btree.BTree // items sorted by value+key
|
||||||
fieldMap map[string]int
|
fieldMap map[string]int
|
||||||
|
fieldArr []string
|
||||||
fieldValues map[string][]float64
|
fieldValues map[string][]float64
|
||||||
weight int
|
weight int
|
||||||
points int
|
points int
|
||||||
|
@ -62,6 +62,7 @@ func New() *Collection {
|
||||||
index: geoindex.Wrap(&rbang.RTree{}),
|
index: geoindex.Wrap(&rbang.RTree{}),
|
||||||
values: btree.New(32, nil),
|
values: btree.New(32, nil),
|
||||||
fieldMap: make(map[string]int),
|
fieldMap: make(map[string]int),
|
||||||
|
fieldArr: make([]string, 0),
|
||||||
}
|
}
|
||||||
return col
|
return col
|
||||||
}
|
}
|
||||||
|
@ -72,11 +73,7 @@ func (c *Collection) setFieldValues(id string, values []float64) {
|
||||||
}
|
}
|
||||||
c.fieldValues[id] = values
|
c.fieldValues[id] = values
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collection) getFieldValues(id string) (values []float64) {
|
func (c *Collection) getFieldValues(id string) (values []float64) {
|
||||||
if c.fieldValues == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c.fieldValues[id]
|
return c.fieldValues[id]
|
||||||
}
|
}
|
||||||
func (c *Collection) deleteFieldValues(id string) {
|
func (c *Collection) deleteFieldValues(id string) {
|
||||||
|
@ -296,6 +293,7 @@ func (c *Collection) setField(item *itemT, field string, value float64) (
|
||||||
if !ok {
|
if !ok {
|
||||||
idx = len(c.fieldMap)
|
idx = len(c.fieldMap)
|
||||||
c.fieldMap[field] = idx
|
c.fieldMap[field] = idx
|
||||||
|
c.addToFieldArr(field)
|
||||||
}
|
}
|
||||||
fields := c.getFieldValues(item.id)
|
fields := c.getFieldValues(item.id)
|
||||||
c.weight -= len(fields) * 8
|
c.weight -= len(fields) * 8
|
||||||
|
@ -316,12 +314,32 @@ func (c *Collection) FieldMap() map[string]int {
|
||||||
|
|
||||||
// FieldArr return an array representation of the field names.
|
// FieldArr return an array representation of the field names.
|
||||||
func (c *Collection) FieldArr() []string {
|
func (c *Collection) FieldArr() []string {
|
||||||
arr := make([]string, len(c.fieldMap))
|
return c.fieldArr
|
||||||
for field, i := range c.fieldMap {
|
}
|
||||||
arr[i] = field
|
|
||||||
|
// bsearch searches array for value.
|
||||||
|
func bsearch(arr []string, val string) (index int, found bool) {
|
||||||
|
i, j := 0, len(arr)
|
||||||
|
for i < j {
|
||||||
|
h := i + (j-i)/2
|
||||||
|
if val >= arr[h] {
|
||||||
|
i = h + 1
|
||||||
|
} else {
|
||||||
|
j = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i > 0 && arr[i-1] >= val {
|
||||||
|
return i - 1, true
|
||||||
|
}
|
||||||
|
return i, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collection) addToFieldArr(field string) {
|
||||||
|
if index, found := bsearch(c.fieldArr, field); !found {
|
||||||
|
c.fieldArr = append(c.fieldArr, "")
|
||||||
|
copy(c.fieldArr[index+1:], c.fieldArr[index:len(c.fieldArr)-1])
|
||||||
|
c.fieldArr[index] = field
|
||||||
}
|
}
|
||||||
sort.Strings(arr)
|
|
||||||
return arr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan iterates though the collection ids.
|
// Scan iterates though the collection ids.
|
||||||
|
|
Loading…
Reference in New Issue