25
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/element.go
generated
vendored
25
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/element.go
generated
vendored
@@ -35,7 +35,7 @@ type PathElement struct {
|
||||
// Key selects the list element which has fields matching those given.
|
||||
// The containing object must be an associative list with map typed
|
||||
// elements.
|
||||
Key *value.Map
|
||||
Key *value.FieldList
|
||||
|
||||
// Value selects the list element with the given value. The containing
|
||||
// object must be an associative list with a primitive typed element
|
||||
@@ -62,7 +62,7 @@ func (e PathElement) Less(rhs PathElement) bool {
|
||||
if rhs.Key == nil {
|
||||
return true
|
||||
}
|
||||
return e.Key.Less(rhs.Key)
|
||||
return e.Key.Less(*rhs.Key)
|
||||
} else if rhs.Key != nil {
|
||||
return false
|
||||
}
|
||||
@@ -101,13 +101,11 @@ func (e PathElement) String() string {
|
||||
case e.FieldName != nil:
|
||||
return "." + *e.FieldName
|
||||
case e.Key != nil:
|
||||
strs := make([]string, len(e.Key.Items))
|
||||
for i, k := range e.Key.Items {
|
||||
strs := make([]string, len(*e.Key))
|
||||
for i, k := range *e.Key {
|
||||
strs[i] = fmt.Sprintf("%v=%v", k.Name, k.Value)
|
||||
}
|
||||
// The order must be canonical, since we use the string value
|
||||
// in a set structure.
|
||||
sort.Strings(strs)
|
||||
// Keys are supposed to be sorted.
|
||||
return "[" + strings.Join(strs, ",") + "]"
|
||||
case e.Value != nil:
|
||||
return fmt.Sprintf("[=%v]", e.Value)
|
||||
@@ -123,18 +121,19 @@ func (e PathElement) String() string {
|
||||
// names (type must be string) with values (type must be value.Value). If these
|
||||
// conditions are not met, KeyByFields will panic--it's intended for static
|
||||
// construction and shouldn't have user-produced values passed to it.
|
||||
func KeyByFields(nameValues ...interface{}) []value.Field {
|
||||
func KeyByFields(nameValues ...interface{}) *value.FieldList {
|
||||
if len(nameValues)%2 != 0 {
|
||||
panic("must have a value for every name")
|
||||
}
|
||||
out := []value.Field{}
|
||||
out := value.FieldList{}
|
||||
for i := 0; i < len(nameValues)-1; i += 2 {
|
||||
out = append(out, value.Field{
|
||||
Name: nameValues[i].(string),
|
||||
Value: nameValues[i+1].(value.Value),
|
||||
})
|
||||
}
|
||||
return out
|
||||
out.Sort()
|
||||
return &out
|
||||
}
|
||||
|
||||
// PathElementSet is a set of path elements.
|
||||
@@ -143,6 +142,12 @@ type PathElementSet struct {
|
||||
members sortedPathElements
|
||||
}
|
||||
|
||||
func MakePathElementSet(size int) PathElementSet {
|
||||
return PathElementSet{
|
||||
members: make(sortedPathElements, 0, size),
|
||||
}
|
||||
}
|
||||
|
||||
type sortedPathElements []PathElement
|
||||
|
||||
// Implement the sort interface; this would permit bulk creation, which would
|
||||
|
||||
5
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/fromvalue.go
generated
vendored
5
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/fromvalue.go
generated
vendored
@@ -104,7 +104,7 @@ func GuessBestListPathElement(index int, item value.Value) PathElement {
|
||||
return PathElement{Index: &index}
|
||||
}
|
||||
|
||||
var keys []value.Field
|
||||
var keys value.FieldList
|
||||
for _, name := range AssociativeListCandidateFieldNames {
|
||||
f, ok := item.MapValue.Get(name)
|
||||
if !ok {
|
||||
@@ -117,7 +117,8 @@ func GuessBestListPathElement(index int, item value.Value) PathElement {
|
||||
keys = append(keys, *f)
|
||||
}
|
||||
if len(keys) > 0 {
|
||||
return PathElement{Key: &value.Map{Items: keys}}
|
||||
keys.Sort()
|
||||
return PathElement{Key: &keys}
|
||||
}
|
||||
return PathElement{Index: &index}
|
||||
}
|
||||
|
||||
6
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/path.go
generated
vendored
6
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/path.go
generated
vendored
@@ -88,11 +88,11 @@ func MakePath(parts ...interface{}) (Path, error) {
|
||||
fp = append(fp, PathElement{Index: &t})
|
||||
case string:
|
||||
fp = append(fp, PathElement{FieldName: &t})
|
||||
case []value.Field:
|
||||
if len(t) == 0 {
|
||||
case *value.FieldList:
|
||||
if len(*t) == 0 {
|
||||
return nil, fmt.Errorf("associative list key type path elements must have at least one key (got zero)")
|
||||
}
|
||||
fp = append(fp, PathElement{Key: &value.Map{Items: t}})
|
||||
fp = append(fp, PathElement{Key: t})
|
||||
case value.Value:
|
||||
// TODO: understand schema and verify that this is a set type
|
||||
// TODO: make a copy of t
|
||||
|
||||
85
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/pathelementmap.go
generated
vendored
Normal file
85
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/pathelementmap.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fieldpath
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"sigs.k8s.io/structured-merge-diff/value"
|
||||
)
|
||||
|
||||
// PathElementValueMap is a map from PathElement to value.Value.
|
||||
//
|
||||
// TODO(apelisse): We have multiple very similar implementation of this
|
||||
// for PathElementSet and SetNodeMap, so we could probably share the
|
||||
// code.
|
||||
type PathElementValueMap struct {
|
||||
members sortedPathElementValues
|
||||
}
|
||||
|
||||
func MakePathElementValueMap(size int) PathElementValueMap {
|
||||
return PathElementValueMap{
|
||||
members: make(sortedPathElementValues, 0, size),
|
||||
}
|
||||
}
|
||||
|
||||
type pathElementValue struct {
|
||||
PathElement PathElement
|
||||
Value value.Value
|
||||
}
|
||||
|
||||
type sortedPathElementValues []pathElementValue
|
||||
|
||||
// Implement the sort interface; this would permit bulk creation, which would
|
||||
// be faster than doing it one at a time via Insert.
|
||||
func (spev sortedPathElementValues) Len() int { return len(spev) }
|
||||
func (spev sortedPathElementValues) Less(i, j int) bool {
|
||||
return spev[i].PathElement.Less(spev[j].PathElement)
|
||||
}
|
||||
func (spev sortedPathElementValues) Swap(i, j int) { spev[i], spev[j] = spev[j], spev[i] }
|
||||
|
||||
// Insert adds the pathelement and associated value in the map.
|
||||
func (s *PathElementValueMap) Insert(pe PathElement, v value.Value) {
|
||||
loc := sort.Search(len(s.members), func(i int) bool {
|
||||
return !s.members[i].PathElement.Less(pe)
|
||||
})
|
||||
if loc == len(s.members) {
|
||||
s.members = append(s.members, pathElementValue{pe, v})
|
||||
return
|
||||
}
|
||||
if s.members[loc].PathElement.Equals(pe) {
|
||||
return
|
||||
}
|
||||
s.members = append(s.members, pathElementValue{})
|
||||
copy(s.members[loc+1:], s.members[loc:])
|
||||
s.members[loc] = pathElementValue{pe, v}
|
||||
}
|
||||
|
||||
// Get retrieves the value associated with the given PathElement from the map.
|
||||
// (nil, false) is returned if there is no such PathElement.
|
||||
func (s *PathElementValueMap) Get(pe PathElement) (value.Value, bool) {
|
||||
loc := sort.Search(len(s.members), func(i int) bool {
|
||||
return !s.members[i].PathElement.Less(pe)
|
||||
})
|
||||
if loc == len(s.members) {
|
||||
return value.Value{}, false
|
||||
}
|
||||
if s.members[loc].PathElement.Equals(pe) {
|
||||
return s.members[loc].Value, true
|
||||
}
|
||||
return value.Value{}, false
|
||||
}
|
||||
31
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/serialize-pe.go
generated
vendored
31
vendor/sigs.k8s.io/structured-merge-diff/fieldpath/serialize-pe.go
generated
vendored
@@ -83,14 +83,18 @@ func DeserializePathElement(s string) (PathElement, error) {
|
||||
case peKeySepBytes[0]:
|
||||
iter := readPool.BorrowIterator(b)
|
||||
defer readPool.ReturnIterator(iter)
|
||||
v, err := value.ReadJSONIter(iter)
|
||||
if err != nil {
|
||||
return PathElement{}, err
|
||||
}
|
||||
if v.MapValue == nil {
|
||||
return PathElement{}, fmt.Errorf("expected key value pairs but got %#v", v)
|
||||
}
|
||||
return PathElement{Key: v.MapValue}, nil
|
||||
fields := value.FieldList{}
|
||||
iter.ReadObjectCB(func(iter *jsoniter.Iterator, key string) bool {
|
||||
v, err := value.ReadJSONIter(iter)
|
||||
if err != nil {
|
||||
iter.Error = err
|
||||
return false
|
||||
}
|
||||
fields = append(fields, value.Field{Name: key, Value: v})
|
||||
return true
|
||||
})
|
||||
fields.Sort()
|
||||
return PathElement{Key: &fields}, iter.Error
|
||||
case peIndexSepBytes[0]:
|
||||
i, err := strconv.Atoi(s[2:])
|
||||
if err != nil {
|
||||
@@ -129,8 +133,15 @@ func serializePathElementToWriter(w io.Writer, pe PathElement) error {
|
||||
if _, err := stream.Write(peKeySepBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
v := value.Value{MapValue: pe.Key}
|
||||
v.WriteJSONStream(stream)
|
||||
stream.WriteObjectStart()
|
||||
for i, field := range *pe.Key {
|
||||
if i > 0 {
|
||||
stream.WriteMore()
|
||||
}
|
||||
stream.WriteObjectField(field.Name)
|
||||
field.Value.WriteJSONStream(stream)
|
||||
}
|
||||
stream.WriteObjectEnd()
|
||||
case pe.Value != nil:
|
||||
if _, err := stream.Write(peValueSepBytes); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user