From ff237432b9d9c5d65f7125562fd66d17edb76940 Mon Sep 17 00:00:00 2001 From: Jaskaran Veer Singh Date: Wed, 15 Dec 2021 10:24:36 -0500 Subject: [PATCH] Replace math/rand with crypto/rand in cuckoo (#62) * Seed math/rand with crypto/rand for performance Co-authored-by: Jaskaran Veer Singh --- internal/cuckoo/cuckoo.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/internal/cuckoo/cuckoo.go b/internal/cuckoo/cuckoo.go index 7b80330..d20f680 100644 --- a/internal/cuckoo/cuckoo.go +++ b/internal/cuckoo/cuckoo.go @@ -2,6 +2,8 @@ package cuckoo import ( "bytes" + crand "crypto/rand" + "encoding/binary" "fmt" "math/rand" @@ -79,10 +81,23 @@ type Cuckoo struct { } // NewCuckoo instantiates a Cuckoo struct with a bucket of size Factor * size, -// and a CuckooHasher for the 3-way cuckoo hashing. +// seeds math/rand with a random seed, returns a CuckooHasher for the 3-way +// cuckoo hashing. func NewCuckoo(size uint64, seeds [Nhash][]byte) *Cuckoo { cuckooHasher := NewCuckooHasher(size, seeds) + // get randombyte from crypto/rand + var rb [8]byte + if _, err := crand.Read(rb[:]); err != nil { + panic(err) + } + + // WARNING: math/rand is not concurrency-safe + // replace with crypto/rand if that's what you want + + // seed math/rand with crypto/rand + rand.Seed(int64(binary.LittleEndian.Uint64(rb[:]))) + return &Cuckoo{ // extra element is "keeper" to which the bucketLookup can be directed // when there is no element present in the bucket. @@ -181,7 +196,8 @@ func (c *Cuckoo) tryAdd(idx uint64, bucketIndices [Nhash]uint64, ignore bool, ex func (c *Cuckoo) tryGreedyAdd(idx uint64, bucketIndices [Nhash]uint64) (homeLessItem uint64, added bool) { for i := 1; i < ReInsertLimit; i++ { // select a random slot to be evicted - evictedHIdx := rand.Int31n(Nhash) + // replace me with crypto/rand for concurrent safety + evictedHIdx := rand.Intn(Nhash) evictedBIdx := bucketIndices[evictedHIdx] evictedIdx := c.bucketLookup[evictedBIdx] // insert the item in the evicted slot