github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/key/composite.go (about)

     1  // Copyright (c) 2016 Arista Networks, Inc.
     2  // Use of this source code is governed by the Apache License 2.0
     3  // that can be found in the COPYING file.
     4  
     5  package key
     6  
     7  // HashInterface computes the hash of a Key
     8  func HashInterface(v interface{}) uintptr {
     9  	if vv, ok := v.(Key); ok {
    10  		v = vv.Key()
    11  	}
    12  	switch v := v.(type) {
    13  	case map[string]interface{}:
    14  		return hashMapString(v)
    15  	case []interface{}:
    16  		return hashSlice(v)
    17  	case []byte:
    18  		return HashInterface(string(v))
    19  	case Pointer:
    20  		// This case applies to pointers used
    21  		// as values in maps or slices (i.e.
    22  		// not wrapped in a key).
    23  		return hashSlice(pointerToSlice(v))
    24  	case Path:
    25  		// This case applies to paths used
    26  		// as values in maps or slices (i.e
    27  		// not wrapped in a kay).
    28  		return hashSlice(pathToSlice(v))
    29  	case Hashable:
    30  		return uintptr(v.Hash())
    31  	default:
    32  		return _nilinterhash(v)
    33  	}
    34  }
    35  
    36  func hashMapString(m map[string]interface{}) uintptr {
    37  	h := uintptr(31 * (len(m) + 1))
    38  	for k, v := range m {
    39  		// Use addition so that the order of iteration doesn't matter.
    40  		h += _strhash(k)
    41  		h += HashInterface(v)
    42  	}
    43  	return h
    44  }
    45  
    46  func hashSlice(s []interface{}) uintptr {
    47  	h := uintptr(31 * (len(s) + 1))
    48  	for _, v := range s {
    49  		h += HashInterface(v)
    50  	}
    51  	return h
    52  }