Skip to content

Commit a933320

Browse files
committed
fix(cache): Estimate size of posting lists
1 parent 07c4d6d commit a933320

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

posting/mvcc.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ func (c *Cache) set(key []byte, i *CachePL) {
370370
return
371371
}
372372
c.numCacheSave.Add(1)
373-
c.data.Set(key, i, 1)
373+
c.data.Set(key, i, 0)
374374
}
375375

376376
func (c *Cache) del(key []byte) {
@@ -508,14 +508,18 @@ func initMemoryLayer(cacheSize int64, removeOnUpdate bool) *MemoryLayer {
508508
ml.removeOnUpdate = removeOnUpdate
509509
ml.statsHolder = NewStatsHolder()
510510
if cacheSize > 0 {
511-
cache, err := ristretto.NewCache[[]byte, *CachePL](&ristretto.Config[[]byte, *CachePL]{
511+
cache, err := ristretto.NewCache(&ristretto.Config[[]byte, *CachePL]{
512512
// Use 5% of cache memory for storing counters.
513513
NumCounters: int64(float64(cacheSize) * 0.05 * 2),
514514
MaxCost: int64(float64(cacheSize) * 0.95),
515515
BufferItems: 16,
516516
Metrics: true,
517517
Cost: func(val *CachePL) int64 {
518-
return 1
518+
itemSize := int64(8)
519+
if val.list != nil {
520+
itemSize += int64(val.list.ApproximateSize())
521+
}
522+
return itemSize
519523
},
520524
ShouldUpdate: func(cur, prev *CachePL) bool {
521525
return !(cur.list != nil && prev.list != nil && prev.list.maxTs > cur.list.maxTs)

posting/size.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,97 @@ import (
1616

1717
const sizeOfBucket = 144
1818

19+
func (l *List) ApproximateSize() uint64 {
20+
if l == nil {
21+
return 0
22+
}
23+
24+
l.RLock()
25+
defer l.RUnlock()
26+
27+
var size uint64 = 4*8 + // safe mutex consists of 4 words.
28+
1*8 + // plist pointer consists of 1 word.
29+
1*8 + // mutation map pointer consists of 1 word.
30+
2*8 + // minTs and maxTs take 1 word each.
31+
3*8 + // array take 3 words. so key array is 3 words.
32+
3*8 + // array take 3 words. so cache array is 3 words.
33+
1*8 // So far 11 words, in order to round the slab we're adding one more word.
34+
// so far basic struct layout has been calculated.
35+
36+
// add byte array memory
37+
size += uint64(cap(l.key)) + uint64(cap(l.cache))
38+
39+
size += approxPostingListSize(l.plist)
40+
41+
if l.mutationMap != nil {
42+
size += l.mutationMap.ApproximateSize()
43+
}
44+
45+
return size
46+
}
47+
48+
func approxPostingListSize(list *pb.PostingList) uint64 {
49+
if list == nil {
50+
return 0
51+
}
52+
53+
var size uint64 = 1*8 + // Pack consists of 1 word.
54+
3*8 + // Postings array consists of 3 words.
55+
1*8 + // CommitTs consists of 1 word.
56+
3*8 // Splits array consists of 3 words.
57+
58+
// add pack size.
59+
size += calculatePackSize(list.Pack)
60+
61+
// Each entry take one word.
62+
// Adding each entry reference allocation.
63+
size += uint64(cap(list.Postings)) * 8
64+
for _, p := range list.Postings {
65+
// add the size of each posting.
66+
size += calculatePostingSize(p) * uint64(cap(list.Postings))
67+
break
68+
}
69+
70+
// Each entry take one word.
71+
// Adding each entry size.
72+
size += uint64(cap(list.Splits)) * 8
73+
74+
return size
75+
}
76+
77+
func (m *MutableLayer) ApproximateSize() uint64 {
78+
if m == nil {
79+
return 0
80+
}
81+
82+
var size uint64 = 2*8 + // committedEntries and currentEntries take 2 words each.
83+
1*8 + // readTs takes 1 word.
84+
1*8 + // deleteAllMarker takes 1 word.
85+
1*8 + // committedUids takes 1 word.
86+
1*8 + // committedUidsTime takes 1 word.
87+
1*8 + // length takes 1 word.
88+
1*8 + // lastEntry takes 1 word.
89+
1*8 + // committedUidsTime takes 1 word.
90+
1*8 + // isUidsCalculated takes 1 word.
91+
1*8 // calculatedUids takes 1 word.
92+
// so far basic struct layout has been calculated.
93+
94+
// Add each entry size of committedEntries.
95+
size += uint64(len(m.committedEntries)) * 8
96+
for _, v := range m.committedUids {
97+
size += calculatePostingSize(v) * uint64(len(m.committedEntries))
98+
break
99+
}
100+
101+
size += approxPostingListSize(m.currentEntries)
102+
size += approxPostingListSize(m.lastEntry)
103+
104+
size += uint64(len(m.currentUids)) * 8
105+
size += uint64(cap(m.calculatedUids)) * 8
106+
107+
return size
108+
}
109+
19110
// DeepSize computes the memory taken by a Posting List
20111
func (l *List) DeepSize() uint64 {
21112
if l == nil {

worker/server_state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const (
4141
ZeroLimitsDefaults = `uid-lease=0; refill-interval=30s; disable-admin-http=false;`
4242
GraphQLDefaults = `introspection=true; debug=false; extensions=true; poll-interval=1s; ` +
4343
`lambda-url=;`
44-
CacheDefaults = `size-mb=1024; percentage=40,40,20; remove-on-update=false`
44+
CacheDefaults = `size-mb=4096; percentage=40,40,20; remove-on-update=false`
4545
FeatureFlagsDefaults = `normalize-compatibility-mode=; enable-detailed-metrics=false`
4646
)
4747

0 commit comments

Comments
 (0)