managers.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. package fieldpath
  14. import (
  15. "fmt"
  16. "strings"
  17. )
  18. // APIVersion describes the version of an object or of a fieldset.
  19. type APIVersion string
  20. type VersionedSet interface {
  21. Set() *Set
  22. APIVersion() APIVersion
  23. Applied() bool
  24. }
  25. // VersionedSet associates a version to a set.
  26. type versionedSet struct {
  27. set *Set
  28. apiVersion APIVersion
  29. applied bool
  30. }
  31. func NewVersionedSet(set *Set, apiVersion APIVersion, applied bool) VersionedSet {
  32. return versionedSet{
  33. set: set,
  34. apiVersion: apiVersion,
  35. applied: applied,
  36. }
  37. }
  38. func (v versionedSet) Set() *Set {
  39. return v.set
  40. }
  41. func (v versionedSet) APIVersion() APIVersion {
  42. return v.apiVersion
  43. }
  44. func (v versionedSet) Applied() bool {
  45. return v.applied
  46. }
  47. // ManagedFields is a map from manager to VersionedSet (what they own in
  48. // what version).
  49. type ManagedFields map[string]VersionedSet
  50. // Equals returns true if the two managedfields are the same, false
  51. // otherwise.
  52. func (lhs ManagedFields) Equals(rhs ManagedFields) bool {
  53. if len(lhs) != len(rhs) {
  54. return false
  55. }
  56. for manager, left := range lhs {
  57. right, ok := rhs[manager]
  58. if !ok {
  59. return false
  60. }
  61. if left.APIVersion() != right.APIVersion() || left.Applied() != right.Applied() {
  62. return false
  63. }
  64. if !left.Set().Equals(right.Set()) {
  65. return false
  66. }
  67. }
  68. return true
  69. }
  70. // Copy the list, this is mostly a shallow copy.
  71. func (lhs ManagedFields) Copy() ManagedFields {
  72. copy := ManagedFields{}
  73. for manager, set := range lhs {
  74. copy[manager] = set
  75. }
  76. return copy
  77. }
  78. // Difference returns a symmetric difference between two Managers. If a
  79. // given user's entry has version X in lhs and version Y in rhs, then
  80. // the return value for that user will be from rhs. If the difference for
  81. // a user is an empty set, that user will not be inserted in the map.
  82. func (lhs ManagedFields) Difference(rhs ManagedFields) ManagedFields {
  83. diff := ManagedFields{}
  84. for manager, left := range lhs {
  85. right, ok := rhs[manager]
  86. if !ok {
  87. if !left.Set().Empty() {
  88. diff[manager] = left
  89. }
  90. continue
  91. }
  92. // If we have sets in both but their version
  93. // differs, we don't even diff and keep the
  94. // entire thing.
  95. if left.APIVersion() != right.APIVersion() {
  96. diff[manager] = right
  97. continue
  98. }
  99. newSet := left.Set().Difference(right.Set()).Union(right.Set().Difference(left.Set()))
  100. if !newSet.Empty() {
  101. diff[manager] = NewVersionedSet(newSet, right.APIVersion(), false)
  102. }
  103. }
  104. for manager, set := range rhs {
  105. if _, ok := lhs[manager]; ok {
  106. // Already done
  107. continue
  108. }
  109. if !set.Set().Empty() {
  110. diff[manager] = set
  111. }
  112. }
  113. return diff
  114. }
  115. func (lhs ManagedFields) String() string {
  116. s := strings.Builder{}
  117. for k, v := range lhs {
  118. fmt.Fprintf(&s, "%s:\n", k)
  119. fmt.Fprintf(&s, "- Applied: %v\n", v.Applied())
  120. fmt.Fprintf(&s, "- APIVersion: %v\n", v.APIVersion())
  121. fmt.Fprintf(&s, "- Set: %v\n", v.Set())
  122. }
  123. return s.String()
  124. }