github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/persistent/hash/hash.go (about)

     1  // Package hash contains some common hash functions suitable for use in hash
     2  // maps.
     3  package hash
     4  
     5  import "unsafe"
     6  
     7  const DJBInit uint32 = 5381
     8  
     9  func DJBCombine(acc, h uint32) uint32 {
    10  	return mul33(acc) + h
    11  }
    12  
    13  func DJB(hs ...uint32) uint32 {
    14  	acc := DJBInit
    15  	for _, h := range hs {
    16  		acc = DJBCombine(acc, h)
    17  	}
    18  	return acc
    19  }
    20  
    21  func UInt32(u uint32) uint32 {
    22  	return u
    23  }
    24  
    25  func UInt64(u uint64) uint32 {
    26  	return mul33(uint32(u>>32)) + uint32(u&0xffffffff)
    27  }
    28  
    29  func Pointer(p unsafe.Pointer) uint32 {
    30  	switch unsafe.Sizeof(p) {
    31  	case 4:
    32  		return UInt32(uint32(uintptr(p)))
    33  	case 8:
    34  		return UInt64(uint64(uintptr(p)))
    35  	default:
    36  		panic("unhandled pointer size")
    37  	}
    38  }
    39  
    40  func UIntPtr(p uintptr) uint32 {
    41  	switch unsafe.Sizeof(p) {
    42  	case 4:
    43  		return UInt32(uint32(p))
    44  	case 8:
    45  		return UInt64(uint64(p))
    46  	default:
    47  		panic("unhandled pointer size")
    48  	}
    49  }
    50  
    51  func String(s string) uint32 {
    52  	h := DJBInit
    53  	for i := 0; i < len(s); i++ {
    54  		h = DJBCombine(h, uint32(s[i]))
    55  	}
    56  	return h
    57  }
    58  
    59  func mul33(u uint32) uint32 {
    60  	return u<<5 + u
    61  }