github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/cmds/core/elvish/eval/vals/hash.go (about)

     1  package vals
     2  
     3  import (
     4  	"github.com/u-root/u-root/cmds/core/elvish/hash"
     5  )
     6  
     7  // Hasher wraps the Hash method.
     8  type Hasher interface {
     9  	// Hash computes the hash code of the receiver.
    10  	Hash() uint32
    11  }
    12  
    13  // Hash returns the 32-bit hash of a value. It is implemented for the builtin
    14  // types bool and string, and types satisfying the listHashable, mapHashable or
    15  // Hasher interface. For other values, it returns 0 (which is OK in terms of
    16  // correctness).
    17  func Hash(v interface{}) uint32 {
    18  	switch v := v.(type) {
    19  	case bool:
    20  		if v {
    21  			return 1
    22  		}
    23  		return 0
    24  	case listHashable:
    25  		h := hash.DJBInit
    26  		for it := v.Iterator(); it.HasElem(); it.Next() {
    27  			h = hash.DJBCombine(h, Hash(it.Elem()))
    28  		}
    29  		return h
    30  	case mapIterable:
    31  		h := hash.DJBInit
    32  		for it := v.Iterator(); it.HasElem(); it.Next() {
    33  			k, v := it.Elem()
    34  			h = hash.DJBCombine(h, Hash(k))
    35  			h = hash.DJBCombine(h, Hash(v))
    36  		}
    37  		return h
    38  	case string:
    39  		return hash.Hash(v)
    40  	case Hasher:
    41  		return v.Hash()
    42  	}
    43  	return 0
    44  }
    45  
    46  type listHashable listIterable
    47  type mapHashable mapIterable