...

Source file src/sigs.k8s.io/structured-merge-diff/v4/fieldpath/managers.go

Documentation: sigs.k8s.io/structured-merge-diff/v4/fieldpath

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6      http://www.apache.org/licenses/LICENSE-2.0
     7  Unless required by applicable law or agreed to in writing, software
     8  distributed under the License is distributed on an "AS IS" BASIS,
     9  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  See the License for the specific language governing permissions and
    11  limitations under the License.
    12  */
    13  
    14  package fieldpath
    15  
    16  import (
    17  	"fmt"
    18  	"strings"
    19  )
    20  
    21  // APIVersion describes the version of an object or of a fieldset.
    22  type APIVersion string
    23  
    24  type VersionedSet interface {
    25  	Set() *Set
    26  	APIVersion() APIVersion
    27  	Applied() bool
    28  }
    29  
    30  // VersionedSet associates a version to a set.
    31  type versionedSet struct {
    32  	set        *Set
    33  	apiVersion APIVersion
    34  	applied    bool
    35  }
    36  
    37  func NewVersionedSet(set *Set, apiVersion APIVersion, applied bool) VersionedSet {
    38  	return versionedSet{
    39  		set:        set,
    40  		apiVersion: apiVersion,
    41  		applied:    applied,
    42  	}
    43  }
    44  
    45  func (v versionedSet) Set() *Set {
    46  	return v.set
    47  }
    48  
    49  func (v versionedSet) APIVersion() APIVersion {
    50  	return v.apiVersion
    51  }
    52  
    53  func (v versionedSet) Applied() bool {
    54  	return v.applied
    55  }
    56  
    57  // ManagedFields is a map from manager to VersionedSet (what they own in
    58  // what version).
    59  type ManagedFields map[string]VersionedSet
    60  
    61  // Equals returns true if the two managedfields are the same, false
    62  // otherwise.
    63  func (lhs ManagedFields) Equals(rhs ManagedFields) bool {
    64  	if len(lhs) != len(rhs) {
    65  		return false
    66  	}
    67  
    68  	for manager, left := range lhs {
    69  		right, ok := rhs[manager]
    70  		if !ok {
    71  			return false
    72  		}
    73  		if left.APIVersion() != right.APIVersion() || left.Applied() != right.Applied() {
    74  			return false
    75  		}
    76  		if !left.Set().Equals(right.Set()) {
    77  			return false
    78  		}
    79  	}
    80  	return true
    81  }
    82  
    83  // Copy the list, this is mostly a shallow copy.
    84  func (lhs ManagedFields) Copy() ManagedFields {
    85  	copy := ManagedFields{}
    86  	for manager, set := range lhs {
    87  		copy[manager] = set
    88  	}
    89  	return copy
    90  }
    91  
    92  // Difference returns a symmetric difference between two Managers. If a
    93  // given user's entry has version X in lhs and version Y in rhs, then
    94  // the return value for that user will be from rhs. If the difference for
    95  // a user is an empty set, that user will not be inserted in the map.
    96  func (lhs ManagedFields) Difference(rhs ManagedFields) ManagedFields {
    97  	diff := ManagedFields{}
    98  
    99  	for manager, left := range lhs {
   100  		right, ok := rhs[manager]
   101  		if !ok {
   102  			if !left.Set().Empty() {
   103  				diff[manager] = left
   104  			}
   105  			continue
   106  		}
   107  
   108  		// If we have sets in both but their version
   109  		// differs, we don't even diff and keep the
   110  		// entire thing.
   111  		if left.APIVersion() != right.APIVersion() {
   112  			diff[manager] = right
   113  			continue
   114  		}
   115  
   116  		newSet := left.Set().Difference(right.Set()).Union(right.Set().Difference(left.Set()))
   117  		if !newSet.Empty() {
   118  			diff[manager] = NewVersionedSet(newSet, right.APIVersion(), false)
   119  		}
   120  	}
   121  
   122  	for manager, set := range rhs {
   123  		if _, ok := lhs[manager]; ok {
   124  			// Already done
   125  			continue
   126  		}
   127  		if !set.Set().Empty() {
   128  			diff[manager] = set
   129  		}
   130  	}
   131  
   132  	return diff
   133  }
   134  
   135  func (lhs ManagedFields) String() string {
   136  	s := strings.Builder{}
   137  	for k, v := range lhs {
   138  		fmt.Fprintf(&s, "%s:\n", k)
   139  		fmt.Fprintf(&s, "- Applied: %v\n", v.Applied())
   140  		fmt.Fprintf(&s, "- APIVersion: %v\n", v.APIVersion())
   141  		fmt.Fprintf(&s, "- Set: %v\n", v.Set())
   142  	}
   143  	return s.String()
   144  }
   145  

View as plain text