2018-02-15 17:14:05 +08:00
|
|
|
package vals
|
2018-01-25 07:28:50 +08:00
|
|
|
|
2018-01-28 01:26:22 +08:00
|
|
|
import (
|
|
|
|
"github.com/xiaq/persistent/hash"
|
|
|
|
)
|
2018-01-25 09:40:15 +08:00
|
|
|
|
2018-01-25 07:57:58 +08:00
|
|
|
// Hasher wraps the Hash method.
|
|
|
|
type Hasher interface {
|
|
|
|
// Hash computes the hash code of the receiver.
|
|
|
|
Hash() uint32
|
|
|
|
}
|
|
|
|
|
2018-01-27 23:51:37 +08:00
|
|
|
// Hash returns the 32-bit hash of a value. It is implemented for the builtin
|
2019-04-19 19:24:45 +08:00
|
|
|
// types bool and string, the List and Map types, and types satisfying the
|
2018-01-29 22:36:43 +08:00
|
|
|
// Hasher interface. For other values, it returns 0 (which is OK in terms of
|
2018-01-28 01:26:22 +08:00
|
|
|
// correctness).
|
2018-01-25 07:28:50 +08:00
|
|
|
func Hash(v interface{}) uint32 {
|
2018-01-25 09:40:15 +08:00
|
|
|
switch v := v.(type) {
|
2018-01-27 23:51:37 +08:00
|
|
|
case bool:
|
|
|
|
if v {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return 0
|
2019-04-19 08:03:56 +08:00
|
|
|
case string:
|
|
|
|
return hash.String(v)
|
2019-04-19 19:24:45 +08:00
|
|
|
case List:
|
2018-01-28 01:26:22 +08:00
|
|
|
h := hash.DJBInit
|
|
|
|
for it := v.Iterator(); it.HasElem(); it.Next() {
|
|
|
|
h = hash.DJBCombine(h, Hash(it.Elem()))
|
|
|
|
}
|
|
|
|
return h
|
2019-04-19 19:24:45 +08:00
|
|
|
case Map:
|
2018-01-29 22:36:43 +08:00
|
|
|
h := hash.DJBInit
|
|
|
|
for it := v.Iterator(); it.HasElem(); it.Next() {
|
|
|
|
k, v := it.Elem()
|
|
|
|
h = hash.DJBCombine(h, Hash(k))
|
|
|
|
h = hash.DJBCombine(h, Hash(v))
|
|
|
|
}
|
|
|
|
return h
|
2018-01-25 09:40:15 +08:00
|
|
|
case Hasher:
|
|
|
|
return v.Hash()
|
2018-01-25 07:57:58 +08:00
|
|
|
}
|
|
|
|
return 0
|
2018-01-25 07:28:50 +08:00
|
|
|
}
|