diff --git a/posting/mvcc.go b/posting/mvcc.go index 06b70fdce57..5024c93078d 100644 --- a/posting/mvcc.go +++ b/posting/mvcc.go @@ -370,7 +370,7 @@ func (c *Cache) set(key []byte, i *CachePL) { return } c.numCacheSave.Add(1) - c.data.Set(key, i, 1) + c.data.Set(key, i, 0) } func (c *Cache) del(key []byte) { @@ -508,14 +508,18 @@ func initMemoryLayer(cacheSize int64, removeOnUpdate bool) *MemoryLayer { ml.removeOnUpdate = removeOnUpdate ml.statsHolder = NewStatsHolder() if cacheSize > 0 { - cache, err := ristretto.NewCache[[]byte, *CachePL](&ristretto.Config[[]byte, *CachePL]{ + cache, err := ristretto.NewCache(&ristretto.Config[[]byte, *CachePL]{ // Use 5% of cache memory for storing counters. NumCounters: int64(float64(cacheSize) * 0.05 * 2), MaxCost: int64(float64(cacheSize) * 0.95), BufferItems: 16, Metrics: true, Cost: func(val *CachePL) int64 { - return 1 + itemSize := int64(8) + if val.list != nil { + itemSize += int64(val.list.ApproximateSize()) + } + return itemSize }, ShouldUpdate: func(cur, prev *CachePL) bool { return !(cur.list != nil && prev.list != nil && prev.list.maxTs > cur.list.maxTs) diff --git a/posting/size.go b/posting/size.go index d7218e4248d..80f81f89a99 100644 --- a/posting/size.go +++ b/posting/size.go @@ -16,6 +16,97 @@ import ( const sizeOfBucket = 144 +func (l *List) ApproximateSize() uint64 { + if l == nil { + return 0 + } + + l.RLock() + defer l.RUnlock() + + var size uint64 = 4*8 + // safe mutex consists of 4 words. + 1*8 + // plist pointer consists of 1 word. + 1*8 + // mutation map pointer consists of 1 word. + 2*8 + // minTs and maxTs take 1 word each. + 3*8 + // array take 3 words. so key array is 3 words. + 3*8 + // array take 3 words. so cache array is 3 words. + 1*8 // So far 11 words, in order to round the slab we're adding one more word. + // so far basic struct layout has been calculated. + + // add byte array memory + size += uint64(cap(l.key)) + uint64(cap(l.cache)) + + size += approxPostingListSize(l.plist) + + if l.mutationMap != nil { + size += l.mutationMap.ApproximateSize() + } + + return size +} + +func approxPostingListSize(list *pb.PostingList) uint64 { + if list == nil { + return 0 + } + + var size uint64 = 1*8 + // Pack consists of 1 word. + 3*8 + // Postings array consists of 3 words. + 1*8 + // CommitTs consists of 1 word. + 3*8 // Splits array consists of 3 words. + + // add pack size. + size += calculatePackSize(list.Pack) + + // Each entry take one word. + // Adding each entry reference allocation. + size += uint64(cap(list.Postings)) * 8 + for _, p := range list.Postings { + // add the size of each posting. + size += calculatePostingSize(p) * uint64(cap(list.Postings)) + break + } + + // Each entry take one word. + // Adding each entry size. + size += uint64(cap(list.Splits)) * 8 + + return size +} + +func (m *MutableLayer) ApproximateSize() uint64 { + if m == nil { + return 0 + } + + var size uint64 = 2*8 + // committedEntries and currentEntries take 2 words each. + 1*8 + // readTs takes 1 word. + 1*8 + // deleteAllMarker takes 1 word. + 1*8 + // committedUids takes 1 word. + 1*8 + // committedUidsTime takes 1 word. + 1*8 + // length takes 1 word. + 1*8 + // lastEntry takes 1 word. + 1*8 + // committedUidsTime takes 1 word. + 1*8 + // isUidsCalculated takes 1 word. + 1*8 // calculatedUids takes 1 word. + // so far basic struct layout has been calculated. + + // Add each entry size of committedEntries. + size += uint64(len(m.committedEntries)) * 8 + for _, v := range m.committedUids { + size += calculatePostingSize(v) * uint64(len(m.committedEntries)) + break + } + + size += approxPostingListSize(m.currentEntries) + size += approxPostingListSize(m.lastEntry) + + size += uint64(len(m.currentUids)) * 8 + size += uint64(cap(m.calculatedUids)) * 8 + + return size +} + // DeepSize computes the memory taken by a Posting List func (l *List) DeepSize() uint64 { if l == nil { diff --git a/worker/server_state.go b/worker/server_state.go index 829678ee03e..66a8eb1ce9b 100644 --- a/worker/server_state.go +++ b/worker/server_state.go @@ -41,7 +41,7 @@ const ( ZeroLimitsDefaults = `uid-lease=0; refill-interval=30s; disable-admin-http=false;` GraphQLDefaults = `introspection=true; debug=false; extensions=true; poll-interval=1s; ` + `lambda-url=;` - CacheDefaults = `size-mb=1024; percentage=40,40,20; remove-on-update=false` + CacheDefaults = `size-mb=4096; percentage=40,40,20; remove-on-update=false` FeatureFlagsDefaults = `normalize-compatibility-mode=; enable-detailed-metrics=false` )