@@ -17,6 +17,7 @@ limitations under the License.
17
17
package fieldpath
18
18
19
19
import (
20
+ "sort"
20
21
"strings"
21
22
)
22
23
@@ -172,24 +173,29 @@ type setNode struct {
172
173
173
174
// SetNodeMap is a map of PathElement to subset.
174
175
type SetNodeMap struct {
175
- members map [ string ]setNode
176
+ members [ ]setNode
176
177
}
177
178
178
179
// Descend adds pe to the set if necessary, returning the associated subset.
179
180
func (s * SetNodeMap ) Descend (pe PathElement ) * Set {
180
- serialized := pe .String ()
181
- if s .members == nil {
182
- s .members = map [string ]setNode {}
181
+ loc := sort .Search (len (s .members ), func (i int ) bool {
182
+ return ! s .members [i ].pathElement .Less (pe )
183
+ })
184
+ if loc == len (s .members ) {
185
+ s .members = append (s .members , setNode {pathElement : pe , set : & Set {}})
186
+ return s .members [loc ].set
183
187
}
184
- if n , ok := s .members [serialized ]; ok {
185
- return n .set
188
+ if s .members [loc ]. pathElement . Equal ( pe ) {
189
+ return s . members [ loc ] .set
186
190
}
187
- ss := & Set {}
188
- s .members [serialized ] = setNode {
189
- pathElement : pe ,
190
- set : ss ,
191
+ n := len (s .members ) - 1
192
+ s .members = append (s .members , s .members [n ])
193
+ for n > loc {
194
+ s .members [n ] = s .members [n - 1 ]
195
+ n --
191
196
}
192
- return ss
197
+ s .members [loc ] = setNode {pathElement : pe , set : & Set {}}
198
+ return s .members [loc ].set
193
199
}
194
200
195
201
// Size returns the sum of the number of members of all subsets.
@@ -213,12 +219,14 @@ func (s *SetNodeMap) Empty() bool {
213
219
214
220
// Get returns (the associated set, true) or (nil, false) if there is none.
215
221
func (s * SetNodeMap ) Get (pe PathElement ) (* Set , bool ) {
216
- if s .members == nil {
222
+ loc := sort .Search (len (s .members ), func (i int ) bool {
223
+ return ! s .members [i ].pathElement .Less (pe )
224
+ })
225
+ if loc == len (s .members ) {
217
226
return nil , false
218
227
}
219
- serialized := pe .String ()
220
- if n , ok := s .members [serialized ]; ok {
221
- return n .set , true
228
+ if s .members [loc ].pathElement .Equal (pe ) {
229
+ return s .members [loc ].set , true
222
230
}
223
231
return nil , false
224
232
}
@@ -229,12 +237,11 @@ func (s *SetNodeMap) Equals(s2 *SetNodeMap) bool {
229
237
if len (s .members ) != len (s2 .members ) {
230
238
return false
231
239
}
232
- for k , v := range s .members {
233
- v2 , ok := s2 .members [k ]
234
- if ! ok {
240
+ for i := range s .members {
241
+ if ! s .members [i ].pathElement .Equal (s2 .members [i ].pathElement ) {
235
242
return false
236
243
}
237
- if ! v . set .Equals (v2 .set ) {
244
+ if ! s . members [ i ]. set .Equals (s2 . members [ i ] .set ) {
238
245
return false
239
246
}
240
247
}
@@ -244,35 +251,49 @@ func (s *SetNodeMap) Equals(s2 *SetNodeMap) bool {
244
251
// Union returns a SetNodeMap with members that appear in either s or s2.
245
252
func (s * SetNodeMap ) Union (s2 * SetNodeMap ) * SetNodeMap {
246
253
out := & SetNodeMap {}
247
- for k , sn := range s .members {
248
- pe := sn .pathElement
249
- if sn2 , ok := s2 .members [k ]; ok {
250
- * out .Descend (pe ) = * sn .set .Union (sn2 .set )
254
+
255
+ i , j := 0 , 0
256
+ for i < len (s .members ) && j < len (s2 .members ) {
257
+ if s .members [i ].pathElement .Less (s2 .members [j ].pathElement ) {
258
+ out .members = append (out .members , s .members [i ])
259
+ i ++
251
260
} else {
252
- * out .Descend (pe ) = * sn .set
261
+ if ! s2 .members [j ].pathElement .Less (s .members [i ].pathElement ) {
262
+ out .members = append (out .members , setNode {pathElement : s .members [i ].pathElement , set : s .members [i ].set .Union (s2 .members [j ].set )})
263
+ i ++
264
+ } else {
265
+ out .members = append (out .members , s2 .members [j ])
266
+ }
267
+ j ++
253
268
}
254
269
}
255
- for k , sn2 := range s2 .members {
256
- pe := sn2 .pathElement
257
- if _ , ok := s .members [k ]; ok {
258
- // already handled
259
- continue
260
- }
261
- * out .Descend (pe ) = * sn2 .set
270
+
271
+ if i < len (s .members ) {
272
+ out .members = append (out .members , s .members [i :]... )
273
+ }
274
+ if j < len (s2 .members ) {
275
+ out .members = append (out .members , s2 .members [j :]... )
262
276
}
263
277
return out
264
278
}
265
279
266
280
// Intersection returns a SetNodeMap with members that appear in both s and s2.
267
281
func (s * SetNodeMap ) Intersection (s2 * SetNodeMap ) * SetNodeMap {
268
282
out := & SetNodeMap {}
269
- for k , sn := range s .members {
270
- pe := sn .pathElement
271
- if sn2 , ok := s2 .members [k ]; ok {
272
- i := * sn .set .Intersection (sn2 .set )
273
- if ! i .Empty () {
274
- * out .Descend (pe ) = i
283
+
284
+ i , j := 0 , 0
285
+ for i < len (s .members ) && j < len (s2 .members ) {
286
+ if s .members [i ].pathElement .Less (s2 .members [j ].pathElement ) {
287
+ i ++
288
+ } else {
289
+ if ! s2 .members [j ].pathElement .Less (s .members [i ].pathElement ) {
290
+ res := s .members [i ].set .Intersection (s2 .members [j ].set )
291
+ if ! res .Empty () {
292
+ out .members = append (out .members , setNode {pathElement : s .members [i ].pathElement , set : res })
293
+ }
294
+ i ++
275
295
}
296
+ j ++
276
297
}
277
298
}
278
299
return out
@@ -281,18 +302,30 @@ func (s *SetNodeMap) Intersection(s2 *SetNodeMap) *SetNodeMap {
281
302
// Difference returns a SetNodeMap with members that appear in s but not in s2.
282
303
func (s * SetNodeMap ) Difference (s2 * Set ) * SetNodeMap {
283
304
out := & SetNodeMap {}
284
- for k , sn := range s .members {
285
- pe := sn .pathElement
286
- if sn2 , ok := s2 .Children .members [k ]; ok {
287
- diff := * sn .set .Difference (sn2 .set )
288
- // We aren't permitted to add nodes with no elements.
289
- if ! diff .Empty () {
290
- * out .Descend (pe ) = diff
291
- }
305
+
306
+ i , j := 0 , 0
307
+ for i < len (s .members ) && j < len (s2 .Children .members ) {
308
+ if s .members [i ].pathElement .Less (s2 .Children .members [j ].pathElement ) {
309
+ out .members = append (out .members , setNode {pathElement : s .members [i ].pathElement , set : s .members [i ].set })
310
+ i ++
292
311
} else {
293
- * out .Descend (pe ) = * sn .set
312
+ if ! s2 .Children .members [j ].pathElement .Less (s .members [i ].pathElement ) {
313
+
314
+ diff := s .members [i ].set .Difference (s2 .Children .members [j ].set )
315
+ // We aren't permitted to add nodes with no elements.
316
+ if ! diff .Empty () {
317
+ out .members = append (out .members , setNode {pathElement : s .members [i ].pathElement , set : diff })
318
+ }
319
+
320
+ i ++
321
+ }
322
+ j ++
294
323
}
295
324
}
325
+
326
+ if i < len (s .members ) {
327
+ out .members = append (out .members , s .members [i :]... )
328
+ }
296
329
return out
297
330
}
298
331
0 commit comments