Skip to content

Commit 89db19a

Browse files
Antoine Pelisseapelisse
Antoine Pelisse
authored andcommitted
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 1ad9a28 commit 89db19a

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

value/less_test.go

Lines changed: 3 additions & 0 deletions
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

Lines changed: 88 additions & 1 deletion
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
@@ -187,6 +243,20 @@ type List struct {
187243
Items []Value
188244
}
189245

246+
// Equals compares two lists lexically.
247+
func (l *List) Equals(rhs *List) bool {
248+
if len(l.Items) != len(rhs.Items) {
249+
return false
250+
}
251+
252+
for i, lv := range l.Items {
253+
if !lv.Equals(rhs.Items[i]) {
254+
return false
255+
}
256+
}
257+
return true
258+
}
259+
190260
// Less compares two lists lexically.
191261
func (l *List) Less(rhs *List) bool {
192262
i := 0
@@ -244,6 +314,23 @@ func (m *Map) computeOrder() []int {
244314
return m.order
245315
}
246316

317+
// Equals compares two maps lexically.
318+
func (m *Map) Equals(rhs *Map) bool {
319+
if len(m.Items) != len(rhs.Items) {
320+
return false
321+
}
322+
for _, lfield := range m.Items {
323+
rfield, ok := rhs.Get(lfield.Name)
324+
if !ok {
325+
return false
326+
}
327+
if !lfield.Value.Equals(rfield.Value) {
328+
return false
329+
}
330+
}
331+
return true
332+
}
333+
247334
// Less compares two maps lexically.
248335
func (m *Map) Less(rhs *Map) bool {
249336
var noAllocL, noAllocR [2]int

0 commit comments

Comments
 (0)