github.com/QuangTung97/bigcache@v0.1.0/bigcache.go (about) 1 package bigcache 2 3 import ( 4 "github.com/QuangTung97/bigcache/memhash" 5 "math/bits" 6 ) 7 8 // Cache ... 9 type Cache struct { 10 segments []segment 11 12 segmentMask uint64 13 segmentShift int 14 } 15 16 // New ... 17 func New(numSegments int, segmentSize int) *Cache { 18 if numSegments < 1 { 19 panic("numSegments must not be < 1") 20 } 21 numSegments = nextPowerOfTwo(numSegments) 22 23 segments := make([]segment, numSegments) 24 for i := range segments { 25 initSegment(&segments[i], segmentSize) 26 } 27 28 mask, shift := computeSegmentMask(numSegments) 29 return &Cache{ 30 segments: segments, 31 segmentMask: mask, 32 segmentShift: shift, 33 } 34 } 35 36 func (c *Cache) getSegment(key []byte) (*segment, uint64) { 37 hash := memhash.Hash(key) 38 index := getSegmentIndex(c.segmentMask, c.segmentShift, hash) 39 return &c.segments[index], hash 40 } 41 42 // Put ... 43 func (c *Cache) Put(key []byte, value []byte) { 44 seg, hash := c.getSegment(key) 45 46 seg.mu.Lock() 47 seg.put(uint32(hash), key, value) 48 seg.mu.Unlock() 49 } 50 51 // Get ... 52 func (c *Cache) Get(key []byte, value []byte) (int, bool) { 53 seg, hash := c.getSegment(key) 54 55 seg.mu.Lock() 56 n, ok := seg.get(uint32(hash), key, value) 57 seg.mu.Unlock() 58 59 return n, ok 60 } 61 62 // Delete ... 63 func (c *Cache) Delete(key []byte) bool { 64 seg, hash := c.getSegment(key) 65 66 seg.mu.Lock() 67 affected := seg.delete(uint32(hash), key) 68 seg.mu.Unlock() 69 70 return affected 71 } 72 73 // GetHitCount ... 74 func (c *Cache) GetHitCount() uint64 { 75 count := uint64(0) 76 for i := range c.segments { 77 count += c.segments[i].getHitCount() 78 } 79 return count 80 } 81 82 // GetAccessCount ... 83 func (c *Cache) GetAccessCount() uint64 { 84 count := uint64(0) 85 for i := range c.segments { 86 count += c.segments[i].getAccessCount() 87 } 88 return count 89 } 90 91 // GetTotal ... 92 func (c *Cache) GetTotal() uint64 { 93 count := uint64(0) 94 for i := range c.segments { 95 count += c.segments[i].getTotal() 96 } 97 return count 98 } 99 100 func nextPowerOfTwo(n int) int { 101 num := uint32(n) 102 return 1 << bits.Len32(num-1) 103 } 104 105 func computeSegmentMask(n int) (uint64, int) { 106 shift := 64 - bits.Len64(uint64(n-1)) 107 return ^uint64(0) << shift, shift 108 } 109 110 func getSegmentIndex(mask uint64, shift int, hash uint64) int { 111 return int((hash & mask) >> shift) 112 }