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  }