github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/mmhash/hash.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package mmhash
    19  
    20  import "unsafe"
    21  
    22  //go:noescape
    23  //go:linkname memhash runtime.memhash
    24  func memhash(p unsafe.Pointer, h, s uintptr) uintptr
    25  
    26  type stringStruct struct {
    27  	str unsafe.Pointer
    28  	len int
    29  }
    30  
    31  func Sum64(data []byte) uint64 {
    32  	ss := (*stringStruct)(unsafe.Pointer(&data))
    33  	return uint64(memhash(ss.str, 0, uintptr(ss.len)))
    34  }
    35  
    36  func Hash(b []byte) uint32 {
    37  	const (
    38  		seed = 0xbc9f1d34
    39  		m    = 0xc6a4a793
    40  	)
    41  	h := uint32(seed) ^ uint32(len(b))*m
    42  	for ; len(b) >= 4; b = b[4:] {
    43  		h += uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
    44  		h *= m
    45  		h ^= h >> 16
    46  	}
    47  	switch len(b) {
    48  	case 3:
    49  		h += uint32(b[2]) << 16
    50  		fallthrough
    51  	case 2:
    52  		h += uint32(b[1]) << 8
    53  		fallthrough
    54  	case 1:
    55  		h += uint32(b[0])
    56  		h *= m
    57  		h ^= h >> 24
    58  	}
    59  	return h
    60  }