[VOL-3678] First implementation of the BBSim-sadis-server

Change-Id: I5077a8f861f4cc6af9759f31a4a415042c05eba3
diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go
new file mode 100644
index 0000000..dc8b8c7
--- /dev/null
+++ b/vendor/sigs.k8s.io/structured-merge-diff/v4/value/mapreflect.go
@@ -0,0 +1,209 @@
+/*
+Copyright 2019 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 value
+
+import (
+	"reflect"
+)
+
+type mapReflect struct {
+	valueReflect
+}
+
+func (r mapReflect) Length() int {
+	val := r.Value
+	return val.Len()
+}
+
+func (r mapReflect) Empty() bool {
+	val := r.Value
+	return val.Len() == 0
+}
+
+func (r mapReflect) Get(key string) (Value, bool) {
+	return r.GetUsing(HeapAllocator, key)
+}
+
+func (r mapReflect) GetUsing(a Allocator, key string) (Value, bool) {
+	k, v, ok := r.get(key)
+	if !ok {
+		return nil, false
+	}
+	return a.allocValueReflect().mustReuse(v, nil, &r.Value, &k), true
+}
+
+func (r mapReflect) get(k string) (key, value reflect.Value, ok bool) {
+	mapKey := r.toMapKey(k)
+	val := r.Value.MapIndex(mapKey)
+	return mapKey, val, val.IsValid() && val != reflect.Value{}
+}
+
+func (r mapReflect) Has(key string) bool {
+	var val reflect.Value
+	val = r.Value.MapIndex(r.toMapKey(key))
+	if !val.IsValid() {
+		return false
+	}
+	return val != reflect.Value{}
+}
+
+func (r mapReflect) Set(key string, val Value) {
+	r.Value.SetMapIndex(r.toMapKey(key), reflect.ValueOf(val.Unstructured()))
+}
+
+func (r mapReflect) Delete(key string) {
+	val := r.Value
+	val.SetMapIndex(r.toMapKey(key), reflect.Value{})
+}
+
+// TODO: Do we need to support types that implement json.Marshaler and are used as string keys?
+func (r mapReflect) toMapKey(key string) reflect.Value {
+	val := r.Value
+	return reflect.ValueOf(key).Convert(val.Type().Key())
+}
+
+func (r mapReflect) Iterate(fn func(string, Value) bool) bool {
+	return r.IterateUsing(HeapAllocator, fn)
+}
+
+func (r mapReflect) IterateUsing(a Allocator, fn func(string, Value) bool) bool {
+	if r.Value.Len() == 0 {
+		return true
+	}
+	v := a.allocValueReflect()
+	defer a.Free(v)
+	return eachMapEntry(r.Value, func(e *TypeReflectCacheEntry, key reflect.Value, value reflect.Value) bool {
+		return fn(key.String(), v.mustReuse(value, e, &r.Value, &key))
+	})
+}
+
+func eachMapEntry(val reflect.Value, fn func(*TypeReflectCacheEntry, reflect.Value, reflect.Value) bool) bool {
+	iter := val.MapRange()
+	entry := TypeReflectEntryOf(val.Type().Elem())
+	for iter.Next() {
+		next := iter.Value()
+		if !next.IsValid() {
+			continue
+		}
+		if !fn(entry, iter.Key(), next) {
+			return false
+		}
+	}
+	return true
+}
+
+func (r mapReflect) Unstructured() interface{} {
+	result := make(map[string]interface{}, r.Length())
+	r.Iterate(func(s string, value Value) bool {
+		result[s] = value.Unstructured()
+		return true
+	})
+	return result
+}
+
+func (r mapReflect) Equals(m Map) bool {
+	return r.EqualsUsing(HeapAllocator, m)
+}
+
+func (r mapReflect) EqualsUsing(a Allocator, m Map) bool {
+	lhsLength := r.Length()
+	rhsLength := m.Length()
+	if lhsLength != rhsLength {
+		return false
+	}
+	if lhsLength == 0 {
+		return true
+	}
+	vr := a.allocValueReflect()
+	defer a.Free(vr)
+	entry := TypeReflectEntryOf(r.Value.Type().Elem())
+	return m.Iterate(func(key string, value Value) bool {
+		_, lhsVal, ok := r.get(key)
+		if !ok {
+			return false
+		}
+		return Equals(vr.mustReuse(lhsVal, entry, nil, nil), value)
+	})
+}
+
+func (r mapReflect) Zip(other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool {
+	return r.ZipUsing(HeapAllocator, other, order, fn)
+}
+
+func (r mapReflect) ZipUsing(a Allocator, other Map, order MapTraverseOrder, fn func(key string, lhs, rhs Value) bool) bool {
+	if otherMapReflect, ok := other.(*mapReflect); ok && order == Unordered {
+		return r.unorderedReflectZip(a, otherMapReflect, fn)
+	}
+	return defaultMapZip(a, &r, other, order, fn)
+}
+
+// unorderedReflectZip provides an optimized unordered zip for mapReflect types.
+func (r mapReflect) unorderedReflectZip(a Allocator, other *mapReflect, fn func(key string, lhs, rhs Value) bool) bool {
+	if r.Empty() && (other == nil || other.Empty()) {
+		return true
+	}
+
+	lhs := r.Value
+	lhsEntry := TypeReflectEntryOf(lhs.Type().Elem())
+
+	// map lookup via reflection is expensive enough that it is better to keep track of visited keys
+	visited := map[string]struct{}{}
+
+	vlhs, vrhs := a.allocValueReflect(), a.allocValueReflect()
+	defer a.Free(vlhs)
+	defer a.Free(vrhs)
+
+	if other != nil {
+		rhs := other.Value
+		rhsEntry := TypeReflectEntryOf(rhs.Type().Elem())
+		iter := rhs.MapRange()
+
+		for iter.Next() {
+			key := iter.Key()
+			keyString := key.String()
+			next := iter.Value()
+			if !next.IsValid() {
+				continue
+			}
+			rhsVal := vrhs.mustReuse(next, rhsEntry, &rhs, &key)
+			visited[keyString] = struct{}{}
+			var lhsVal Value
+			if _, v, ok := r.get(keyString); ok {
+				lhsVal = vlhs.mustReuse(v, lhsEntry, &lhs, &key)
+			}
+			if !fn(keyString, lhsVal, rhsVal) {
+				return false
+			}
+		}
+	}
+
+	iter := lhs.MapRange()
+	for iter.Next() {
+		key := iter.Key()
+		if _, ok := visited[key.String()]; ok {
+			continue
+		}
+		next := iter.Value()
+		if !next.IsValid() {
+			continue
+		}
+		if !fn(key.String(), vlhs.mustReuse(next, lhsEntry, &lhs, &key), nil) {
+			return false
+		}
+	}
+	return true
+}