@@ -16,17 +16,18 @@ import (
16
16
type ResourceSet [T client.Object ] interface {
17
17
// Get the set stored keys
18
18
Keys () sets.Set [string ]
19
- // List of resources stored in the set. Pass an optional filter function to filter on the list.
19
+ // List returns an iterator for the set.
20
+ // Pass an optional filter function to skip iteration on specific entries; Note: index will still progress.
20
21
List (filterResource ... func (T ) bool ) iter.Seq2 [int , T ]
21
22
// Return the Set as a map of key to resource.
22
23
Map () map [string ]T
23
24
// Insert a resource into the set.
24
25
Insert (resource ... T )
25
26
// Compare the equality of the keys in two sets (not the resources themselves)
26
27
Equal (set ResourceSet [T ]) bool
27
- // Check if the set contains a key matching the resource (not the resource itself)
28
+ // Check if the set contains the resource. Uses the compare func to determine equality.
28
29
Has (resource T ) bool
29
- // Delete the key matching the resource
30
+ // Delete the matching resource. Uses the compare func to determine equality.
30
31
Delete (resource T )
31
32
// Return the union with the provided set
32
33
Union (set ResourceSet [T ]) ResourceSet [T ]
@@ -35,15 +36,17 @@ type ResourceSet[T client.Object] interface {
35
36
// Return the intersection with the provided set
36
37
Intersection (set ResourceSet [T ]) ResourceSet [T ]
37
38
// Find the resource with the given ID
38
- Find (id T ) (T , error )
39
+ Find (resource ezkube. ResourceId ) (T , error )
39
40
// Get the length of the set
40
- Length () int
41
+ Len () int
41
42
// returns the generic implementation of the set
42
43
Generic () sk_sets.ResourceSet
43
44
// returns the delta between this and and another ResourceSet[T]
44
45
Delta (newSet ResourceSet [T ]) sk_sets.ResourceDelta
45
46
// Clone returns a deep copy of the set
46
47
Clone () ResourceSet [T ]
48
+ // Get the compare function used by the set
49
+ GetCompareFunc () func (a , b client.Object ) int
47
50
}
48
51
49
52
// ResourceDelta represents the set of changes between two ResourceSets.
@@ -64,18 +67,15 @@ func (r *ResourceDelta[T]) DeltaV1() sk_sets.ResourceDelta {
64
67
type resourceSet [T client.Object ] struct {
65
68
lock sync.RWMutex
66
69
set []T
67
- sortFunc func (toInsert , existing client.Object ) bool
68
70
compareFunc func (a , b client.Object ) int
69
71
}
70
72
71
73
func NewResourceSet [T client.Object ](
72
- sortFunc func (toInsert , existing client.Object ) bool ,
73
74
compareFunc func (a , b client.Object ) int ,
74
75
resources ... T ,
75
76
) ResourceSet [T ] {
76
77
rs := & resourceSet [T ]{
77
78
set : []T {},
78
- sortFunc : sortFunc ,
79
79
compareFunc : compareFunc ,
80
80
}
81
81
rs .Insert (resources ... )
@@ -122,22 +122,18 @@ func (s *resourceSet[T]) Map() map[string]T {
122
122
123
123
// Insert adds items to the set.
124
124
// If an item is already in the set, it is overwritten.
125
- // The set is sorted based on the sortFunc. If sortFunc is nil, the set will be unsorted .
125
+ // The set is sorted based on the compare func .
126
126
func (s * resourceSet [T ]) Insert (resources ... T ) {
127
127
s .lock .RLock ()
128
128
defer s .lock .RUnlock ()
129
129
for _ , resource := range resources {
130
- insertIndex := sort .Search (len (s .set ), func (i int ) bool { return s .sortFunc (resource , s .set [i ]) })
130
+ insertIndex := sort .Search (len (s .set ), func (i int ) bool { return s .compareFunc (resource , s .set [i ]) < 0 })
131
131
132
132
// if the resource is already in the set, replace it
133
133
if insertIndex < len (s .set ) && s .compareFunc (resource , s .set [insertIndex ]) == 0 {
134
134
s .set [insertIndex ] = resource
135
135
return
136
136
}
137
- if s .sortFunc == nil {
138
- s .set = append (s .set , resource )
139
- return
140
- }
141
137
142
138
// insert the resource at the determined index
143
139
s .set = slices .Insert (s .set , insertIndex , resource )
@@ -148,7 +144,7 @@ func (s *resourceSet[T]) Has(resource T) bool {
148
144
s .lock .RLock ()
149
145
defer s .lock .RUnlock ()
150
146
i := sort .Search (len (s .set ), func (i int ) bool {
151
- return ezkube . CompareResourceIds (s .set [i ], resource ) >= 0
147
+ return s . compareFunc (s .set [i ], resource ) >= 0
152
148
})
153
149
return i < len (s .set ) && s .compareFunc (s .set [i ], resource ) == 0
154
150
}
@@ -167,11 +163,9 @@ func (s *resourceSet[T]) Delete(resource T) {
167
163
i := sort .Search (len (s .set ), func (i int ) bool {
168
164
return s .compareFunc (s .set [i ], resource ) >= 0
169
165
})
170
- if found := i < len (s .set ) && s .compareFunc (s .set [i ], resource ) == 0 ; ! found {
171
- return
166
+ if i != len (s .set ) && s .compareFunc (s .set [i ], resource ) == 0 {
167
+ s . set = slices . Delete ( s . set , i , i + 1 )
172
168
}
173
-
174
- s .set = slices .Delete (s .set , i , i + 1 )
175
169
}
176
170
177
171
func (s * resourceSet [T ]) Union (set ResourceSet [T ]) ResourceSet [T ] {
@@ -180,7 +174,6 @@ func (s *resourceSet[T]) Union(set ResourceSet[T]) ResourceSet[T] {
180
174
list = append (list , resource .(T ))
181
175
}
182
176
return NewResourceSet [T ](
183
- s .sortFunc ,
184
177
s .compareFunc ,
185
178
list ... ,
186
179
)
@@ -189,7 +182,7 @@ func (s *resourceSet[T]) Union(set ResourceSet[T]) ResourceSet[T] {
189
182
func (s * resourceSet [T ]) Difference (set ResourceSet [T ]) ResourceSet [T ] {
190
183
s .lock .RLock ()
191
184
defer s .lock .RUnlock ()
192
- result := NewResourceSet [T ](s .sortFunc , s . compareFunc )
185
+ result := NewResourceSet [T ](s .compareFunc )
193
186
for _ , resource := range s .set {
194
187
if ! set .Has (resource ) {
195
188
result .Insert (resource )
@@ -202,13 +195,13 @@ func (s *resourceSet[T]) Intersection(set ResourceSet[T]) ResourceSet[T] {
202
195
s .lock .RLock ()
203
196
defer s .lock .RUnlock ()
204
197
var walk , other ResourceSet [T ]
205
- result := NewResourceSet [T ](s .sortFunc , s . compareFunc )
206
- if len (s .set ) < set .Length () {
207
- walk = NewResourceSet (s .sortFunc , s . compareFunc , s .set ... )
198
+ result := NewResourceSet [T ](s .compareFunc )
199
+ if len (s .set ) < set .Len () {
200
+ walk = NewResourceSet (s .compareFunc , s .set ... )
208
201
other = set
209
202
} else {
210
203
walk = set
211
- other = NewResourceSet (s .sortFunc , s . compareFunc , s .set ... )
204
+ other = NewResourceSet (s .compareFunc , s .set ... )
212
205
}
213
206
for _ , key := range walk .List () {
214
207
if other .Has (key ) {
@@ -218,33 +211,31 @@ func (s *resourceSet[T]) Intersection(set ResourceSet[T]) ResourceSet[T] {
218
211
return result
219
212
}
220
213
221
- func (s * resourceSet [T ]) Find (id T ) (T , error ) {
214
+ // this is only possible when the compare func is ezkube.ResourceIdsCompare
215
+ // otherwise the set won't be sorted to allow for binary search
216
+ func (s * resourceSet [T ]) Find (resource ezkube.ResourceId ) (T , error ) {
222
217
s .lock .RLock ()
223
218
defer s .lock .RUnlock ()
224
- key := sk_sets .Key (id )
219
+ desired_key := sk_sets .Key (resource )
225
220
i := sort .Search (len (s .set ), func (i int ) bool {
226
- return key <= sk_sets .Key (s .set [i ])
221
+ return sk_sets .Key (s .set [i ]) >= desired_key
227
222
})
228
- var resource T
229
- if i < len (s .set ) {
230
- resource = s .set [i ]
231
- }
232
- if i != len (s .set ) && sk_sets .Key (resource ) == key {
233
- return resource , nil
223
+ var found T
224
+ if i < len (s .set ) && sk_sets .Key (s .set [i ]) == desired_key {
225
+ return s .set [i ], nil
234
226
}
235
-
236
- return resource , sk_sets .NotFoundErr (resource , id )
227
+ return found , sk_sets .NotFoundErr (found , resource )
237
228
}
238
229
239
- func (s * resourceSet [T ]) Length () int {
230
+ func (s * resourceSet [T ]) Len () int {
240
231
s .lock .RLock ()
241
232
defer s .lock .RUnlock ()
242
233
return len (s .set )
243
234
}
244
235
245
236
// note that this function will currently panic if called for a ResourceSet[T] containing non-runtime.Objects
246
237
func (oldSet * resourceSet [T ]) Delta (newSet ResourceSet [T ]) sk_sets.ResourceDelta {
247
- updated , removed := NewResourceSet [T ](oldSet .sortFunc , oldSet . compareFunc ), NewResourceSet [T ](oldSet . sortFunc , oldSet .compareFunc )
238
+ updated , removed := NewResourceSet [T ](oldSet .compareFunc ), NewResourceSet [T ](oldSet .compareFunc )
248
239
249
240
// find objects updated or removed
250
241
for _ , resource := range oldSet .set {
@@ -279,25 +270,26 @@ func (oldSet *resourceSet[T]) Delta(newSet ResourceSet[T]) sk_sets.ResourceDelta
279
270
// Create a clone of the current set
280
271
// note that this function will currently panic if called for a ResourceSet[T] containing non-runtime.Objects
281
272
func (oldSet * resourceSet [T ]) Clone () ResourceSet [T ] {
282
- new := NewResourceSet [T ](oldSet .sortFunc , oldSet .compareFunc )
283
- oldSet .List (func (oldObj T ) bool {
273
+ new := NewResourceSet [T ](oldSet .compareFunc )
274
+
275
+ for _ , oldObj := range oldSet .List () {
284
276
copy := oldObj .DeepCopyObject ().(T )
285
277
new .Insert (copy )
286
- return true
287
- })
278
+ }
288
279
return new
289
280
}
290
281
291
282
func (s * resourceSet [T ]) Generic () sk_sets.ResourceSet {
292
- genericSortFunc := func (toInsert , existing interface {}) bool {
293
- return s .sortFunc (toInsert .(T ), existing .(T ))
294
- }
295
283
genericCompareFunc := func (a , b interface {}) int {
296
284
return s .compareFunc (a .(T ), b .(T ))
297
285
}
298
- set := sk_sets .NewResourceSet (genericSortFunc , genericCompareFunc )
286
+ set := sk_sets .NewResourceSet (nil , genericCompareFunc )
299
287
for _ , v := range s .List () {
300
288
set .Insert (v )
301
289
}
302
290
return set
303
291
}
292
+
293
+ func (s * resourceSet [T ]) GetCompareFunc () func (a , b client.Object ) int {
294
+ return s .compareFunc
295
+ }
0 commit comments