mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-27 23:51:59 -05:00
Switch Set from using a Map to a sorted set internally.
This commit is contained in:
+1
-12
@@ -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
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user