Skip to content

Commit 9cd3089

Browse files
author
Antoine Pelisse
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 1ad9a28 commit 9cd3089

File tree

2 files changed

+72
-34
lines changed

2 files changed

+72
-34
lines changed

value/less_test.go

+3-33
Original file line numberDiff line numberDiff line change
@@ -29,39 +29,6 @@ func TestValueLess(t *testing.T) {
2929
eq bool
3030
}{
3131
{
32-
name: "Invalid-1",
33-
a: Value{},
34-
b: Value{},
35-
eq: true,
36-
}, {
37-
name: "Invalid-2",
38-
a: FloatValue(1),
39-
b: Value{},
40-
}, {
41-
name: "Invalid-3",
42-
a: IntValue(1),
43-
b: Value{},
44-
}, {
45-
name: "Invalid-4",
46-
a: StringValue("aoeu"),
47-
b: Value{},
48-
}, {
49-
name: "Invalid-5",
50-
a: BooleanValue(true),
51-
b: Value{},
52-
}, {
53-
name: "Invalid-6",
54-
a: Value{ListValue: &List{}},
55-
b: Value{},
56-
}, {
57-
name: "Invalid-7",
58-
a: Value{MapValue: &Map{}},
59-
b: Value{},
60-
}, {
61-
name: "Invalid-8",
62-
a: Value{Null: true},
63-
b: Value{},
64-
}, {
6532
name: "Float-1",
6633
a: FloatValue(1.14),
6734
b: FloatValue(3.14),
@@ -296,6 +263,9 @@ func TestValueLess(t *testing.T) {
296263
t.Run(table[i].name, func(t *testing.T) {
297264
tt := table[i]
298265
if tt.eq {
266+
if !tt.a.Equals(tt.b) {
267+
t.Errorf("oops, a != b: %#v, %#v", tt.a, tt.b)
268+
}
299269
if tt.a.Less(tt.b) {
300270
t.Errorf("oops, a < b: %#v, %#v", tt.a, tt.b)
301271
}

value/value.go

+69-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,44 @@ 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.IntValue != nil && rhs.IntValue != nil {
40+
return *v.IntValue == *rhs.IntValue
41+
}
42+
if v.FloatValue != nil || rhs.FloatValue != nil {
43+
lf := float64(0.0)
44+
if v.FloatValue != nil {
45+
lf = float64(*v.FloatValue)
46+
} else if v.IntValue != nil {
47+
lf = float64(*v.IntValue)
48+
} else {
49+
return false
50+
}
51+
rf := 0.0
52+
if rhs.FloatValue != nil {
53+
rf = float64(*rhs.FloatValue)
54+
} else if rhs.IntValue != nil {
55+
rf = float64(*rhs.IntValue)
56+
} else {
57+
return false
58+
}
59+
return lf == rf
60+
}
61+
if v.StringValue != nil && rhs.StringValue != nil {
62+
return *v.StringValue == *rhs.StringValue
63+
}
64+
if v.BooleanValue != nil && rhs.BooleanValue != nil {
65+
return *v.BooleanValue == *rhs.BooleanValue
66+
}
67+
if v.ListValue != nil && rhs.ListValue != nil {
68+
return v.ListValue.Equals(rhs.ListValue)
69+
}
70+
if v.MapValue != nil && rhs.MapValue != nil {
71+
return v.MapValue.Equals(rhs.MapValue)
72+
}
73+
if v.Null && rhs.Null {
74+
return true
75+
}
76+
return false
4077
}
4178

4279
// Less provides a total ordering for Value (so that they can be sorted, even
@@ -187,6 +224,20 @@ type List struct {
187224
Items []Value
188225
}
189226

227+
// Equals compares two lists lexically.
228+
func (l *List) Equals(rhs *List) bool {
229+
if len(l.Items) != len(rhs.Items) {
230+
return false
231+
}
232+
233+
for i, lv := range l.Items {
234+
if !lv.Equals(rhs.Items[i]) {
235+
return false
236+
}
237+
}
238+
return true
239+
}
240+
190241
// Less compares two lists lexically.
191242
func (l *List) Less(rhs *List) bool {
192243
i := 0
@@ -244,6 +295,23 @@ func (m *Map) computeOrder() []int {
244295
return m.order
245296
}
246297

298+
// Equals compares two maps lexically.
299+
func (m *Map) Equals(rhs *Map) bool {
300+
if len(m.Items) != len(rhs.Items) {
301+
return false
302+
}
303+
for _, lfield := range m.Items {
304+
rfield, ok := rhs.Get(lfield.Name)
305+
if !ok {
306+
return false
307+
}
308+
if !lfield.Value.Equals(rfield.Value) {
309+
return false
310+
}
311+
}
312+
return true
313+
}
314+
247315
// Less compares two maps lexically.
248316
func (m *Map) Less(rhs *Map) bool {
249317
var noAllocL, noAllocR [2]int

0 commit comments

Comments
 (0)