Skip to content

Commit f3d5cb6

Browse files
chore: reduce string allocations in TSI series cache (#27255) (#27257)
eliminate string allocations in TSI series cache (cherry picked from commit 37b3100)
1 parent 6a3b02c commit f3d5cb6

File tree

1 file changed

+21
-16
lines changed

1 file changed

+21
-16
lines changed

tsdb/index/tsi1/cache.go

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ func (c *TagValueSeriesIDCache) get(name, key, value []byte) *tsdb.SeriesIDSet {
5656
return nil
5757
}
5858

59-
// exists returns true if the an item exists for the tuple {name, key, value}.
60-
func (c *TagValueSeriesIDCache) exists(name, key, value []byte) bool {
61-
if mmap, ok := c.cache[string(name)]; ok {
62-
if tkmap, ok := mmap[string(key)]; ok {
63-
_, ok := tkmap[string(value)]
59+
// exists returns true if the item exists for the tuple {name, key, value}.
60+
func (c *TagValueSeriesIDCache) exists(name, key, value string) bool {
61+
if mmap, ok := c.cache[name]; ok {
62+
if tkmap, ok := mmap[key]; ok {
63+
_, ok := tkmap[value]
6464
return ok
6565
}
6666
}
@@ -97,8 +97,13 @@ func (c *TagValueSeriesIDCache) measurementContainsSets(name []byte) bool {
9797
// the cache is at its limit, then the least recently used item is evicted.
9898
func (c *TagValueSeriesIDCache) Put(name, key, value []byte, ss *tsdb.SeriesIDSet) {
9999
c.Lock()
100+
// Convert once; the same string backing array is shared between
101+
// the cache element (used during eviction) and the map keys.
102+
nameStr := string(name)
103+
keyStr := string(key)
104+
valueStr := string(value)
100105
// Check under the write lock if the relevant item is now in the cache.
101-
if c.exists(name, key, value) {
106+
if c.exists(nameStr, keyStr, valueStr) {
102107
c.Unlock()
103108
return
104109
}
@@ -111,32 +116,32 @@ func (c *TagValueSeriesIDCache) Put(name, key, value []byte, ss *tsdb.SeriesIDSe
111116

112117
// Create list item, and add to the front of the eviction list.
113118
listElement := c.evictor.PushFront(&seriesIDCacheElement{
114-
name: string(name),
115-
key: string(key),
116-
value: string(value),
119+
name: nameStr,
120+
key: keyStr,
121+
value: valueStr,
117122
SeriesIDSet: ss,
118123
})
119124

120125
// Add the listElement to the set of items.
121-
if mmap, ok := c.cache[string(name)]; ok {
122-
if tkmap, ok := mmap[string(key)]; ok {
123-
if _, ok := tkmap[string(value)]; ok {
126+
if mmap, ok := c.cache[nameStr]; ok {
127+
if tkmap, ok := mmap[keyStr]; ok {
128+
if _, ok := tkmap[valueStr]; ok {
124129
goto EVICT
125130
}
126131

127132
// Add the set to the map
128-
tkmap[string(value)] = listElement
133+
tkmap[valueStr] = listElement
129134
goto EVICT
130135
}
131136

132137
// No series set map for the tag key - first tag value for the tag key.
133-
mmap[string(key)] = map[string]*list.Element{string(value): listElement}
138+
mmap[keyStr] = map[string]*list.Element{valueStr: listElement}
134139
goto EVICT
135140
}
136141

137142
// No map for the measurement - first tag key for the measurment.
138-
c.cache[string(name)] = map[string]map[string]*list.Element{
139-
string(key): map[string]*list.Element{string(value): listElement},
143+
c.cache[nameStr] = map[string]map[string]*list.Element{
144+
keyStr: map[string]*list.Element{valueStr: listElement},
140145
}
141146

142147
EVICT:

0 commit comments

Comments
 (0)