Skip to content

Commit

Permalink
tpl/collections: Use SetIterKey/SetIterValue for Where, Sort and Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Jan 12, 2025
1 parent a3a651f commit 2db0a95
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 10 deletions.
18 changes: 13 additions & 5 deletions tpl/collections/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ func caseInsensitiveLookup(m, k reflect.Value) (reflect.Value, bool) {
return v, hreflect.IsTruthfulValue(v)
}

k2 := reflect.New(m.Type().Key()).Elem()

iter := m.MapRange()
for iter.Next() {
k2 := iter.Key()
k2.SetIterKey(iter)
if strings.EqualFold(k.String(), k2.String()) {
return iter.Value(), true
}
Expand All @@ -92,20 +94,26 @@ func mergeMap(dst, src reflect.Value) reflect.Value {
// If the destination is Params, we must lower case all keys.
_, lowerCase := dst.Interface().(maps.Params)

k := reflect.New(dst.Type().Key()).Elem()
v := reflect.New(dst.Type().Elem()).Elem()

// Copy the destination map.
iter := dst.MapRange()
for iter.Next() {
k := iter.Key()
v := iter.Value()
k.SetIterKey(iter)
v.SetIterValue(iter)
out.SetMapIndex(k, v)
}

// Add all keys in src not already in destination.
// Maps of the same type will be merged.
k = reflect.New(src.Type().Key()).Elem()
sv := reflect.New(src.Type().Elem()).Elem()

iter = src.MapRange()
for iter.Next() {
k := iter.Key()
sv := iter.Value()
k.SetIterKey(iter)
sv.SetIterValue(iter)
dv, found := caseInsensitiveLookup(dst, k)

if found {
Expand Down
7 changes: 5 additions & 2 deletions tpl/collections/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,14 @@ func (ns *Namespace) Sort(ctx context.Context, l any, args ...any) (any, error)
}

case reflect.Map:
key := reflect.New(seqv.Type().Key()).Elem()
value := reflect.New(seqv.Type().Elem()).Elem()

iter := seqv.MapRange()
i := 0
for iter.Next() {
key := iter.Key()
value := iter.Value()
key.SetIterKey(iter)
value.SetIterValue(iter)
p.Pairs[i].Value = value
if sortByField == "" {
p.Pairs[i].Key = key
Expand Down
6 changes: 4 additions & 2 deletions tpl/collections/where.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,12 @@ func (ns *Namespace) checkWhereArray(ctxv, seqv, kv, mv reflect.Value, path []st
// checkWhereMap handles the where-matching logic when the seqv value is a Map.
func (ns *Namespace) checkWhereMap(ctxv, seqv, kv, mv reflect.Value, path []string, op string) (any, error) {
rv := reflect.MakeMap(seqv.Type())
k := reflect.New(seqv.Type().Key()).Elem()
elemv := reflect.New(seqv.Type().Elem()).Elem()
iter := seqv.MapRange()
for iter.Next() {
k := iter.Key()
elemv := iter.Value()
k.SetIterKey(iter)
elemv.SetIterValue(iter)
switch elemv.Kind() {
case reflect.Array, reflect.Slice:
r, err := ns.checkWhereArray(ctxv, elemv, kv, mv, path, op)
Expand Down
6 changes: 5 additions & 1 deletion tpl/internal/go_templates/fmtsort/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ func Sort(mapValue reflect.Value) SortedMap {
// yelling loudly if that happens. See issue 33275.
n := mapValue.Len()
sorted := make(SortedMap, 0, n)
k := reflect.New(mapValue.Type().Key()).Elem()
v := reflect.New(mapValue.Type().Elem()).Elem()
iter := mapValue.MapRange()
for iter.Next() {
sorted = append(sorted, KeyValue{iter.Key(), iter.Value()})
k.SetIterKey(iter)
v.SetIterValue(iter)
sorted = append(sorted, KeyValue{k, v})
}
slices.SortStableFunc(sorted, func(a, b KeyValue) int {
return compare(a.Key, b.Key)
Expand Down

0 comments on commit 2db0a95

Please sign in to comment.