Switch Set from using a Map to a sorted set internally.

This commit is contained in:
Aaron Boodman
2015-07-20 08:16:43 -07:00
parent 69cef43527
commit 636708e302
2 changed files with 26 additions and 22 deletions
+1 -12
View File
@@ -3,7 +3,6 @@ package types
import (
"encoding/json"
"fmt"
"sort"
"github.com/attic-labs/noms/chunks"
. "github.com/attic-labs/noms/dbg"
@@ -135,18 +134,8 @@ func getJSONMap(m Map, s chunks.ChunkSink) (r interface{}, err error) {
}
func getJSONSet(set Set, s chunks.ChunkSink) (r interface{}, err error) {
// Iteration through Set is random, but we need a deterministic order for serialization. Let's order using the refs of the values in the set.
lookup := setData{}
order := ref.RefSlice{}
for _, f := range set.m {
order = append(order, f.Ref())
lookup[f.Ref()] = f
}
sort.Sort(order)
j := []interface{}{}
for _, r := range order {
f := lookup[r]
for _, f := range set.m {
var cj interface{}
cj, err = getChildJSON(f, s)
if err != nil {
+25 -10
View File
@@ -1,15 +1,17 @@
package types
import (
"sort"
"github.com/attic-labs/noms/chunks"
. "github.com/attic-labs/noms/dbg"
"github.com/attic-labs/noms/ref"
)
type setData map[ref.Ref]future
type setData []future
type Set struct {
m setData
m setData // sorted by Ref()
cs chunks.ChunkSource
ref *ref.Ref
}
@@ -31,8 +33,8 @@ func (fs Set) Len() uint64 {
}
func (fs Set) Has(v Value) bool {
_, ok := fs.m[v.Ref()]
return ok
idx := indexSetData(fs.m, v.Ref())
return idx < len(fs.m) && fs.m[idx].Ref() == v.Ref()
}
func (fs Set) Insert(values ...Value) Set {
@@ -43,7 +45,10 @@ func (fs Set) Remove(values ...Value) Set {
m2 := copySetData(fs.m)
for _, v := range values {
if v != nil {
delete(m2, v.Ref())
idx := indexSetData(fs.m, v.Ref())
if idx < len(fs.m) && fs.m[idx].Ref() == v.Ref() {
m2 = append(m2[:idx], m2[idx+1:]...)
}
}
}
return newSetFromData(m2, fs.cs)
@@ -110,17 +115,27 @@ func newSetFromData(m setData, cs chunks.ChunkSource) Set {
}
func copySetData(m setData) setData {
r := setData{}
for k, f := range m {
r[k] = f
}
r := make(setData, len(m))
copy(r, m)
return r
}
func buildSetData(old setData, futures []future) setData {
m := copySetData(old)
for _, f := range futures {
m[f.Ref()] = f
idx := indexSetData(m, f.Ref())
if idx == len(m) || m[idx].Ref() != f.Ref() {
// The key isn't present. Make room for it.
m = append(m, nil)
copy(m[idx+1:], m[idx:])
}
m[idx] = f
}
return m
}
func indexSetData(m setData, r ref.Ref) int {
return sort.Search(len(m), func(i int) bool {
return !ref.Less(m[i].Ref(), r)
})
}