Skip to content

Commit

Permalink
tweak bytes cache hasher and shards
Browse files Browse the repository at this point in the history
  • Loading branch information
phuslu committed Apr 21, 2024
1 parent a5dfbfb commit e859537
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
25 changes: 16 additions & 9 deletions bytes_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ type BytesCache struct {
}

// NewBytesCache creates bytes cache with size capacity.
func NewBytesCache[K comparable, V any](size int) *BytesCache {
func NewBytesCache(shards uint8, size uint32) *BytesCache {
c := new(BytesCache)

c.mask = 511
c.mask = nextPowOf2(uint32(shards)) - 1
c.shards = make([]bytesshard, c.mask+1)

shardsize := (uint32(size) + c.mask) / (c.mask + 1)
shardsize := (size + c.mask) / (c.mask + 1)
for i := uint32(0); i <= c.mask; i++ {
c.shards[i].Init(shardsize)
}
Expand All @@ -31,14 +31,14 @@ func NewBytesCache[K comparable, V any](size int) *BytesCache {

// Get returns value for key.
func (c *BytesCache) Get(key []byte) (value []byte, ok bool) {
hash := uint32(wyhash_HashString(b2s(key), 0))
hash := uint32(wyhash_HashBytes(key, 0))
// return c.shards[hash&c.mask].Get(hash, key)
return (*bytesshard)(unsafe.Add(unsafe.Pointer(&c.shards[0]), uintptr(hash&c.mask)*unsafe.Sizeof(c.shards[0]))).Get(hash, key)
}

// GetOrLoad returns value for key, call loader function by singleflight if value was not in cache.
func (c *BytesCache) GetOrLoad(ctx context.Context, key []byte, loader func(context.Context, []byte) ([]byte, error)) (value []byte, err error, ok bool) {
hash := uint32(wyhash_HashString(b2s(key), 0))
hash := uint32(wyhash_HashBytes(key, 0))
value, ok = c.shards[hash&c.mask].Get(hash, key)
if !ok {
if loader == nil {
Expand All @@ -59,28 +59,28 @@ func (c *BytesCache) GetOrLoad(ctx context.Context, key []byte, loader func(cont

// Peek returns value, but does not modify its recency.
func (c *BytesCache) Peek(key []byte) (value []byte, ok bool) {
hash := uint32(wyhash_HashString(b2s(key), 0))
hash := uint32(wyhash_HashBytes(key, 0))
// return c.shards[hash&c.mask].Peek(hash, key)
return (*bytesshard)(unsafe.Add(unsafe.Pointer(&c.shards[0]), uintptr(hash&c.mask)*unsafe.Sizeof(c.shards[0]))).Peek(hash, key)
}

// Set inserts key value pair and returns previous value.
func (c *BytesCache) Set(key []byte, value []byte) (prev []byte, replaced bool) {
hash := uint32(wyhash_HashString(b2s(key), 0))
hash := uint32(wyhash_HashBytes(key, 0))
// return c.shards[hash&c.mask].Set(hash, key, value)
return (*bytesshard)(unsafe.Add(unsafe.Pointer(&c.shards[0]), uintptr(hash&c.mask)*unsafe.Sizeof(c.shards[0]))).Set(hash, key, value)
}

// SetIfAbsent inserts key value pair and returns previous value, if key is absent in the cache.
func (c *BytesCache) SetIfAbsent(key []byte, value []byte) (prev []byte, replaced bool) {
hash := uint32(wyhash_HashString(b2s(key), 0))
hash := uint32(wyhash_HashBytes(key, 0))
// return c.shards[hash&c.mask].SetIfAbsent(hash, key, value)
return (*bytesshard)(unsafe.Add(unsafe.Pointer(&c.shards[0]), uintptr(hash&c.mask)*unsafe.Sizeof(c.shards[0]))).SetIfAbsent(hash, key, value)
}

// Delete method deletes value associated with key and returns deleted value (or empty value if key was not in cache).
func (c *BytesCache) Delete(key []byte) (prev []byte) {
hash := uint32(wyhash_HashString(b2s(key), 0))
hash := uint32(wyhash_HashBytes(key, 0))
// return c.shards[hash&c.mask].Delete(hash, key)
return (*bytesshard)(unsafe.Add(unsafe.Pointer(&c.shards[0]), uintptr(hash&c.mask)*unsafe.Sizeof(c.shards[0]))).Delete(hash, key)
}
Expand Down Expand Up @@ -115,3 +115,10 @@ func (c *BytesCache) Stats() (stats Stats) {
}
return
}

func wyhash_HashBytes(data []byte, seed uint64) uint64 {
if len(data) == 0 {
return seed
}
return wyhash_hash(*(*string)(unsafe.Pointer(&data)), seed)
}
4 changes: 2 additions & 2 deletions bytes_shard.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (s *bytesshard) SetIfAbsent(hash uint32, key []byte, value []byte) (prev []
index := s.list[0].prev
node := (*bytesnode)(unsafe.Add(unsafe.Pointer(&s.list[0]), uintptr(index)*unsafe.Sizeof(s.list[0])))
evictedValue := node.value
s.table_Delete(uint32(wyhash_HashString(b2s(node.key), 0)), node.key)
s.table_Delete(uint32(wyhash_HashBytes(node.key, 0)), node.key)

node.key = key
node.value = value
Expand Down Expand Up @@ -129,7 +129,7 @@ func (s *bytesshard) Set(hash uint32, key []byte, value []byte) (prev []byte, re
index := s.list[0].prev
node := (*bytesnode)(unsafe.Add(unsafe.Pointer(&s.list[0]), uintptr(index)*unsafe.Sizeof(s.list[0])))
evictedValue := node.value
s.table_Delete(uint32(wyhash_HashString(b2s(node.key), 0)), node.key)
s.table_Delete(uint32(wyhash_HashBytes(node.key, 0)), node.key)

node.key = key
node.value = value
Expand Down

0 comments on commit e859537

Please sign in to comment.