Skip to content

Commit fa5e197

Browse files
Antoine PelisseJennifer Buckley
Antoine Pelisse
authored and
Jennifer Buckley
committed
Implement equality for Values
Equality doesn't require the same amount of sophistication than ordering comparison. Implement an Equal function that does just that but does it much faster. Benchmark results show up to 96% improvement: ``` benchmark old ns/op new ns/op delta BenchmarkDeducedSimple-12 110083 103256 -6.20% BenchmarkDeducedNested-12 374366 374160 -0.06% BenchmarkDeducedNestedAcrossVersion-12 392864 405525 +3.22% BenchmarkLeafConflictAcrossVersion-12 89112 89070 -0.05% BenchmarkMultipleApplierRecursiveRealConversion-12 1564330 1574620 +0.66% BenchmarkOperations/Pod/Create-12 103693 103970 +0.27% BenchmarkOperations/Pod/Apply-12 291760 291317 -0.15% BenchmarkOperations/Pod/Update-12 193419 190470 -1.52% BenchmarkOperations/Pod/UpdateVersion-12 261692 251966 -3.72% BenchmarkOperations/Node/Create-12 152047 155710 +2.41% BenchmarkOperations/Node/Apply-12 499187 473901 -5.07% BenchmarkOperations/Node/Update-12 299271 279142 -6.73% BenchmarkOperations/Node/UpdateVersion-12 438723 403125 -8.11% BenchmarkOperations/Endpoints/Create-12 12246 11940 -2.50% BenchmarkOperations/Endpoints/Apply-12 915806 924080 +0.90% BenchmarkOperations/Endpoints/Update-12 7155675 285092 -96.02% BenchmarkOperations/Endpoints/UpdateVersion-12 14278150 544040 -96.19% BenchmarkOperations/CustomResourceDefinition/Create-12 1312734 1288472 -1.85% BenchmarkOperations/CustomResourceDefinition/Apply-12 3346591 3376864 +0.90% BenchmarkOperations/CustomResourceDefinition/Update-12 10681243 1758764 -83.53% BenchmarkOperations/CustomResourceDefinition/UpdateVersion-12 19069925 2202330 -88.45% ```
1 parent 6149e45 commit fa5e197

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

value/less_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ func TestValueLess(t *testing.T) {
296296
t.Run(table[i].name, func(t *testing.T) {
297297
tt := table[i]
298298
if tt.eq {
299+
if !tt.a.Equals(tt.b) {
300+
t.Errorf("oops, a != b: %#v, %#v", tt.a, tt.b)
301+
}
299302
if tt.a.Less(tt.b) {
300303
t.Errorf("oops, a < b: %#v, %#v", tt.a, tt.b)
301304
}

value/value.go

+88-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,63 @@ type Value struct {
3636

3737
// Equals returns true iff the two values are equal.
3838
func (v Value) Equals(rhs Value) bool {
39-
return !v.Less(rhs) && !rhs.Less(v)
39+
if v.FloatValue != nil || rhs.FloatValue != nil {
40+
var lf float64
41+
if v.FloatValue != nil {
42+
lf = float64(*v.FloatValue)
43+
} else if v.IntValue != nil {
44+
lf = float64(*v.IntValue)
45+
} else {
46+
return false
47+
}
48+
var rf float64
49+
if rhs.FloatValue != nil {
50+
rf = float64(*rhs.FloatValue)
51+
} else if rhs.IntValue != nil {
52+
rf = float64(*rhs.IntValue)
53+
} else {
54+
return false
55+
}
56+
return lf == rf
57+
}
58+
if v.IntValue != nil {
59+
if rhs.IntValue != nil {
60+
return *v.IntValue == *rhs.IntValue
61+
}
62+
return false
63+
}
64+
if v.StringValue != nil {
65+
if rhs.StringValue != nil {
66+
return *v.StringValue == *rhs.StringValue
67+
}
68+
return false
69+
}
70+
if v.BooleanValue != nil {
71+
if rhs.BooleanValue != nil {
72+
return *v.BooleanValue == *rhs.BooleanValue
73+
}
74+
return false
75+
}
76+
if v.ListValue != nil {
77+
if rhs.ListValue != nil {
78+
return v.ListValue.Equals(rhs.ListValue)
79+
}
80+
return false
81+
}
82+
if v.MapValue != nil {
83+
if rhs.MapValue != nil {
84+
return v.MapValue.Equals(rhs.MapValue)
85+
}
86+
return false
87+
}
88+
if v.Null {
89+
if rhs.Null {
90+
return true
91+
}
92+
return false
93+
}
94+
// No field is set, on either objects.
95+
return true
4096
}
4197

4298
// Less provides a total ordering for Value (so that they can be sorted, even
@@ -134,6 +190,20 @@ type List struct {
134190
Items []Value
135191
}
136192

193+
// Equals compares two lists lexically.
194+
func (l *List) Equals(rhs *List) bool {
195+
if len(l.Items) != len(rhs.Items) {
196+
return false
197+
}
198+
199+
for i, lv := range l.Items {
200+
if !lv.Equals(rhs.Items[i]) {
201+
return false
202+
}
203+
}
204+
return true
205+
}
206+
137207
// Less compares two lists lexically.
138208
func (l *List) Less(rhs *List) bool {
139209
i := 0
@@ -191,6 +261,23 @@ func (m *Map) computeOrder() []int {
191261
return m.order
192262
}
193263

264+
// Equals compares two maps lexically.
265+
func (m *Map) Equals(rhs *Map) bool {
266+
if len(m.Items) != len(rhs.Items) {
267+
return false
268+
}
269+
for _, lfield := range m.Items {
270+
rfield, ok := rhs.Get(lfield.Name)
271+
if !ok {
272+
return false
273+
}
274+
if !lfield.Value.Equals(rfield.Value) {
275+
return false
276+
}
277+
}
278+
return true
279+
}
280+
194281
// Less compares two maps lexically.
195282
func (m *Map) Less(rhs *Map) bool {
196283
var noAllocL, noAllocR [2]int

0 commit comments

Comments
 (0)