sigs.k8s.io/kueue@v0.6.2/pkg/util/maps/maps.go (about)

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // replacing this with `https://pkg.go.dev/golang.org/x/exp/maps` should be considered
    18  // when `x/exp/maps` graduates to stable.
    19  package maps
    20  
    21  import (
    22  	"fmt"
    23  	"maps"
    24  )
    25  
    26  // Merge merges a and b while resolving the conflicts by calling commonKeyValue
    27  func Merge[K comparable, V any, S ~map[K]V](a, b S, commonKeyValue func(a, b V) V) S {
    28  	if a == nil {
    29  		return maps.Clone(b)
    30  	}
    31  
    32  	ret := maps.Clone(a)
    33  
    34  	for k, v := range b {
    35  		if _, found := a[k]; found {
    36  			ret[k] = commonKeyValue(a[k], v)
    37  		} else {
    38  			ret[k] = v
    39  		}
    40  	}
    41  	return ret
    42  }
    43  
    44  // Intersect returns the intersection of a and b with the values generated by calling commonKeyValue
    45  func Intersect[K comparable, V any, M ~map[K]V](a, b M, commonKeyValue func(a, b V) V) M {
    46  	if a == nil || b == nil {
    47  		return nil
    48  	}
    49  
    50  	ret := make(M)
    51  
    52  	for k, v := range b {
    53  		if _, found := a[k]; found {
    54  			ret[k] = commonKeyValue(a[k], v)
    55  		}
    56  	}
    57  	return ret
    58  }
    59  
    60  // MergeKeepFirst merges a and b keeping the values in a in case of conflict
    61  func MergeKeepFirst[K comparable, V any, S ~map[K]V](a, b S) S {
    62  	return Merge(a, b, func(v, _ V) V { return v })
    63  }
    64  
    65  // HaveConflict checks if a and b have the same key, but different value
    66  func HaveConflict[K comparable, V comparable, S ~map[K]V](a, b S) error {
    67  	for k, av := range a {
    68  		if bv, found := b[k]; found && av != bv {
    69  			return fmt.Errorf("conflict for key=%v, value1=%v, value2=%v", k, av, bv)
    70  		}
    71  	}
    72  	return nil
    73  }
    74  
    75  // Contains returns true if a contains all the keys in b with the same value
    76  func Contains[K, V comparable, A ~map[K]V, B ~map[K]V](a A, b B) bool {
    77  	for k, bv := range b {
    78  		if av, found := a[k]; !found || av != bv {
    79  			return false
    80  		}
    81  	}
    82  	return true
    83  }
    84  
    85  // Keys returns a slice containing the m keys
    86  func Keys[K comparable, V any, M ~map[K]V](m M) []K {
    87  	if m == nil {
    88  		return nil
    89  	}
    90  	ret := make([]K, 0, len(m))
    91  
    92  	for k := range m {
    93  		ret = append(ret, k)
    94  	}
    95  	return ret
    96  }