// Licensed to the Apache Software Foundation (ASF) under one// or more contributor license agreements. See the NOTICE file// distributed with this work for additional information// regarding copyright ownership. The ASF licenses this file// to you under the Apache License, Version 2.0 (the// "License"); you may not use this file except in compliance// with the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.package hashingimport ()func hash[ fixedLenMemoTypes]( , uint64) uint64 {switch v := any().(type) {caseint8:returnhashInt(uint64(), )caseuint8:returnhashInt(uint64(), )caseint16:returnhashInt(uint64(), )caseuint16:returnhashInt(uint64(), )caseint32:returnhashInt(uint64(), )caseuint32:returnhashInt(uint64(), )caseint64:returnhashInt(uint64(), )caseuint64:returnhashInt(, )casefloat32:ifmath.IsNaN(float64()) {returnhashFloat32(float32(math.NaN()), ) }returnhashFloat32(, )casefloat64:ifmath.IsNaN() {returnhashFloat64(math.NaN(), ) }returnhashFloat64(, )default:panic("unsupported type for hashing") }}func hashInt( uint64, uint64) uint64 {// Two of xxhash's prime multipliers (which are chosen for their // bit dispersion properties)var = [2]uint64{11400714785074694791, 14029467366897019727}// Multiplying by the prime number mixes the low bits into the high bits, // then byte-swapping (which is a single CPU instruction) allows the // combined high and low bits to participate in the initial hash table index.returnbits.ReverseBytes64([] * )}func hashFloat32( float32, uint64) uint64 {// grab the raw byte pattern of the := *(*[4]byte)(unsafe.Pointer(&)) := uint64(*(*uint32)(unsafe.Pointer(&[0]))) := hashInt(, ) := hashInt(, ^1)return4 ^ ^ }func hashFloat64( float64, uint64) uint64 { := *(*[8]byte)(unsafe.Pointer(&)) := hashInt(uint64(*(*uint32)(unsafe.Pointer(&[4]))), ) := hashInt(uint64(*(*uint32)(unsafe.Pointer(&[0]))), ^1)return8 ^ ^ }// prime constants used for slightly increasing the hash quality furthervar exprimes = [2]uint64{1609587929392839161, 9650029242287828579}// for smaller amounts of bytes this is faster than even calling into// xxh3 to do the Hash, so we specialize in order to get the benefits// of that performance.func ( []byte, uint64) uint64 { := uint32(len())if <= 16 {switch {case > 8:// 8 < length <= 16 // apply same principle as above, but as two 64-bit ints := *(*uint64)(unsafe.Pointer(&[-8])) := *(*uint64)(unsafe.Pointer(&[0])) := hashInt(, ) := hashInt(, ^1)returnuint64() ^ ^ case >= 4:// 4 < length <= 8 // we can read the bytes as two overlapping 32-bit ints, apply different // hash functions to each in parallel // then xor the results := *(*uint32)(unsafe.Pointer(&[-4])) := *(*uint32)(unsafe.Pointer(&[0])) := hashInt(uint64(), ) := hashInt(uint64(), ^1)returnuint64() ^ ^ case > 0: := uint32(( << 24) ^ (uint32([0]) << 16) ^ (uint32([/2]) << 8) ^ uint32([-1]))returnhashInt(uint64(), )case == 0:return1 } }// increase differentiation enough to improve hash qualityreturnxxh3.Hash() + exprimes[]}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.