From 68a59bfabdd41efc0cf8b12a673b0cc6dce562ec Mon Sep 17 00:00:00 2001
From: Aliaksandr Valialkin <valyala@victoriametrics.com>
Date: Tue, 23 Jan 2024 01:06:45 +0200
Subject: [PATCH] app/vmselect/netstorage: avoid metricName->blockRef lookup
 when processing multiple blocks for the same time series

This saves a few CPU cycles for common case
---
 app/vmselect/netstorage/netstorage.go | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/app/vmselect/netstorage/netstorage.go b/app/vmselect/netstorage/netstorage.go
index 6f1c3483ce..7c64feba04 100644
--- a/app/vmselect/netstorage/netstorage.go
+++ b/app/vmselect/netstorage/netstorage.go
@@ -1375,6 +1375,12 @@ type tmpBlocksFileWrapperShard struct {
 	// orderedMetricNames contains metric names in the order of their load.
 	// This order is important for sequential read of data from tmpBlocksFile.
 	orderedMetricNames []string
+
+	// prevMetricName contains the metric name previously seen at RegisterAndWriteBlock.
+	prevMetricName []byte
+
+	// prevAddrsIdx contains the addrssPool index previously seen at RegisterAndWriteBlock.
+	prevAddrsIdx int
 }
 
 type tmpBlocksFileWrapperShardWithPadding struct {
@@ -1431,13 +1437,21 @@ func (tbfw *tmpBlocksFileWrapper) RegisterAndWriteBlock(mb *storage.MetricBlock,
 	if err != nil {
 		return err
 	}
-	metricName := mb.MetricName
+
 	m := tbfwLocal.m
-	addrsIdx, ok := m[string(metricName)]
-	if !ok {
-		addrsIdx = tbfwLocal.newBlockAddrs()
+	metricName := mb.MetricName
+	addrsIdx := tbfwLocal.prevAddrsIdx
+	if tbfwLocal.prevMetricName == nil || string(metricName) != string(tbfwLocal.prevMetricName) {
+		idx, ok := m[string(metricName)]
+		if !ok {
+			idx = tbfwLocal.newBlockAddrs()
+		}
+		addrsIdx = idx
+		tbfwLocal.prevMetricName = append(tbfwLocal.prevMetricName[:0], metricName...)
+		tbfwLocal.prevAddrsIdx = addrsIdx
 	}
 	addrs := &tbfwLocal.addrssPool[addrsIdx]
+
 	addrsPool := tbfwLocal.addrsPool
 	if addrs.addrs == nil || haveSameBlockAddrTails(addrs.addrs, addrsPool) {
 		// It is safe appending addr to addrsPool, since there are no other items added there yet.
@@ -1449,6 +1463,7 @@ func (tbfw *tmpBlocksFileWrapper) RegisterAndWriteBlock(mb *storage.MetricBlock,
 		// So just append it to addrs.addrs.
 		addrs.addrs = append(addrs.addrs, addr)
 	}
+
 	if len(addrs.addrs) == 1 {
 		metricNamesBuf := tbfwLocal.metricNamesBuf
 		metricNamesBufLen := len(metricNamesBuf)
@@ -1462,6 +1477,7 @@ func (tbfw *tmpBlocksFileWrapper) RegisterAndWriteBlock(mb *storage.MetricBlock,
 		tbfwLocal.orderedMetricNames = orderedMetricNames
 		tbfwLocal.metricNamesBuf = metricNamesBuf
 	}
+
 	return nil
 }