Skip to content

Commit

Permalink
clean bucket.m on every wrap over chunks
Browse files Browse the repository at this point in the history
This should reduce memory usage for bucket.m
  • Loading branch information
valyala committed Feb 7, 2022
1 parent 656ee2f commit ef94071
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 18 deletions.
37 changes: 20 additions & 17 deletions fastcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,20 +271,18 @@ func (b *bucket) Reset() {
b.mu.Unlock()
}

func (b *bucket) Clean() {
b.mu.Lock()
func (b *bucket) cleanLocked() {
bGen := b.gen & ((1 << genSizeBits) - 1)
bIdx := b.idx
bm := b.m
for k, v := range bm {
gen := v >> bucketSizeBits
idx := v & ((1 << bucketSizeBits) - 1)
if gen == bGen && idx < bIdx || gen+1 == bGen && idx >= bIdx || gen == maxGen && bGen == 1 && idx >= bIdx {
if (gen+1 == bGen || gen == maxGen && bGen == 1) && idx >= bIdx || gen == bGen && idx < bIdx {
continue
}
delete(bm, k)
}
b.mu.Unlock()
}

func (b *bucket) UpdateStats(s *Stats) {
Expand All @@ -296,19 +294,17 @@ func (b *bucket) UpdateStats(s *Stats) {

b.mu.RLock()
s.EntriesCount += uint64(len(b.m))
bytesSize := uint64(0)
for _, chunk := range b.chunks {
s.BytesSize += uint64(cap(chunk))
bytesSize += uint64(cap(chunk))
}
s.MaxBytesSize += uint64(len(b.chunks))*chunkSize
s.BytesSize += bytesSize
s.MaxBytesSize += uint64(len(b.chunks)) * chunkSize
b.mu.RUnlock()
}

func (b *bucket) Set(k, v []byte, h uint64) {
setCalls := atomic.AddUint64(&b.setCalls, 1)
if setCalls%(1<<14) == 0 {
b.Clean()
}

atomic.AddUint64(&b.setCalls, 1)
if len(k) >= (1<<16) || len(v) >= (1<<16) {
// Too big key or value - its length cannot be encoded
// with 2 bytes (see below). Skip the entry.
Expand All @@ -326,44 +322,51 @@ func (b *bucket) Set(k, v []byte, h uint64) {
return
}

chunks := b.chunks
needClean := false
b.mu.Lock()
idx := b.idx
idxNew := idx + kvLen
chunkIdx := idx / chunkSize
chunkIdxNew := idxNew / chunkSize
if chunkIdxNew > chunkIdx {
if chunkIdxNew >= uint64(len(b.chunks)) {
if chunkIdxNew >= uint64(len(chunks)) {
idx = 0
idxNew = kvLen
chunkIdx = 0
b.gen++
if b.gen&((1<<genSizeBits)-1) == 0 {
b.gen++
}
needClean = true
} else {
idx = chunkIdxNew * chunkSize
idxNew = idx + kvLen
chunkIdx = chunkIdxNew
}
b.chunks[chunkIdx] = b.chunks[chunkIdx][:0]
chunks[chunkIdx] = chunks[chunkIdx][:0]
}
chunk := b.chunks[chunkIdx]
chunk := chunks[chunkIdx]
if chunk == nil {
chunk = getChunk()
chunk = chunk[:0]
}
chunk = append(chunk, kvLenBuf[:]...)
chunk = append(chunk, k...)
chunk = append(chunk, v...)
b.chunks[chunkIdx] = chunk
chunks[chunkIdx] = chunk
b.m[h] = idx | (b.gen << bucketSizeBits)
b.idx = idxNew
if needClean {
b.cleanLocked()
}
b.mu.Unlock()
}

func (b *bucket) Get(dst, k []byte, h uint64, returnDst bool) ([]byte, bool) {
atomic.AddUint64(&b.getCalls, 1)
found := false
chunks := b.chunks
b.mu.RLock()
v := b.m[h]
bGen := b.gen & ((1 << genSizeBits) - 1)
Expand All @@ -372,12 +375,12 @@ func (b *bucket) Get(dst, k []byte, h uint64, returnDst bool) ([]byte, bool) {
idx := v & ((1 << bucketSizeBits) - 1)
if gen == bGen && idx < b.idx || gen+1 == bGen && idx >= b.idx || gen == maxGen && bGen == 1 && idx >= b.idx {
chunkIdx := idx / chunkSize
if chunkIdx >= uint64(len(b.chunks)) {
if chunkIdx >= uint64(len(chunks)) {
// Corrupted data during the load from file. Just skip it.
atomic.AddUint64(&b.corruptions, 1)
goto end
}
chunk := b.chunks[chunkIdx]
chunk := chunks[chunkIdx]
idx %= chunkSize
if idx+4 >= chunkSize {
// Corrupted data during the load from file. Just skip it.
Expand Down
4 changes: 3 additions & 1 deletion file.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,9 @@ func loadBuckets(buckets []bucket, dataPath string, maxChunks uint64) error {
}

func (b *bucket) Save(w io.Writer) error {
b.Clean()
b.mu.Lock()
b.cleanLocked()
b.mu.Unlock()

b.mu.RLock()
defer b.mu.RUnlock()
Expand Down
1 change: 1 addition & 0 deletions malloc_heap.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build appengine || windows
// +build appengine windows

package fastcache
Expand Down
1 change: 1 addition & 0 deletions malloc_mmap.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !appengine && !windows
// +build !appengine,!windows

package fastcache
Expand Down

0 comments on commit ef94071

Please sign in to comment.