Change Value.Chunks() to return []types.RefBase

In pursuit of issue #654, we want to be able to figure out all the
refs contained in a given Value, along with the Types of the Values to
which those refs point. Value.Chunks() _almost_ met those needs, but
it returned a slice of ref.Ref, which doesn't convey any type info.

To address this, this patch does two things:
1) RefBase embeds the Value interface, and
2) Chunks() now returns []types.RefBase

RefBase now provides Type() as well, by virtue of embedding Value, so
callers can just iterate through the slice returned from Chunks() and
gather type info for all the refs embedded in a given Value.

I went all the way and made RefBase a Value instead of just adding the
Type() method because both types.Ref and the generated Ref types are
actually all Values, and doing so allowed me to change the definition of
refBuilderFunc in package_registry.go to be more precise. It now returns
RefBase instead of just Value.
This commit is contained in:
Chris Masone
2016-03-18 17:36:55 -07:00
parent a6e5de48dc
commit 82338bb5be
46 changed files with 148 additions and 155 deletions

View File

@@ -99,7 +99,7 @@ func (s Commit) Ref() ref.Ref {
return types.EnsureRef(s.ref, s)
}
func (s Commit) Chunks() (chunks []ref.Ref) {
func (s Commit) Chunks() (chunks []types.RefBase) {
chunks = append(chunks, __typeForCommit.Chunks()...)
chunks = append(chunks, s._value.Chunks()...)
chunks = append(chunks, s._parents.Chunks()...)
@@ -170,7 +170,7 @@ func (m MapOfStringToRefOfCommit) Ref() ref.Ref {
return types.EnsureRef(m.ref, m)
}
func (m MapOfStringToRefOfCommit) Chunks() (chunks []ref.Ref) {
func (m MapOfStringToRefOfCommit) Chunks() (chunks []types.RefBase) {
chunks = append(chunks, m.Type().Chunks()...)
chunks = append(chunks, m.m.Chunks()...)
return
@@ -305,7 +305,7 @@ func (s SetOfRefOfCommit) Ref() ref.Ref {
return types.EnsureRef(s.ref, s)
}
func (s SetOfRefOfCommit) Chunks() (chunks []ref.Ref) {
func (s SetOfRefOfCommit) Chunks() (chunks []types.RefBase) {
chunks = append(chunks, s.Type().Chunks()...)
chunks = append(chunks, s.s.Chunks()...)
return
@@ -433,9 +433,9 @@ func (r RefOfCommit) Equals(other types.Value) bool {
return other != nil && __typeForRefOfCommit.Equals(other.Type()) && r.Ref() == other.Ref()
}
func (r RefOfCommit) Chunks() (chunks []ref.Ref) {
func (r RefOfCommit) Chunks() (chunks []types.RefBase) {
chunks = append(chunks, r.Type().Chunks()...)
chunks = append(chunks, r.target)
chunks = append(chunks, r)
return
}
@@ -459,7 +459,7 @@ func init() {
types.RegisterRef(__typeForRefOfCommit, builderForRefOfCommit)
}
func builderForRefOfCommit(r ref.Ref) types.Value {
func builderForRefOfCommit(r ref.Ref) types.RefBase {
return NewRefOfCommit(r)
}

View File

@@ -41,7 +41,7 @@ func (e {{.Name}}) Ref() ref.Ref {
return {{$typesPackage}}EnsureRef(&throwaway, e)
}
func (e {{.Name}}) Chunks() []ref.Ref {
func (e {{.Name}}) Chunks() []{{$typesPackage}}RefBase {
return nil
}

View File

@@ -39,7 +39,7 @@ func (l {{.Name}}) Ref() ref.Ref {
return {{$typesPackage}}EnsureRef(l.ref, l)
}
func (l {{.Name}}) Chunks() (chunks []ref.Ref) {
func (l {{.Name}}) Chunks() (chunks []{{$typesPackage}}RefBase) {
chunks = append(chunks, l.Type().Chunks()...)
chunks = append(chunks, l.l.Chunks()...)
return

View File

@@ -40,7 +40,7 @@ func (m {{.Name}}) Ref() ref.Ref {
return {{$typesPackage}}EnsureRef(m.ref, m)
}
func (m {{.Name}}) Chunks() (chunks []ref.Ref) {
func (m {{.Name}}) Chunks() (chunks []{{$typesPackage}}RefBase) {
chunks = append(chunks, m.Type().Chunks()...)
chunks = append(chunks, m.m.Chunks()...)
return

View File

@@ -23,9 +23,9 @@ func (r {{.Name}}) Equals(other {{$typesPackage}}Value) bool {
return other != nil && __typeFor{{.Name}}.Equals(other.Type()) && r.Ref() == other.Ref()
}
func (r {{.Name}}) Chunks() (chunks []ref.Ref) {
func (r {{.Name}}) Chunks() (chunks []{{$typesPackage}}RefBase) {
chunks = append(chunks, r.Type().Chunks()...)
chunks = append(chunks, r.target)
chunks = append(chunks, r)
return
}
@@ -49,7 +49,7 @@ func init() {
{{$typesPackage}}RegisterRef(__typeFor{{.Name}}, builderFor{{.Name}})
}
func builderFor{{.Name}}(r ref.Ref) {{$typesPackage}}Value {
func builderFor{{.Name}}(r ref.Ref) {{$typesPackage}}RefBase {
return New{{.Name}}(r)
}

View File

@@ -42,7 +42,7 @@ func (s {{.Name}}) Ref() ref.Ref {
return {{$typesPackage}}EnsureRef(s.ref, s)
}
func (s {{.Name}}) Chunks() (chunks []ref.Ref) {
func (s {{.Name}}) Chunks() (chunks []{{$typesPackage}}RefBase) {
chunks = append(chunks, s.Type().Chunks()...)
chunks = append(chunks, s.s.Chunks()...)
return

View File

@@ -95,7 +95,7 @@ func (s {{.Name}}) Ref() ref.Ref {
return {{$typesPackage}}EnsureRef(s.ref, s)
}
func (s {{.Name}}) Chunks() (chunks []ref.Ref) {
func (s {{.Name}}) Chunks() (chunks []{{$typesPackage}}RefBase) {
chunks = append(chunks, __typeFor{{.Name}}.Chunks()...)
{{range .Fields}}{{if mayHaveChunks .T}}{{if .Optional}}if s.__optional{{.Name}} {
{{end}}chunks = append(chunks, s._{{.Name}}.Chunks()...)

View File

@@ -4,7 +4,6 @@ import (
"io"
"github.com/attic-labs/noms/d"
"github.com/attic-labs/noms/ref"
)
const (
@@ -45,7 +44,7 @@ func newBlobLeafChunkFn() makeChunkFn {
}
leaf := newBlobLeaf(buff)
return newMetaTuple(Uint64(uint64(len(buff))), leaf, ref.Ref{}), leaf
return newMetaTuple(Uint64(uint64(len(buff))), leaf, Ref{}), leaf
}
}

View File

@@ -32,7 +32,7 @@ func (bl blobLeaf) Ref() ref.Ref {
return EnsureRef(bl.ref, bl)
}
func (bl blobLeaf) Chunks() []ref.Ref {
func (bl blobLeaf) Chunks() []RefBase {
return nil
}

View File

@@ -27,9 +27,9 @@ func (r RefOfBlob) Equals(other Value) bool {
return other != nil && __typeForRefOfBlob.Equals(other.Type()) && r.Ref() == other.Ref()
}
func (r RefOfBlob) Chunks() (chunks []ref.Ref) {
func (r RefOfBlob) Chunks() (chunks []RefBase) {
chunks = append(chunks, r.Type().Chunks()...)
chunks = append(chunks, r.target)
chunks = append(chunks, r)
return
}
@@ -40,7 +40,7 @@ func (r RefOfBlob) ChildValues() []Value {
// A Noms Value that describes RefOfBlob.
var __typeForRefOfBlob Type
func (m RefOfBlob) Type() Type {
func (r RefOfBlob) Type() Type {
return __typeForRefOfBlob
}
@@ -49,7 +49,7 @@ func init() {
RegisterRef(__typeForRefOfBlob, builderForRefOfBlob)
}
func builderForRefOfBlob(r ref.Ref) Value {
func builderForRefOfBlob(r ref.Ref) RefBase {
return NewRefOfBlob(r)
}

View File

@@ -9,7 +9,6 @@ import (
"strings"
"testing"
"github.com/attic-labs/noms/ref"
"github.com/stretchr/testify/assert"
)
@@ -17,7 +16,7 @@ func getTestCompoundBlob(datas ...string) compoundBlob {
tuples := make([]metaTuple, len(datas))
for i, s := range datas {
b := NewBlob(bytes.NewBufferString(s))
tuples[i] = newMetaTuple(Uint64(len(s)), b, ref.Ref{})
tuples[i] = newMetaTuple(Uint64(len(s)), b, Ref{})
}
return newCompoundBlob(tuples, nil)
}
@@ -187,8 +186,8 @@ func TestCompoundBlobChunks(t *testing.T) {
bl1 := newBlobLeaf([]byte("hello"))
bl2 := newBlobLeaf([]byte("world"))
cb = newCompoundBlob([]metaTuple{
newMetaTuple(Uint64(uint64(5)), bl1, ref.Ref{}),
newMetaTuple(Uint64(uint64(10)), bl2, ref.Ref{}),
newMetaTuple(Uint64(uint64(5)), bl1, Ref{}),
newMetaTuple(Uint64(uint64(10)), bl2, Ref{}),
}, vs)
assert.Equal(2, len(cb.Chunks()))
}
@@ -265,7 +264,7 @@ func printBlob(b Blob, indent int) {
fmt.Printf("%scompoundBlob, len: %d, chunks: %d\n", indentString, b.Len(), len(b.tuples))
indent++
for _, t := range b.tuples {
printBlob(b.vr.ReadValue(t.ChildRef()).(Blob), indent)
printBlob(b.vr.ReadValue(t.ChildRef().TargetRef()).(Blob), indent)
}
}
}

View File

@@ -66,7 +66,7 @@ func (cl compoundList) cursorAt(idx uint64) (*sequenceCursor, listLeaf, uint64)
return idx < offset, offset
}, uint64(0))
if current := cursor.current().(metaTuple); current.ChildRef() != valueFromType(leaf, leaf.Type()).Ref() {
if current := cursor.current().(metaTuple); current.ChildRef().TargetRef() != valueFromType(leaf, leaf.Type()).Ref() {
leaf = readMetaTupleValue(current, cl.vr)
}
@@ -265,8 +265,9 @@ func makeListLeafChunkFn(t Type, sink ValueWriter) makeChunkFn {
list := valueFromType(newListLeaf(t, values...), t)
if sink != nil {
return newMetaTuple(Uint64(len(values)), nil, sink.WriteValue(list)), list
r := newRef(sink.WriteValue(list), MakeRefType(list.Type()))
return newMetaTuple(Uint64(len(values)), nil, r), list
}
return newMetaTuple(Uint64(len(values)), list, ref.Ref{}), list
return newMetaTuple(Uint64(len(values)), list, Ref{}), list
}
}

View File

@@ -177,7 +177,7 @@ func (r *jsonArrayReader) maybeReadMetaSequence(t Type, pkg *Package) (Value, bo
for !r2.atEnd() {
ref := r2.readRef()
v := r2.readValueWithoutTag(indexType, pkg)
data = append(data, newMetaTuple(v, nil, ref))
data = append(data, newMetaTuple(v, nil, refFromType(ref, MakeRefType(v.Type()))))
}
t = fixupType(t, pkg)

View File

@@ -132,8 +132,8 @@ func TestReadCompoundList(t *testing.T) {
leaf1 := newListLeaf(tr, Int32(0))
leaf2 := newListLeaf(tr, Int32(1), Int32(2), Int32(3))
l2 := buildCompoundList([]metaTuple{
newMetaTuple(Uint64(1), leaf1, ref.Ref{}),
newMetaTuple(Uint64(4), leaf2, ref.Ref{}),
newMetaTuple(Uint64(1), leaf1, Ref{}),
newMetaTuple(Uint64(4), leaf2, Ref{}),
}, tr, cs)
a := parseJson(`[%d, %d, true, ["%s", "1", "%s", "4"]]`, ListKind, Int32Kind, leaf1.Ref(), leaf2.Ref())
@@ -213,9 +213,9 @@ func TestReadCompoundBlob(t *testing.T) {
_, ok := m.(compoundBlob)
assert.True(ok)
m2 := newCompoundBlob([]metaTuple{
newMetaTuple(Uint64(20), nil, r1),
newMetaTuple(Uint64(40), nil, r2),
newMetaTuple(Uint64(60), nil, r3),
newMetaTuple(Uint64(20), nil, newRef(r1, MakeRefType(typeForBlob))),
newMetaTuple(Uint64(40), nil, newRef(r2, MakeRefType(typeForBlob))),
newMetaTuple(Uint64(60), nil, newRef(r3, MakeRefType(typeForBlob))),
}, cs)
assert.True(m.Type().Equals(m2.Type()))

View File

@@ -106,7 +106,7 @@ func (w *jsonArrayWriter) maybeWriteMetaSequence(v Value, tr Type, pkg *Package)
// Write unwritten chunked sequences. Chunks are lazily written so that intermediate chunked structures like NewList().Append(x).Append(y) don't cause unnecessary churn.
w.vw.WriteValue(tuple.child)
}
w2.writeRef(tuple.ChildRef())
w2.writeRef(tuple.ChildRef().TargetRef())
w2.writeValue(tuple.value, indexType, pkg)
}
w.write(w2.toArray())

View File

@@ -131,9 +131,9 @@ func TestWriteCompoundBlob(t *testing.T) {
r3 := ref.Parse("sha1-0000000000000000000000000000000000000003")
v := newCompoundBlob([]metaTuple{
newMetaTuple(Uint64(20), nil, r1),
newMetaTuple(Uint64(40), nil, r2),
newMetaTuple(Uint64(60), nil, r3),
newMetaTuple(Uint64(20), nil, newRef(r1, MakeRefType(typeForBlob))),
newMetaTuple(Uint64(40), nil, newRef(r2, MakeRefType(typeForBlob))),
newMetaTuple(Uint64(60), nil, newRef(r3, MakeRefType(typeForBlob))),
}, NewTestValueStore())
w := newJsonArrayWriter(NewTestValueStore())
w.writeTopLevelValue(v)
@@ -314,8 +314,8 @@ func TestWriteCompoundList(t *testing.T) {
leaf1 := newListLeaf(ltr, Int32(0))
leaf2 := newListLeaf(ltr, Int32(1), Int32(2), Int32(3))
cl := buildCompoundList([]metaTuple{
newMetaTuple(Uint64(1), leaf1, ref.Ref{}),
newMetaTuple(Uint64(4), leaf2, ref.Ref{}),
newMetaTuple(Uint64(1), leaf1, Ref{}),
newMetaTuple(Uint64(4), leaf2, Ref{}),
}, ltr, NewTestValueStore())
w := newJsonArrayWriter(NewTestValueStore())

View File

@@ -20,7 +20,7 @@ func (e Enum) Ref() ref.Ref {
return EnsureRef(&throwaway, e)
}
func (e Enum) Chunks() []ref.Ref {
func (e Enum) Chunks() []RefBase {
return nil
}

View File

@@ -4,7 +4,6 @@ import (
"bytes"
"testing"
"github.com/attic-labs/noms/ref"
"github.com/stretchr/testify/assert"
)
@@ -60,8 +59,8 @@ func TestValueEquals(t *testing.T) {
b1 := NewBlob(bytes.NewBufferString("hi"))
b2 := NewBlob(bytes.NewBufferString("bye"))
return newCompoundBlob([]metaTuple{
newMetaTuple(Uint64(uint64(2)), b1, ref.Ref{}),
newMetaTuple(Uint64(uint64(5)), b2, ref.Ref{}),
newMetaTuple(Uint64(uint64(2)), b1, Ref{}),
newMetaTuple(Uint64(uint64(5)), b2, Ref{}),
}, nil)
},
func() Value { return NewList() },

View File

@@ -8,7 +8,7 @@ func (v {{.NomsType}}) Ref() ref.Ref {
return getRef(v)
}
func (v {{.NomsType}}) Chunks() []ref.Ref {
func (v {{.NomsType}}) Chunks() []RefBase {
return nil
}
@@ -25,7 +25,6 @@ var typeFor{{.NomsType}} = MakePrimitiveType({{.NomsType}}Kind)
func (v {{.NomsType}}) Type() Type {
return typeFor{{.NomsType}}
}
{{if .IsOrdered}}
func (v {{.NomsType}}) Less(other OrderedValue) bool {
return v < other.({{.NomsType}})

View File

@@ -43,16 +43,16 @@ func TestEnsureRef(t *testing.T) {
}()
bl := newBlobLeaf([]byte("hi"))
cb := newCompoundBlob([]metaTuple{{bl, ref.Ref{}, Uint64(2)}}, vs)
cb := newCompoundBlob([]metaTuple{{bl, Ref{}, Uint64(2)}}, vs)
ll := newListLeaf(listType, NewString("foo"))
cl := buildCompoundList([]metaTuple{{ll, ref.Ref{}, Uint64(1)}}, listType, vs)
cl := buildCompoundList([]metaTuple{{ll, Ref{}, Uint64(1)}}, listType, vs)
ml := newMapLeaf(mapType, mapEntry{NewString("foo"), NewString("bar")})
cm := buildCompoundMap([]metaTuple{{ml, ref.Ref{}, NewString("foo")}}, mapType, vs)
cm := buildCompoundMap([]metaTuple{{ml, Ref{}, NewString("foo")}}, mapType, vs)
sl := newSetLeaf(setType, NewString("foo"))
cps := buildCompoundSet([]metaTuple{{sl, ref.Ref{}, NewString("foo")}}, setType, vs)
cps := buildCompoundSet([]metaTuple{{sl, Ref{}, NewString("foo")}}, setType, vs)
count = byte(1)
values := []Value{

View File

@@ -1,14 +1,10 @@
package types
import (
"crypto/sha1"
"github.com/attic-labs/noms/ref"
)
import "crypto/sha1"
func newIndexedMetaSequenceBoundaryChecker() boundaryChecker {
return newBuzHashBoundaryChecker(objectWindowSize, sha1.Size, objectPattern, func(item sequenceItem) []byte {
digest := item.(metaTuple).ChildRef().Digest()
digest := item.(metaTuple).ChildRef().TargetRef().Digest()
return digest[:]
})
}
@@ -25,8 +21,9 @@ func newIndexedMetaSequenceChunkFn(t Type, source ValueReader, sink ValueWriter)
meta := newMetaSequenceFromData(tuples, t, source)
if sink != nil {
return metaTuple{nil, sink.WriteValue(meta), Uint64(tuples.uint64ValuesSum())}, meta
r := newRef(sink.WriteValue(meta), MakeRefType(meta.Type()))
return newMetaTuple(Uint64(tuples.uint64ValuesSum()), nil, r), meta
}
return metaTuple{meta, ref.Ref{}, Uint64(tuples.uint64ValuesSum())}, meta
return newMetaTuple(Uint64(tuples.uint64ValuesSum()), meta, Ref{}), meta
}
}

View File

@@ -172,7 +172,7 @@ func (l listLeaf) Equals(other Value) bool {
return false
}
func (l listLeaf) Chunks() (chunks []ref.Ref) {
func (l listLeaf) Chunks() (chunks []RefBase) {
for _, v := range l.values {
chunks = append(chunks, v.Chunks()...)
}

View File

@@ -373,12 +373,13 @@ func TestListChunks(t *testing.T) {
c1 := l1.Chunks()
assert.Len(c1, 0)
l2 := NewList(NewRef(Int32(0).Ref()))
ool := NewRef(Int32(0).Ref())
l2 := NewList(ool)
c2 := l2.Chunks()
assert.Len(c2, 1)
l3 := NewList(l2)
c3 := l3.Chunks()
assert.Len(c3, 1)
assert.Equal(Int32(0).Ref(), c3[0])
assert.Equal(ool, c3[0])
}

View File

@@ -31,10 +31,9 @@ func newMapLeaf(t Type, data ...mapEntry) Map {
func (m mapLeaf) First() (Value, Value) {
if len(m.data) == 0 {
return nil, nil
} else {
entry := m.data[0]
return entry.key, entry.value
}
entry := m.data[0]
return entry.key, entry.value
}
func (m mapLeaf) Len() uint64 {
@@ -148,7 +147,7 @@ func (m mapLeaf) Equals(other Value) bool {
return other != nil && m.t.Equals(other.Type()) && m.Ref() == other.Ref()
}
func (m mapLeaf) Chunks() (chunks []ref.Ref) {
func (m mapLeaf) Chunks() (chunks []RefBase) {
for _, entry := range m.data {
chunks = append(chunks, entry.key.Chunks()...)
chunks = append(chunks, entry.value.Chunks()...)
@@ -249,10 +248,10 @@ func makeMapLeafChunkFn(t Type, vr ValueReader) makeChunkFn {
if isSequenceOrderedByIndexedType(t) {
indexValue = lastValue.key
} else {
indexValue = NewRef(lastValue.key.Ref())
indexValue = refFromType(lastValue.key.Ref(), MakeRefType(lastValue.key.Type()))
}
}
return newMetaTuple(indexValue, mapLeaf, ref.Ref{}), mapLeaf
return newMetaTuple(indexValue, mapLeaf, Ref{}), mapLeaf
}
}

View File

@@ -1,9 +1,6 @@
package types
import (
"github.com/attic-labs/noms/d"
"github.com/attic-labs/noms/ref"
)
import "github.com/attic-labs/noms/d"
const (
objectWindowSize = 8
@@ -20,25 +17,24 @@ type metaSequence interface {
tupleCount() int
}
func newMetaTuple(value, child Value, childRef ref.Ref) metaTuple {
d.Chk.True((child != nil) != (childRef != ref.Ref{}), "Either child or childRef can be set, but not both")
func newMetaTuple(value, child Value, childRef RefBase) metaTuple {
d.Chk.True((child != nil) != (childRef != Ref{}), "Either child or childRef can be set, but not both")
return metaTuple{child, childRef, value}
}
// metaTuple is a node in a "probably" tree, consisting of data in the node (either tree leaves or other metaSequences), and a Value annotation for exploring the tree (e.g. the largest item if this an ordered sequence).
type metaTuple struct {
child Value // nil if the child data hasn't been read, or has already been written
childRef ref.Ref // may be empty if |child| is non-nil; call ChildRef() instead of accessing |childRef| directly
childRef RefBase // may be empty if |child| is non-nil; call ChildRef() instead of accessing |childRef| directly
value Value
}
func (mt metaTuple) ChildRef() ref.Ref {
func (mt metaTuple) ChildRef() RefBase {
if mt.child != nil {
return mt.child.Ref()
} else {
d.Chk.False(mt.childRef.IsEmpty())
return mt.childRef
return newRef(mt.child.Ref(), MakeRefType(mt.child.Type()))
}
d.Chk.False(mt.childRef.TargetRef().IsEmpty())
return mt.childRef
}
func (mt metaTuple) uint64Value() uint64 {
@@ -84,12 +80,12 @@ func (ms metaSequenceObject) ChildValues() []Value {
refOfLeafType := MakeCompoundType(RefKind, leafType)
res := make([]Value, len(ms.tuples))
for i, t := range ms.tuples {
res[i] = refFromType(t.ChildRef(), refOfLeafType)
res[i] = refFromType(t.ChildRef().TargetRef(), refOfLeafType)
}
return res
}
func (ms metaSequenceObject) Chunks() (chunks []ref.Ref) {
func (ms metaSequenceObject) Chunks() (chunks []RefBase) {
for _, tuple := range ms.tuples {
chunks = append(chunks, tuple.ChildRef())
}
@@ -102,9 +98,7 @@ func (ms metaSequenceObject) Type() Type {
type metaBuilderFunc func(tuples metaSequenceData, t Type, vr ValueReader) Value
var (
metaFuncMap map[NomsKind]metaBuilderFunc = map[NomsKind]metaBuilderFunc{}
)
var metaFuncMap = map[NomsKind]metaBuilderFunc{}
func registerMetaValue(k NomsKind, bf metaBuilderFunc) {
metaFuncMap[k] = bf
@@ -146,8 +140,8 @@ func newMetaSequenceCursor(root metaSequence, vr ValueReader) (*sequenceCursor,
func readMetaTupleValue(item sequenceItem, vr ValueReader) Value {
mt := item.(metaTuple)
if mt.child == nil {
d.Chk.False(mt.childRef.IsEmpty())
mt.child = vr.ReadValue(mt.childRef)
d.Chk.False(mt.childRef.TargetRef().IsEmpty())
mt.child = vr.ReadValue(mt.childRef.TargetRef())
d.Chk.NotNil(mt.child)
}
return internalValueFromType(mt.child, mt.child.Type())

View File

@@ -13,38 +13,39 @@ func TestMeta(t *testing.T) {
vs := NewTestValueStore()
flatList := []Value{Uint32(0), Uint32(1), Uint32(2), Uint32(3), Uint32(4), Uint32(5), Uint32(6), Uint32(7)}
typeForRefOfListOfValue := MakeRefType(MakeCompoundType(ListKind, MakePrimitiveType(ValueKind)))
l0 := NewList(flatList[0])
lr0 := vs.WriteValue(l0)
lr0 := newRef(vs.WriteValue(l0), typeForRefOfListOfValue)
l1 := NewList(flatList[1])
lr1 := vs.WriteValue(l1)
lr1 := newRef(vs.WriteValue(l1), typeForRefOfListOfValue)
l2 := NewList(flatList[2])
lr2 := vs.WriteValue(l2)
lr2 := newRef(vs.WriteValue(l2), typeForRefOfListOfValue)
l3 := NewList(flatList[3])
lr3 := vs.WriteValue(l3)
lr3 := newRef(vs.WriteValue(l3), typeForRefOfListOfValue)
l4 := NewList(flatList[4])
lr4 := vs.WriteValue(l4)
lr4 := newRef(vs.WriteValue(l4), typeForRefOfListOfValue)
l5 := NewList(flatList[5])
lr5 := vs.WriteValue(l5)
lr5 := newRef(vs.WriteValue(l5), typeForRefOfListOfValue)
l6 := NewList(flatList[6])
lr6 := vs.WriteValue(l6)
lr6 := newRef(vs.WriteValue(l6), typeForRefOfListOfValue)
l7 := NewList(flatList[7])
lr7 := vs.WriteValue(l7)
lr7 := newRef(vs.WriteValue(l7), typeForRefOfListOfValue)
mtr := l0.Type()
m0 := compoundList{metaSequenceObject{metaSequenceData{{l0, lr0, Uint64(1)}, {l1, lr1, Uint64(2)}}, mtr}, 0, &ref.Ref{}, vs}
lm0 := vs.WriteValue(m0)
lm0 := newRef(vs.WriteValue(m0), typeForRefOfListOfValue)
m1 := compoundList{metaSequenceObject{metaSequenceData{{l2, lr2, Uint64(1)}, {l3, lr3, Uint64(2)}}, mtr}, 0, &ref.Ref{}, vs}
lm1 := vs.WriteValue(m1)
lm1 := newRef(vs.WriteValue(m1), typeForRefOfListOfValue)
m2 := compoundList{metaSequenceObject{metaSequenceData{{l4, lr4, Uint64(1)}, {l5, lr5, Uint64(2)}}, mtr}, 0, &ref.Ref{}, vs}
lm2 := vs.WriteValue(m2)
lm2 := newRef(vs.WriteValue(m2), typeForRefOfListOfValue)
m3 := compoundList{metaSequenceObject{metaSequenceData{{l6, lr6, Uint64(1)}, {l7, lr7, Uint64(2)}}, mtr}, 0, &ref.Ref{}, vs}
lm3 := vs.WriteValue(m3)
lm3 := newRef(vs.WriteValue(m3), typeForRefOfListOfValue)
m00 := compoundList{metaSequenceObject{metaSequenceData{{m0, lm0, Uint64(2)}, {m1, lm1, Uint64(4)}}, mtr}, 0, &ref.Ref{}, vs}
lm00 := vs.WriteValue(m00)
lm00 := newRef(vs.WriteValue(m00), typeForRefOfListOfValue)
m01 := compoundList{metaSequenceObject{metaSequenceData{{m2, lm2, Uint64(2)}, {m3, lm3, Uint64(4)}}, mtr}, 0, &ref.Ref{}, vs}
lm01 := vs.WriteValue(m01)
lm01 := newRef(vs.WriteValue(m01), typeForRefOfListOfValue)
rootList := compoundList{metaSequenceObject{metaSequenceData{{m00, lm00, Uint64(4)}, {m01, lm01, Uint64(8)}}, mtr}, 0, &ref.Ref{}, vs}
rootRef := vs.WriteValue(rootList)

View File

@@ -3,8 +3,6 @@ package types
import (
"crypto/sha1"
"sort"
"github.com/attic-labs/noms/ref"
)
func isSequenceOrderedByIndexedType(t Type) bool {
@@ -30,7 +28,7 @@ func findLeafInOrderedSequence(ms metaSequence, t Type, key Value, getValues get
})
}
if current := cursor.current().(metaTuple); current.ChildRef() != valueFromType(leaf, leaf.Type()).Ref() {
if current := cursor.current().(metaTuple); current.ChildRef().TargetRef() != valueFromType(leaf, leaf.Type()).Ref() {
leaf = readMetaTupleValue(current, vr)
}
@@ -51,7 +49,7 @@ func findLeafInOrderedSequence(ms metaSequence, t Type, key Value, getValues get
func newOrderedMetaSequenceBoundaryChecker() boundaryChecker {
return newBuzHashBoundaryChecker(orderedSequenceWindowSize, sha1.Size, objectPattern, func(item sequenceItem) []byte {
digest := item.(metaTuple).ChildRef().Digest()
digest := item.(metaTuple).ChildRef().TargetRef().Digest()
return digest[:]
})
}
@@ -65,6 +63,6 @@ func newOrderedMetaSequenceChunkFn(t Type, vr ValueReader) makeChunkFn {
}
meta := newMetaSequenceFromData(tuples, t, vr)
return newMetaTuple(tuples.last().value, meta, ref.Ref{}), meta
return newMetaTuple(tuples.last().value, meta, Ref{}), meta
}
}

View File

@@ -29,12 +29,12 @@ func (p Package) Ref() ref.Ref {
return EnsureRef(p.ref, p)
}
func (p Package) Chunks() (chunks []ref.Ref) {
func (p Package) Chunks() (chunks []RefBase) {
for _, t := range p.types {
chunks = append(chunks, t.Chunks()...)
}
for _, d := range p.dependencies {
chunks = append(chunks, d)
chunks = append(chunks, refFromType(d, MakeRefType(typeForPackage)))
}
return
}

View File

@@ -7,7 +7,7 @@ import (
type enumBuilderFunc func(v uint32) Value
type enumReaderFunc func(v Value) uint32
type refBuilderFunc func(target ref.Ref) Value
type refBuilderFunc func(target ref.Ref) RefBase
type structBuilderFunc func(values []Value) Value
type structReaderFunc func(v Value) []Value
type valueBuilderFunc func(v Value) Value
@@ -127,7 +127,7 @@ func RegisterRef(t Type, bf refBuilderFunc) {
refFuncMap[t.Ref()] = bf
}
func refFromType(target ref.Ref, t Type) Value {
func refFromType(target ref.Ref, t Type) RefBase {
if f, ok := refFuncMap[t.Ref()]; ok {
return f(target)
}

View File

@@ -45,7 +45,7 @@ func (s SetOfRefOfPackage) Ref() ref.Ref {
return EnsureRef(s.ref, s)
}
func (s SetOfRefOfPackage) Chunks() (chunks []ref.Ref) {
func (s SetOfRefOfPackage) Chunks() (chunks []RefBase) {
chunks = append(chunks, s.Type().Chunks()...)
chunks = append(chunks, s.s.Chunks()...)
return
@@ -172,9 +172,9 @@ func (r RefOfPackage) Equals(other Value) bool {
return other != nil && __typeForRefOfPackage.Equals(other.Type()) && r.Ref() == other.Ref()
}
func (r RefOfPackage) Chunks() (chunks []ref.Ref) {
func (r RefOfPackage) Chunks() (chunks []RefBase) {
chunks = append(chunks, r.Type().Chunks()...)
chunks = append(chunks, r.target)
chunks = append(chunks, r)
return
}
@@ -198,7 +198,7 @@ func init() {
RegisterRef(__typeForRefOfPackage, builderForRefOfPackage)
}
func builderForRefOfPackage(r ref.Ref) Value {
func builderForRefOfPackage(r ref.Ref) RefBase {
return NewRefOfPackage(r)
}

View File

@@ -17,7 +17,7 @@ func (v Bool) Ref() ref.Ref {
return getRef(v)
}
func (v Bool) Chunks() []ref.Ref {
func (v Bool) Chunks() []RefBase {
return nil
}
@@ -45,7 +45,7 @@ func (v Float32) Ref() ref.Ref {
return getRef(v)
}
func (v Float32) Chunks() []ref.Ref {
func (v Float32) Chunks() []RefBase {
return nil
}
@@ -77,7 +77,7 @@ func (v Float64) Ref() ref.Ref {
return getRef(v)
}
func (v Float64) Chunks() []ref.Ref {
func (v Float64) Chunks() []RefBase {
return nil
}
@@ -109,7 +109,7 @@ func (v Int16) Ref() ref.Ref {
return getRef(v)
}
func (v Int16) Chunks() []ref.Ref {
func (v Int16) Chunks() []RefBase {
return nil
}
@@ -141,7 +141,7 @@ func (v Int32) Ref() ref.Ref {
return getRef(v)
}
func (v Int32) Chunks() []ref.Ref {
func (v Int32) Chunks() []RefBase {
return nil
}
@@ -173,7 +173,7 @@ func (v Int64) Ref() ref.Ref {
return getRef(v)
}
func (v Int64) Chunks() []ref.Ref {
func (v Int64) Chunks() []RefBase {
return nil
}
@@ -205,7 +205,7 @@ func (v Int8) Ref() ref.Ref {
return getRef(v)
}
func (v Int8) Chunks() []ref.Ref {
func (v Int8) Chunks() []RefBase {
return nil
}
@@ -237,7 +237,7 @@ func (v Uint16) Ref() ref.Ref {
return getRef(v)
}
func (v Uint16) Chunks() []ref.Ref {
func (v Uint16) Chunks() []RefBase {
return nil
}
@@ -269,7 +269,7 @@ func (v Uint32) Ref() ref.Ref {
return getRef(v)
}
func (v Uint32) Chunks() []ref.Ref {
func (v Uint32) Chunks() []RefBase {
return nil
}
@@ -301,7 +301,7 @@ func (v Uint64) Ref() ref.Ref {
return getRef(v)
}
func (v Uint64) Chunks() []ref.Ref {
func (v Uint64) Chunks() []RefBase {
return nil
}
@@ -333,7 +333,7 @@ func (v Uint8) Ref() ref.Ref {
return getRef(v)
}
func (v Uint8) Chunks() []ref.Ref {
func (v Uint8) Chunks() []RefBase {
return nil
}
@@ -354,3 +354,4 @@ func (v Uint8) Type() Type {
func (v Uint8) Less(other OrderedValue) bool {
return v < other.(Uint8)
}

View File

@@ -9,6 +9,7 @@ type Ref struct {
}
type RefBase interface {
Value
TargetRef() ref.Ref
}
@@ -28,8 +29,8 @@ func (r Ref) Ref() ref.Ref {
return EnsureRef(r.ref, r)
}
func (r Ref) Chunks() []ref.Ref {
return []ref.Ref{r.target}
func (r Ref) Chunks() (chunks []RefBase) {
return append(chunks, r)
}
func (r Ref) ChildValues() []Value {

View File

@@ -69,5 +69,5 @@ func TestRefChunks(t *testing.T) {
l := NewList()
r := NewRef(l.Ref())
assert.Len(r.Chunks(), 1)
assert.Equal(l.Ref(), r.Chunks()[0])
assert.Equal(r, r.Chunks()[0])
}

View File

@@ -33,9 +33,8 @@ func (cur *sequenceCursor) maybeCurrent() (sequenceItem, bool) {
d.Chk.True(cur.idx >= -1 && cur.idx <= cur.length)
if cur.idx == -1 || cur.idx == cur.length {
return nil, false
} else {
return cur.getItem(cur.item, cur.idx), true
}
return cur.getItem(cur.item, cur.idx), true
}
func (cur *sequenceCursor) indexInChunk() int {

View File

@@ -79,7 +79,7 @@ func setUnion(set Set, others []Set) Set {
}
smallest := func(cursors map[*sequenceCursor]bool) (smallestCursor *sequenceCursor, smallestItem sequenceItem) {
for cursor, _ := range cursors {
for cursor := range cursors {
currentItem := cursor.current()
if smallestCursor == nil || lessFunction(currentItem, smallestItem) {
smallestCursor = cursor

View File

@@ -120,7 +120,7 @@ func (s setLeaf) Equals(other Value) bool {
return other != nil && s.t.Equals(other.Type()) && s.Ref() == other.Ref()
}
func (s setLeaf) Chunks() (chunks []ref.Ref) {
func (s setLeaf) Chunks() (chunks []RefBase) {
for _, v := range s.data {
chunks = append(chunks, v.Chunks()...)
}
@@ -216,7 +216,7 @@ func makeSetLeafChunkFn(t Type, vr ValueReader) makeChunkFn {
}
}
return newMetaTuple(indexValue, setLeaf, ref.Ref{}), setLeaf
return newMetaTuple(indexValue, setLeaf, Ref{}), setLeaf
}
}

View File

@@ -209,7 +209,7 @@ func testSetOrder(assert *assert.Assertions, valueType Type, value []Value, expe
i := 0
m.IterAll(func(value Value) {
assert.Equal(expectOrdering[i].Ref().String(), value.Ref().String())
i += 1
i++
})
}

View File

@@ -30,7 +30,7 @@ func (s String) Less(other OrderedValue) bool {
return s.s < other.(String).s
}
func (fs String) Chunks() []ref.Ref {
func (fs String) Chunks() []RefBase {
return nil
}

View File

@@ -56,7 +56,7 @@ func (s Struct) Ref() ref.Ref {
return EnsureRef(s.ref, s)
}
func (s Struct) Chunks() (chunks []ref.Ref) {
func (s Struct) Chunks() (chunks []RefBase) {
chunks = append(chunks, s.t.Chunks()...)
for _, f := range s.desc().Fields {
if v, ok := s.data[f.Name]; ok {

View File

@@ -43,8 +43,8 @@ func TestGenericStructChunks(t *testing.T) {
s1 := newStructFromData(data1, 0, nil, typ, typeDef)
assert.Len(s1.Chunks(), 2)
assert.Equal(pkgRef, s1.Chunks()[0])
assert.Equal(b.Ref(), s1.Chunks()[1])
assert.Equal(pkgRef, s1.Chunks()[0].TargetRef())
assert.Equal(b.Ref(), s1.Chunks()[1].TargetRef())
}
func TestGenericStructChunksOptional(t *testing.T) {
@@ -63,14 +63,14 @@ func TestGenericStructChunksOptional(t *testing.T) {
s1 := newStructFromData(data1, 0, nil, typ, typeDef)
assert.Len(s1.Chunks(), 1)
assert.Equal(pkgRef, s1.Chunks()[0])
assert.Equal(pkgRef, s1.Chunks()[0].TargetRef())
data2 := structData{"r": NewRef(b.Ref())}
s2 := newStructFromData(data2, 0, nil, typ, typeDef)
assert.Len(s2.Chunks(), 2)
assert.Equal(pkgRef, s2.Chunks()[0])
assert.Equal(b.Ref(), s2.Chunks()[1])
assert.Equal(pkgRef, s2.Chunks()[0].TargetRef())
assert.Equal(b.Ref(), s2.Chunks()[1].TargetRef())
}
func TestGenericStructChunksUnion(t *testing.T) {
@@ -89,13 +89,13 @@ func TestGenericStructChunksUnion(t *testing.T) {
s1 := NewStruct(typ, typeDef, structData{"s": NewString("hi")})
assert.Len(s1.Chunks(), 1)
assert.Equal(pkgRef, s1.Chunks()[0])
assert.Equal(pkgRef, s1.Chunks()[0].TargetRef())
s2 := NewStruct(typ, typeDef, structData{"r": NewRef(b.Ref())})
assert.Len(s2.Chunks(), 2)
assert.Equal(pkgRef, s2.Chunks()[0])
assert.Equal(b.Ref(), s2.Chunks()[1])
assert.Equal(pkgRef, s2.Chunks()[0].TargetRef())
assert.Equal(b.Ref(), s2.Chunks()[1].TargetRef())
}
func TestGenericStructNew(t *testing.T) {

View File

@@ -108,10 +108,10 @@ func (t Type) Equals(other Value) (res bool) {
return other != nil && t.Ref() == other.Ref()
}
func (t Type) Chunks() (chunks []ref.Ref) {
func (t Type) Chunks() (chunks []RefBase) {
if t.IsUnresolved() {
if t.HasPackageRef() {
chunks = append(chunks, t.PackageRef())
chunks = append(chunks, refFromType(t.PackageRef(), MakeRefType(typeForPackage)))
}
return
}
@@ -165,6 +165,10 @@ func MakePrimitiveTypeByString(p string) Type {
return buildType("", primitiveToDesc(p))
}
func MakeRefType(elemType Type) Type {
return MakeCompoundType(RefKind, elemType)
}
func MakeCompoundType(kind NomsKind, elemTypes ...Type) Type {
if len(elemTypes) == 1 {
d.Chk.NotEqual(MapKind, kind, "MapKind requires 2 element types.")

View File

@@ -51,7 +51,7 @@ func TestTypeWithPkgRef(t *testing.T) {
unresolvedRef := vs.WriteValue(unresolvedType)
v := vs.ReadValue(unresolvedRef)
assert.EqualValues(pkgRef, v.Chunks()[0])
assert.EqualValues(pkgRef, v.Chunks()[0].TargetRef())
assert.NotNil(vs.ReadValue(pkgRef))
}

View File

@@ -10,7 +10,7 @@ type Value interface {
Ref() ref.Ref
// Returns the immediate children of this value in the DAG, if any, not including Type().
ChildValues() []Value
Chunks() []ref.Ref
Chunks() []RefBase
Type() Type
}

View File

@@ -5,19 +5,20 @@ import (
"github.com/attic-labs/noms/ref"
)
// ValueStore is currently used only for tests in this pacakge.
// ValueStore is currently used only for tests in this package.
type ValueStore struct {
cs chunks.ChunkStore
}
func newValueStore(cs chunks.ChunkStore) *ValueStore {
return &ValueStore{cs}
}
// NewTestValueStore creates a simple struct that satisfies ValueReadWriter and is backed by a chunks.TestStore.
func NewTestValueStore() *ValueStore {
return &ValueStore{chunks.NewTestStore()}
}
func newValueStore(cs chunks.ChunkStore) *ValueStore {
return &ValueStore{cs}
}
// ReadValue reads and decodes a value from vrw. It is not considered an error for the requested chunk to be empty; in this case, the function simply returns nil.
func (vrw *ValueStore) ReadValue(r ref.Ref) Value {
return DecodeChunk(vrw.cs.Get(r), vrw)

View File

@@ -14,7 +14,7 @@ type primitive interface {
ToPrimitive() interface{}
}
// WriteValue takes a Value and encodes it to a Chunk, if |vw| is non-nill, it will vw.WriteValue reachable unwritten sub-chunks.
// EncodeValue takes a Value and encodes it to a Chunk, if |vw| is non-nill, it will vw.WriteValue reachable unwritten sub-chunks.
func EncodeValue(v Value, vw ValueWriter) chunks.Chunk {
e := toEncodeable(v, vw)
w := chunks.NewChunkWriter()

View File

@@ -121,7 +121,7 @@ func doChunkWalkP(r ref.Ref, vr types.ValueReader, callback SomeChunksCallback,
v := vr.ReadValue(r)
for _, r1 := range v.Chunks() {
wg.Add(1)
rq.tail() <- r1
rq.tail() <- r1.TargetRef()
}
}