diff options
author | 2018-08-31 17:26:43 -0400 | |
---|---|---|
committer | 2018-08-31 14:26:43 -0700 | |
commit | 4c6c9d4b2700c3e4606d4b98bde64e7c1ed0c231 (patch) | |
tree | 628c776c0d6e7211b7e648a99303115e0f1f1a72 /plugin/pkg/cache/cache.go | |
parent | d00e8c39183b0385324bc7ea56a3f2aeb6918748 (diff) | |
download | coredns-4c6c9d4b2700c3e4606d4b98bde64e7c1ed0c231.tar.gz coredns-4c6c9d4b2700c3e4606d4b98bde64e7c1ed0c231.tar.zst coredns-4c6c9d4b2700c3e4606d4b98bde64e7c1ed0c231.zip |
Move cache Keys to 64bit for a better dispersion and lower collision frequency (#2077)
* - change Key for cache to 64bits.
* - change Key for cache to 64bits.
Diffstat (limited to 'plugin/pkg/cache/cache.go')
-rw-r--r-- | plugin/pkg/cache/cache.go | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/plugin/pkg/cache/cache.go b/plugin/pkg/cache/cache.go index 954befa76..8a5ad783e 100644 --- a/plugin/pkg/cache/cache.go +++ b/plugin/pkg/cache/cache.go @@ -9,10 +9,10 @@ import ( ) // Hash returns the FNV hash of what. -func Hash(what []byte) uint32 { - h := fnv.New32() +func Hash(what []byte) uint64 { + h := fnv.New64() h.Write(what) - return h.Sum32() + return h.Sum64() } // Cache is cache. @@ -22,7 +22,7 @@ type Cache struct { // shard is a cache with random eviction. type shard struct { - items map[uint32]interface{} + items map[uint64]interface{} size int sync.RWMutex @@ -45,19 +45,19 @@ func New(size int) *Cache { } // Add adds a new element to the cache. If the element already exists it is overwritten. -func (c *Cache) Add(key uint32, el interface{}) { +func (c *Cache) Add(key uint64, el interface{}) { shard := key & (shardSize - 1) c.shards[shard].Add(key, el) } // Get looks up element index under key. -func (c *Cache) Get(key uint32) (interface{}, bool) { +func (c *Cache) Get(key uint64) (interface{}, bool) { shard := key & (shardSize - 1) return c.shards[shard].Get(key) } // Remove removes the element indexed with key. -func (c *Cache) Remove(key uint32) { +func (c *Cache) Remove(key uint64) { shard := key & (shardSize - 1) c.shards[shard].Remove(key) } @@ -72,10 +72,10 @@ func (c *Cache) Len() int { } // newShard returns a new shard with size. -func newShard(size int) *shard { return &shard{items: make(map[uint32]interface{}), size: size} } +func newShard(size int) *shard { return &shard{items: make(map[uint64]interface{}), size: size} } // Add adds element indexed by key into the cache. Any existing element is overwritten -func (s *shard) Add(key uint32, el interface{}) { +func (s *shard) Add(key uint64, el interface{}) { l := s.Len() if l+1 > s.size { s.Evict() @@ -87,7 +87,7 @@ func (s *shard) Add(key uint32, el interface{}) { } // Remove removes the element indexed by key from the cache. -func (s *shard) Remove(key uint32) { +func (s *shard) Remove(key uint64) { s.Lock() delete(s.items, key) s.Unlock() @@ -95,26 +95,28 @@ func (s *shard) Remove(key uint32) { // Evict removes a random element from the cache. func (s *shard) Evict() { - key := -1 + hasKey := false + var key uint64 s.RLock() for k := range s.items { - key = int(k) + key = k + hasKey = true break } s.RUnlock() - if key == -1 { + if !hasKey { // empty cache return } // If this item is gone between the RUnlock and Lock race we don't care. - s.Remove(uint32(key)) + s.Remove(key) } // Get looks up the element indexed under key. -func (s *shard) Get(key uint32) (interface{}, bool) { +func (s *shard) Get(key uint64) (interface{}, bool) { s.RLock() el, found := s.items[key] s.RUnlock() |