Make Chunks return all reachable Refs from the current Value

We now do a recursive call which bottoms out with a ref.Ref for RefKind
Values. This means that we traverse into nested structures consistently.

The effect of this is that we get all the refs that the current chunk
references.
This commit is contained in:
Erik Arvidsson
2015-11-03 14:01:46 -05:00
parent b68b3c8c3c
commit eeaac87d5f
22 changed files with 131 additions and 181 deletions

View File

@@ -399,8 +399,10 @@ func (r RefOfIncident) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfIncident.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfIncident) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfIncident) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfIncidentFromVal(val types.Value) RefOfIncident {

View File

@@ -436,8 +436,10 @@ func (r RefOfValue) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfValue.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfValue) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfValue) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfValueFromVal(val types.Value) RefOfValue {
@@ -1043,8 +1045,10 @@ func (r RefOfSQuadTree) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfSQuadTree.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfSQuadTree) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfSQuadTree) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfSQuadTreeFromVal(val types.Value) RefOfSQuadTree {

View File

@@ -421,8 +421,10 @@ func (r RefOfUser) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfUser.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfUser) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfUser) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfUserFromVal(val types.Value) RefOfUser {
@@ -478,8 +480,10 @@ func (r RefOfSetOfRefOfRemotePhoto) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfSetOfRefOfRemotePhoto.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfSetOfRefOfRemotePhoto) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfSetOfRefOfRemotePhoto) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfSetOfRefOfRemotePhotoFromVal(val types.Value) RefOfSetOfRefOfRemotePhoto {
@@ -683,8 +687,10 @@ func (r RefOfRemotePhoto) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfRemotePhoto.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfRemotePhoto) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfRemotePhoto) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfRemotePhotoFromVal(val types.Value) RefOfRemotePhoto {

View File

@@ -117,10 +117,7 @@ func (s User) InternalImplementation() types.Map {
}
func (s User) Equals(other types.Value) bool {
if other, ok := other.(User); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForUser.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s User) Ref() ref.Ref {
@@ -249,10 +246,7 @@ func (s Album) InternalImplementation() types.Map {
}
func (s Album) Equals(other types.Value) bool {
if other, ok := other.(Album); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForAlbum.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s Album) Ref() ref.Ref {
@@ -341,10 +335,7 @@ func (m MapOfStringToAlbum) InternalImplementation() types.Map {
}
func (m MapOfStringToAlbum) Equals(other types.Value) bool {
if other, ok := other.(MapOfStringToAlbum); ok {
return m.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForMapOfStringToAlbum.Equals(other.TypeRef()) && m.Ref() == other.Ref()
}
func (m MapOfStringToAlbum) Ref() ref.Ref {
@@ -457,10 +448,7 @@ func (s SetOfRemotePhoto) InternalImplementation() types.Set {
}
func (s SetOfRemotePhoto) Equals(other types.Value) bool {
if other, ok := other.(SetOfRemotePhoto); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForSetOfRemotePhoto.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s SetOfRemotePhoto) Ref() ref.Ref {
@@ -583,14 +571,13 @@ func (r RefOfUser) Ref() ref.Ref {
}
func (r RefOfUser) Equals(other types.Value) bool {
if other, ok := other.(RefOfUser); ok {
return r.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForRefOfUser.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfUser) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfUser) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfUserFromVal(val types.Value) RefOfUser {
@@ -643,14 +630,13 @@ func (r RefOfSetOfRefOfRemotePhoto) Ref() ref.Ref {
}
func (r RefOfSetOfRefOfRemotePhoto) Equals(other types.Value) bool {
if other, ok := other.(RefOfSetOfRefOfRemotePhoto); ok {
return r.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForRefOfSetOfRefOfRemotePhoto.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfSetOfRefOfRemotePhoto) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfSetOfRefOfRemotePhoto) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfSetOfRefOfRemotePhotoFromVal(val types.Value) RefOfSetOfRefOfRemotePhoto {
@@ -728,10 +714,7 @@ func (s SetOfRefOfRemotePhoto) InternalImplementation() types.Set {
}
func (s SetOfRefOfRemotePhoto) Equals(other types.Value) bool {
if other, ok := other.(SetOfRefOfRemotePhoto); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForSetOfRefOfRemotePhoto.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s SetOfRefOfRemotePhoto) Ref() ref.Ref {
@@ -854,14 +837,13 @@ func (r RefOfRemotePhoto) Ref() ref.Ref {
}
func (r RefOfRemotePhoto) Equals(other types.Value) bool {
if other, ok := other.(RefOfRemotePhoto); ok {
return r.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForRefOfRemotePhoto.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfRemotePhoto) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfRemotePhoto) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfRemotePhotoFromVal(val types.Value) RefOfRemotePhoto {

View File

@@ -114,10 +114,7 @@ func (s RemotePhoto) InternalImplementation() types.Map {
}
func (s RemotePhoto) Equals(other types.Value) bool {
if other, ok := other.(RemotePhoto); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForRemotePhoto.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s RemotePhoto) Ref() ref.Ref {
@@ -238,10 +235,7 @@ func (s Size) InternalImplementation() types.Map {
}
func (s Size) Equals(other types.Value) bool {
if other, ok := other.(Size); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForSize.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s Size) Ref() ref.Ref {
@@ -314,10 +308,7 @@ func (m MapOfSizeToString) InternalImplementation() types.Map {
}
func (m MapOfSizeToString) Equals(other types.Value) bool {
if other, ok := other.(MapOfSizeToString); ok {
return m.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForMapOfSizeToString.Equals(other.TypeRef()) && m.Ref() == other.Ref()
}
func (m MapOfSizeToString) Ref() ref.Ref {
@@ -451,10 +442,7 @@ func (s SetOfString) InternalImplementation() types.Set {
}
func (s SetOfString) Equals(other types.Value) bool {
if other, ok := other.(SetOfString); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForSetOfString.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s SetOfString) Ref() ref.Ref {

View File

@@ -92,10 +92,7 @@ func (s Geoposition) InternalImplementation() types.Map {
}
func (s Geoposition) Equals(other types.Value) bool {
if other, ok := other.(Geoposition); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForGeoposition.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s Geoposition) Ref() ref.Ref {
@@ -184,10 +181,7 @@ func (s Georectangle) InternalImplementation() types.Map {
}
func (s Georectangle) Equals(other types.Value) bool {
if other, ok := other.(Georectangle); ok {
return s.Ref() == other.Ref()
}
return false
return other != nil && __typeRefForGeorectangle.Equals(other.TypeRef()) && s.Ref() == other.Ref()
}
func (s Georectangle) Ref() ref.Ref {

View File

@@ -312,8 +312,10 @@ func (r RefOfRemotePhoto) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfRemotePhoto.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfRemotePhoto) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfRemotePhoto) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfRemotePhotoFromVal(val types.Value) RefOfRemotePhoto {

View File

@@ -419,8 +419,10 @@ func (r RefOfCommit) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfCommit.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfCommit) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfCommit) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfCommitFromVal(val types.Value) RefOfCommit {

View File

@@ -39,7 +39,7 @@ func NewSet(ds Dataset, vs ...types.Value) types.Ref {
return types.NewRef(r)
}
func SkipTestPull(t *testing.T) {
func TestPull(t *testing.T) {
assert := assert.New(t)
sink := createTestDataset("sink")
@@ -76,7 +76,7 @@ func SkipTestPull(t *testing.T) {
assert.True(source.Head().Equals(sink.Head()))
}
func SkipTestPullFirstCommit(t *testing.T) {
func TestPullFirstCommit(t *testing.T) {
assert := assert.New(t)
sink := createTestDataset("sink")
@@ -96,6 +96,24 @@ func SkipTestPullFirstCommit(t *testing.T) {
assert.True(source.Head().Equals(sink.Head()))
}
func TestPullDeepRef(t *testing.T) {
assert := assert.New(t)
sink := createTestDataset("sink")
source := createTestDataset("source")
sourceInitialValue := types.NewList(
types.NewList(NewList(source)),
types.NewSet(NewSet(source)),
types.NewMap(NewMap(source), NewMap(source)))
source, ok := source.Commit(sourceInitialValue)
assert.True(ok)
sink = sink.Pull(source, 1)
assert.True(source.Head().Equals(sink.Head()))
}
func TestFailedCopyChunks(t *testing.T) {
ds := createTestDataset("test")
r := ref.Parse("sha1-0000000000000000000000000000000000000000")

View File

@@ -23,8 +23,10 @@ func (r {{.Name}}) Equals(other {{$typesPackage}}Value) bool {
return other != nil && __typeRefFor{{.Name}}.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r {{.Name}}) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r {{.Name}}) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func {{.Name}}FromVal(val {{$typesPackage}}Value) {{.Name}} {

View File

@@ -125,8 +125,10 @@ func (r RefOfListOfString) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfListOfString.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfListOfString) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfListOfString) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfListOfStringFromVal(val types.Value) RefOfListOfString {
@@ -324,8 +326,10 @@ func (r RefOfSetOfFloat32) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfSetOfFloat32.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfSetOfFloat32) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfSetOfFloat32) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfSetOfFloat32FromVal(val types.Value) RefOfSetOfFloat32 {
@@ -523,8 +527,10 @@ func (r RefOfFloat32) Equals(other types.Value) bool {
return other != nil && __typeRefForRefOfFloat32.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfFloat32) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfFloat32) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfFloat32FromVal(val types.Value) RefOfFloat32 {

View File

@@ -1,16 +0,0 @@
package types
import (
"github.com/attic-labs/noms/ref"
)
type targetRef interface {
TargetRef() ref.Ref
}
func appendChunk(chunks []ref.Ref, v Value) []ref.Ref {
if v.TypeRef().Kind() == RefKind {
chunks = append(chunks, v.(targetRef).TargetRef())
}
return chunks
}

View File

@@ -421,8 +421,10 @@ func (r RefOfBlob) Equals(other Value) bool {
return other != nil && __typeRefForRefOfBlob.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfBlob) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfBlob) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfBlobFromVal(val Value) RefOfBlob {

View File

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

View File

@@ -371,4 +371,9 @@ func TestListChunks(t *testing.T) {
l2 := NewList(NewRef(Int32(0).Ref()))
c2 := l2.Chunks()
assert.Len(c2, 1)
l3 := NewList(l2)
c3 := l3.Chunks()
assert.Len(c3, 1)
assert.Equal(Int32(0).Ref(), c3[0])
}

View File

@@ -124,8 +124,8 @@ func (m Map) Equals(other Value) bool {
func (m Map) Chunks() (chunks []ref.Ref) {
for _, entry := range m.data {
chunks = appendChunk(chunks, entry.key)
chunks = appendChunk(chunks, entry.value)
chunks = append(chunks, entry.key.Chunks()...)
chunks = append(chunks, entry.value.Chunks()...)
}
return
}

View File

@@ -179,8 +179,10 @@ func (r RefOfPackage) Equals(other Value) bool {
return other != nil && __typeRefForRefOfPackage.Equals(other.TypeRef()) && r.Ref() == other.Ref()
}
func (r RefOfPackage) Chunks() []ref.Ref {
return r.TypeRef().Chunks()
func (r RefOfPackage) Chunks() (chunks []ref.Ref) {
chunks = append(chunks, r.TypeRef().Chunks()...)
chunks = append(chunks, r.target)
return
}
func RefOfPackageFromVal(val Value) RefOfPackage {

View File

@@ -28,7 +28,7 @@ func (r Ref) Ref() ref.Ref {
}
func (r Ref) Chunks() []ref.Ref {
return nil
return []ref.Ref{r.target}
}
func (r Ref) TargetRef() ref.Ref {

View File

@@ -61,3 +61,12 @@ func TestRefTypeRef(t *testing.T) {
assert.Panics(func() { r2.SetTargetValue(Int16(1), cs) })
}
func TestRefChunks(t *testing.T) {
assert := assert.New(t)
l := NewList()
r := NewRef(l.Ref())
assert.Len(r.Chunks(), 1)
assert.Equal(l.Ref(), r.Chunks()[0])
}

View File

@@ -120,7 +120,7 @@ func (s Set) Equals(other Value) bool {
func (s Set) Chunks() (chunks []ref.Ref) {
for _, v := range s.data {
chunks = appendChunk(chunks, v)
chunks = append(chunks, v.Chunks()...)
}
return
}

View File

@@ -12,7 +12,6 @@ import (
type TypeDesc interface {
Kind() NomsKind
Equals(other TypeDesc) bool
ToValue() Value
Describe() string // For use in tests.
}
@@ -43,10 +42,6 @@ func (p PrimitiveDesc) Equals(other TypeDesc) bool {
return p.Kind() == other.Kind()
}
func (p PrimitiveDesc) ToValue() Value {
return nil
}
func (p PrimitiveDesc) Describe() string {
return KindToString[p.Kind()]
}
@@ -101,10 +96,6 @@ func (u UnresolvedDesc) Equals(other TypeDesc) bool {
return false
}
func (u UnresolvedDesc) ToValue() Value {
return NewList(NewRef(u.pkgRef), Int16(u.ordinal))
}
func (u UnresolvedDesc) Describe() string {
panic("Not reachable.")
}
@@ -132,18 +123,6 @@ func (c CompoundDesc) Equals(other TypeDesc) bool {
return true
}
func (c CompoundDesc) ToValue() Value {
switch c.Kind() {
case MapKind:
return NewList(c.ElemTypes[0], c.ElemTypes[1])
case ListKind, RefKind, SetKind:
return c.ElemTypes[0]
default:
d.Chk.Fail("Unknown NomsKind in CompoundDesc.", "%d", c.Kind())
}
panic("unreachable")
}
func (c CompoundDesc) Describe() string {
descElems := func() string {
out := make([]string, len(c.ElemTypes))
@@ -191,14 +170,6 @@ func (e EnumDesc) Equals(other TypeDesc) bool {
return true
}
func (e EnumDesc) ToValue() Value {
vids := make([]Value, len(e.IDs))
for i, id := range e.IDs {
vids[i] = NewString(id)
}
return NewList(vids...)
}
func (e EnumDesc) Describe() string {
return "enum: { " + strings.Join(e.IDs, "\n") + "}\n"
}
@@ -242,42 +213,6 @@ func (s StructDesc) Equals(other TypeDesc) bool {
return true
}
func (s StructDesc) ToValue() Value {
listify := func(fields []Field) List {
v := make([]Value, 3*len(fields))
for i, f := range fields {
v[3*i] = NewString(f.Name)
v[3*i+1] = f.T
v[3*i+2] = Bool(f.Optional)
}
return NewList(v...)
}
desc := NewMap(
NewString("fields"), listify(s.Fields),
NewString("choices"), listify(s.Union),
)
return desc
}
// StructDescFromMap builds a StructDesc from a Noms Map that looks like
// {
// fields: ["field1", TypeRef1, "field2", TypeRef2...],
// choices: ["choice1", TypeRef1...]
// }
// Either fields or choices may be the empty List.
func StructDescFromMap(m Map) StructDesc {
fl := m.Get(NewString("fields")).(List)
cl := m.Get(NewString("choices")).(List)
s := StructDesc{make([]Field, fl.Len()/3), make(Choices, cl.Len()/3)}
for i := uint64(0); i < fl.Len(); i += 3 {
s.Fields[i/3] = Field{fl.Get(i).(String).String(), fl.Get(i + 1).(TypeRef), bool(fl.Get(i + 2).(Bool))}
}
for i := uint64(0); i < cl.Len(); i += 3 {
s.Union[i/3] = Field{cl.Get(i).(String).String(), cl.Get(i + 1).(TypeRef), false}
}
return s
}
func (s StructDesc) Describe() (out string) {
if s.Union != nil {
out += s.Union.Describe()

View File

@@ -97,9 +97,16 @@ func (t TypeRef) Equals(other Value) (res bool) {
}
func (t TypeRef) Chunks() (chunks []ref.Ref) {
v := t.Desc.ToValue()
if v != nil {
chunks = append(chunks, v.Chunks()...)
if t.IsUnresolved() {
if t.HasPackageRef() {
chunks = append(chunks, t.PackageRef())
}
return
}
if desc, ok := t.Desc.(CompoundDesc); ok {
for _, t := range desc.ElemTypes {
chunks = append(chunks, t.Chunks()...)
}
}
return
}