// 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 hashing

import (
	
	
	

	
)

func hash[ fixedLenMemoTypes]( ,  uint64) uint64 {
	switch v := any().(type) {
	case int8:
		return hashInt(uint64(), )
	case uint8:
		return hashInt(uint64(), )
	case int16:
		return hashInt(uint64(), )
	case uint16:
		return hashInt(uint64(), )
	case int32:
		return hashInt(uint64(), )
	case uint32:
		return hashInt(uint64(), )
	case int64:
		return hashInt(uint64(), )
	case uint64:
		return hashInt(, )
	case float32:
		if math.IsNaN(float64()) {
			return hashFloat32(float32(math.NaN()), )
		}
		return hashFloat32(, )
	case float64:
		if math.IsNaN() {
			return hashFloat64(math.NaN(), )
		}
		return hashFloat64(, )
	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.
	return bits.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)
	return 4 ^  ^ 
}

func hashFloat64( float64,  uint64) uint64 {
	 := *(*[8]byte)(unsafe.Pointer(&))
	 := hashInt(uint64(*(*uint32)(unsafe.Pointer(&[4]))), )
	 := hashInt(uint64(*(*uint32)(unsafe.Pointer(&[0]))), ^1)
	return 8 ^  ^ 
}

// prime constants used for slightly increasing the hash quality further
var 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)
			return uint64() ^  ^ 
		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)
			return uint64() ^  ^ 
		case  > 0:
			 := uint32(( << 24) ^ (uint32([0]) << 16) ^ (uint32([/2]) << 8) ^ uint32([-1]))
			return hashInt(uint64(), )
		case  == 0:
			return 1
		}
	}

	// increase differentiation enough to improve hash quality
	return xxh3.Hash() + exprimes[]
}