wip Packed

This commit is contained in:
tidwall 2019-02-15 08:47:27 -07:00
parent a60dc57598
commit 8bbf6ab848
2 changed files with 62 additions and 10 deletions

View File

@ -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
} }
if !item.PackedFields {
fields.item.ForEachField(count, iter) 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
} }
if !item.PackedFields {
return fields.item.GetField(index) 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 {

View File

@ -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