mirror of https://github.com/tidwall/tile38.git
wip Packed
This commit is contained in:
parent
a60dc57598
commit
8bbf6ab848
|
@ -1,17 +1,29 @@
|
||||||
package collection
|
package collection
|
||||||
|
|
||||||
import "github.com/tidwall/tile38/internal/collection/item"
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
// // FieldIter ...
|
"github.com/tidwall/tile38/internal/collection/item"
|
||||||
// type FieldIter interface {
|
)
|
||||||
// ForEachField(count int, iter func(value float64) bool)
|
|
||||||
// GetField(index int) float64
|
|
||||||
// HasFields() bool
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Fields ...
|
// Fields ...
|
||||||
type Fields struct {
|
type Fields struct {
|
||||||
item *item.Item
|
mu sync.Mutex
|
||||||
|
unpacked bool // fields have been unpacked
|
||||||
|
values []float64 // unpacked values
|
||||||
|
item *item.Item // base item
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fields *Fields) unpack() {
|
||||||
|
if fields.unpacked {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fields.values = nil
|
||||||
|
fields.item.ForEachField(-1, func(value float64) bool {
|
||||||
|
fields.values = append(fields.values, value)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
fields.unpacked = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEach iterates over each field. The count param is the number of
|
// ForEach iterates over each field. The count param is the number of
|
||||||
|
@ -20,7 +32,31 @@ func (fields *Fields) ForEach(count int, iter func(value float64) bool) {
|
||||||
if fields == nil || fields.item == nil {
|
if fields == nil || fields.item == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fields.item.ForEachField(count, iter)
|
if !item.PackedFields {
|
||||||
|
fields.item.ForEachField(count, iter)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// packed values
|
||||||
|
fields.mu.Lock()
|
||||||
|
defer fields.mu.Unlock()
|
||||||
|
if !fields.unpacked {
|
||||||
|
fields.unpack()
|
||||||
|
}
|
||||||
|
var n int
|
||||||
|
if count < 0 {
|
||||||
|
n = len(fields.values)
|
||||||
|
} else {
|
||||||
|
n = count
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
var field float64
|
||||||
|
if i < len(fields.values) {
|
||||||
|
field = fields.values[i]
|
||||||
|
}
|
||||||
|
if !iter(field) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the value for a field at index. If there is no field at index,
|
// Get returns the value for a field at index. If there is no field at index,
|
||||||
|
@ -29,7 +65,20 @@ func (fields *Fields) Get(index int) float64 {
|
||||||
if fields == nil || fields.item == nil {
|
if fields == nil || fields.item == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return fields.item.GetField(index)
|
if !item.PackedFields {
|
||||||
|
return fields.item.GetField(index)
|
||||||
|
}
|
||||||
|
// packed values
|
||||||
|
fields.mu.Lock()
|
||||||
|
if !fields.unpacked {
|
||||||
|
fields.unpack()
|
||||||
|
}
|
||||||
|
var value float64
|
||||||
|
if index < len(fields.values) {
|
||||||
|
value = fields.values[index]
|
||||||
|
}
|
||||||
|
fields.mu.Unlock()
|
||||||
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
func itemFields(item *item.Item) *Fields {
|
func itemFields(item *item.Item) *Fields {
|
||||||
|
|
|
@ -8,6 +8,9 @@ import (
|
||||||
"github.com/tidwall/geojson"
|
"github.com/tidwall/geojson"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PackedFields indicates that fields are bit packed
|
||||||
|
const PackedFields = true
|
||||||
|
|
||||||
// Item is a item for Tile38 collections
|
// Item is a item for Tile38 collections
|
||||||
type Item struct {
|
type Item struct {
|
||||||
point bool // true: Item is pointItem, false: Item is objItem
|
point bool // true: Item is pointItem, false: Item is objItem
|
||||||
|
|
Loading…
Reference in New Issue