MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / evictBasedOffMemoryUsage

Method evictBasedOffMemoryUsage

db/revision_cache_lru.go:896–950  ·  view source on GitHub ↗
(ctx context.Context)

Source from the content-addressed store, hash-verified

894}
895
896func (rc *LRURevisionCache) evictBasedOffMemoryUsage(ctx context.Context) int64 {
897 var numItemsRemoved, numBytesRemoved int64
898 rc.lock.Lock()
899 defer rc.lock.Unlock()
900 // check if we are over memory capacity after holding rev cache mutex (protect against another goroutine evicting whilst waiting for mutex above)
901 if currMemoryUsage := rc.currMemoryUsage.Value(); currMemoryUsage > rc.memoryCapacity {
902 // find amount of bytes needed to evict till below threshold
903 bytesNeededToRemove := currMemoryUsage - rc.memoryCapacity
904 for bytesNeededToRemove > numBytesRemoved {
905 value := rc._findEvictionValue()
906 if value == nil {
907 if rc.lruList.Len() > 0 {
908 // no more values ready for eviction
909 break
910 } else {
911 // list is empty, nothing more to evict but stats are wrong so zero stats and return
912 base.DebugfCtx(ctx, base.KeyCache, "Revision cache memory stats inconsistent for this shard, resetting to zero")
913 correctionVal := rc.currMemoryUsage.Value()
914 // Correct overall memory stat across shards to remove this shards memory usage, and set this shard to zero
915 rc.cacheMemoryBytesStat.Add(-correctionVal)
916 rc.currMemoryUsage.Set(0)
917 return numItemsRemoved
918 }
919 }
920 revKey := IDAndRev{DocID: value.id, RevID: value.revID, CollectionID: value.collectionID}
921 hlvKey := IDandCV{DocID: value.id, Source: value.cv.SourceID, Version: value.cv.Value, CollectionID: value.collectionID}
922 // same below but for hlv lookup map
923 if elem := rc.hlvCache[hlvKey]; elem != nil {
924 revValue := elem.Value.(*revCacheValue)
925 // we need to check if the value pointed to by the cv lookup map is the same value we're evicting, this is
926 // because we can currently have two items with the same docID and CV, but different revIDs due to
927 // local wins conflict resolution not generating a new CV but generating a new revID.
928 if revValue.revID == value.revID {
929 // this cv lookup item matches the value we're evicting, so remove it
930 delete(rc.hlvCache, hlvKey)
931 }
932 }
933 if elem := rc.cache[revKey]; elem != nil {
934 revValue := elem.Value.(*revCacheValue)
935 // we need to check if the value pointed to by the rev lookup map is the same value we're evicting, this is
936 // because we can have can currently have two items with the same docID and revID, but different CVs due to
937 // a new HLV being generated for user xattr updates where we don't generate a new revID.
938 if revValue.cv.String() == value.cv.String() {
939 // this rev lookup item matches the value we're evicting, so remove it
940 delete(rc.cache, revKey)
941 }
942 }
943 numItemsRemoved++
944 valueBytes := value.getItemBytes()
945 numBytesRemoved += valueBytes
946 }
947 }
948 rc._decrRevCacheMemoryUsage(ctx, -numBytesRemoved) // need update rev cache memory stats before release lock to stop other goroutines evicting based on outdated stats
949 return numItemsRemoved
950}
951
952// _decrRevCacheMemoryUsage atomically decreases overall memory usage for cache and the actual rev cache objects usage.
953// You should be holding rev cache lock in using this function to avoid eviction processes over evicting items

Callers 1

performEvictionMethod · 0.95

Calls 11

_findEvictionValueMethod · 0.95
DebugfCtxFunction · 0.92
getItemBytesMethod · 0.80
LenMethod · 0.65
StringMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45
ValueMethod · 0.45
AddMethod · 0.45
SetMethod · 0.45

Tested by

no test coverage detected