github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/container/concurrent_map/string_key.go (about) 1 package concurrent_map 2 3 import "unsafe" 4 5 // StringKey is for the string type key 6 type StringKey struct { 7 value string 8 } 9 10 const ( 11 c1_32 uint32 = 0xcc9e2d51 12 c2_32 uint32 = 0x1b873593 13 ) 14 15 func hash(str string) uint32 { 16 data := ([]byte)(str) 17 var h1 uint32 = 37 18 19 nblocks := len(data) / 4 20 var p uintptr 21 if len(data) > 0 { 22 p = uintptr(unsafe.Pointer(&data[0])) 23 } 24 25 p1 := p + uintptr(4*nblocks) 26 for ; p < p1; p += 4 { 27 k1 := *(*uint32)(unsafe.Pointer(p)) 28 k1 *= c1_32 29 k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 30 k1 *= c2_32 31 32 h1 ^= k1 33 h1 = (h1 << 13) | (h1 >> 19) // rotl32(h1, 13) 34 h1 = h1*5 + 0xe6546b64 35 } 36 37 tail := data[nblocks*4:] 38 39 var k1 uint32 40 switch len(tail) & 3 { 41 case 3: 42 k1 ^= uint32(tail[2]) << 16 43 fallthrough 44 case 2: 45 k1 ^= uint32(tail[1]) << 8 46 fallthrough 47 case 1: 48 k1 ^= uint32(tail[0]) 49 k1 *= c1_32 50 k1 = (k1 << 15) | (k1 >> 17) // rotl32(k1, 15) 51 k1 *= c2_32 52 h1 ^= k1 53 } 54 55 h1 ^= uint32(len(data)) 56 57 h1 ^= h1 >> 16 58 h1 *= 0x85ebca6b 59 h1 ^= h1 >> 13 60 h1 *= 0xc2b2ae35 61 h1 ^= h1 >> 16 62 63 return (h1 << 24) | (((h1 >> 8) << 16) & 0xFF0000) | (((h1 >> 16) << 8) & 0xFF00) | (h1 >> 24) 64 } 65 66 // PartitionID is created by string's hash 67 func (s *StringKey) PartitionKey() int64 { 68 return int64(hash(s.value)) 69 } 70 71 // Value is the raw string 72 func (s *StringKey) Value() interface{} { 73 return s.value 74 } 75 76 // StrKey is to convert a string to StringKey 77 func StrKey(key string) *StringKey { 78 return &StringKey{key} 79 }