Integer hash function for concurrent map implementation golang

724 views Asked by At

I am using concurrent map from this repo which only uses string as the key and it doesn't have any implementation for key as integer so I tried implementing it by just replacing all string into int64 and modify the hashing function.

Here is the gist for that where key is integer. Below is how I am hashing int64 keys. Is this the right way to hash an int64 to get the right shard?

// GetShard returns shard under given key
func (m ConcurrentMap[V]) GetShard(key int64) *ConcurrentMapShared[V] {
    // I assume the hashing function of Go's map is good enough
    return m[key%int64(SHARD_COUNT)]
}

When I run this code I am getting - panic: runtime error: index out of range [-7] on my above return line in GetShard function.

Is there anything wrong in my hashing function implementation? Any example on what hashing algorithm to use here with my code will help me understand better.

Do I need to use murmurhash3 here on the key and then do mod on that? If yes, any example will be appreciated.

Update

So I should change my above GetShard method to like this -

// GetShard returns shard under given key
func (m ConcurrentMap) GetShard(key int64) *ConcurrentMapShared {
    var h maphash.Hash
    // what is the seed value I should pass here?
    h.SetSeed(seed)
    binary.Write(&h, binary.LittleEndian, key)
    return m[h.Sum64()%uint64(SHARD_COUNT)]
}
1

There are 1 answers

9
VonC On

You can check out for comparison puzpuzpuz/xsync#Map

m := xsync.NewMapOf[int64]()
m.Store(1, "bar")
v, ok := m.Load(1)

Its hashUint64 calculates a hash of K (IntegerConstraint) with the given seed.

// hashUint64 calculates a hash of v with the given seed.
//
//lint:ignore U1000 used in MapOf
func hashUint64[K IntegerConstraint](seed maphash.Seed, k K) uint64 {
    n := uint64(k)
    // Java's Long standard hash function.
    n = n ^ (n >> 32)
    nseed := *(*uint64)(unsafe.Pointer(&seed))
    // 64-bit variation of boost's hash_combine.
    nseed ^= n + 0x9e3779b97f4a7c15 + (nseed << 12) + (nseed >> 4)
    return nseed
}

Used by NewTypedMapOf[K comparable, V any](hasher func(maphash.Seed, K) uint64) *MapOf[K, V]

Keys are hashed to uint64 using the hasher function. It is strongly recommended to use the hash/maphash package to implement hasher.
See example.