// newDefaultHasher returns a new 64-bit FNV-1a Hasher which makes no memory allocations. // Its Sum64 method will lay the value out in big-endian byte order. // See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function funcnewDefaultHasher()fnv64a { return fnv64a{} }
type fnv64a struct{}
const ( // offset64 FNVa offset basis. See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function#FNV-1a_hash offset64 = 14695981039346656037 // prime64 FNVa prime value. See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function#FNV-1a_hash prime64 = 1099511628211 )
// Sum64 gets the string and returns its uint64 hash value. func(f fnv64a)Sum64(key string)uint64 { var hash uint64 = offset64 for i := 0; i < len(key); i++ { hash ^= uint64(key[i]) hash *= prime64 }
func(s *cacheShard)set(hashedKey uint64, entry []byte) { w := wrapEntry(entry) s.lock.Lock() index := s.push(w) s.items[hashedKey] = uint32(index) s.lock.Unlock() }
func(s *cacheShard)push(data []byte)int { dataLen := len(data) index := s.tail s.save(data, dataLen) return index }
func(s *cacheShard)save(data []byte, lenint) { // Put in the first 4 bytes the size of the value binary.LittleEndian.PutUint32(s.headerBuffer, uint32(len)) s.copy(s.headerBuffer, headerEntrySize) s.copy(data, len) }
func(s *cacheShard)copy(data []byte, lenint) { // Using the tail to keep the order to write in the array s.tail += copy(s.array[s.tail:], data[:len]) }
// Read the first 4 bytes after the index, remember these 4 bytes have the size of the value, so // you can use this to get the size and get the value in the array using index+blockSize to know until what point // you need to read blockSize := int(binary.LittleEndian.Uint32(s.array[itemIndex : itemIndex+headerEntrySize])) entry := s.array[itemIndex+headerEntrySize : itemIndex+headerEntrySize+blockSize] s.lock.RUnlock() return readEntry(entry), nil }
funcwrapEntry(entry []byte) []byte { // You can put more information like a timestamp if you want. blobLength := len(entry) blob := make([]byte, blobLength) copy(blob, entry) return blob }