compare: allow nil newDh and oldDh

This allows people to create synthetic InodeDeltas, which is something
that umoci would like to be able to do in order to nicely create 'umoci
insert' layers.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
Aleksa Sarai 2018-05-16 19:53:28 +10:00
parent ffb4a05860
commit be3abf053a
No known key found for this signature in database
GPG key ID: 9E18AA267DDB8DB4

View file

@ -325,6 +325,10 @@ func compareEntry(oldEntry, newEntry Entry) ([]KeyDelta, error) {
// missing entries and the like). A missing or extra key is treated as a // missing entries and the like). A missing or extra key is treated as a
// Modified type. // Modified type.
// //
// If oldDh or newDh are empty, we assume they are a hierarchy that is
// completely empty. This is purely for helping callers create synthetic
// InodeDeltas.
//
// NB: The order of the parameters matters (old, new) because Extra and // NB: The order of the parameters matters (old, new) because Extra and
// Missing are considered as different discrepancy types. // Missing are considered as different discrepancy types.
func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, error) { func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, error) {
@ -338,43 +342,47 @@ func Compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword) ([]InodeDelta, er
// map to make sure we don't start comparing unrelated entries. // map to make sure we don't start comparing unrelated entries.
diffs := map[string]*stateT{} diffs := map[string]*stateT{}
// First, iterate over the old hierarchy. // First, iterate over the old hierarchy. If nil, pretend it's empty.
for _, e := range oldDh.Entries { if oldDh != nil {
if e.Type == RelativeType || e.Type == FullType { for _, e := range oldDh.Entries {
path, err := e.Path() if e.Type == RelativeType || e.Type == FullType {
if err != nil { path, err := e.Path()
return nil, err if err != nil {
} return nil, err
}
// Cannot take &kv because it's the iterator. // Cannot take &kv because it's the iterator.
copy := new(Entry) copy := new(Entry)
*copy = e *copy = e
_, ok := diffs[path] _, ok := diffs[path]
if !ok { if !ok {
diffs[path] = &stateT{} diffs[path] = &stateT{}
}
diffs[path].Old = copy
} }
diffs[path].Old = copy
} }
} }
// Then, iterate over the new hierarchy. // Then, iterate over the new hierarchy. If nil, pretend it's empty.
for _, e := range newDh.Entries { if newDh != nil {
if e.Type == RelativeType || e.Type == FullType { for _, e := range newDh.Entries {
path, err := e.Path() if e.Type == RelativeType || e.Type == FullType {
if err != nil { path, err := e.Path()
return nil, err if err != nil {
} return nil, err
}
// Cannot take &kv because it's the iterator. // Cannot take &kv because it's the iterator.
copy := new(Entry) copy := new(Entry)
*copy = e *copy = e
_, ok := diffs[path] _, ok := diffs[path]
if !ok { if !ok {
diffs[path] = &stateT{} diffs[path] = &stateT{}
}
diffs[path].New = copy
} }
diffs[path].New = copy
} }
} }