Files
traces/modules/frontend/cache_keys.go
Joe ElliottandGitHub 50db194080 BugFix: Blocks whose end second matches a query range throw an erroneous error (#4783)
* make block metas for search take a time.Time to force the caller to interpret their time correctly

Signed-off-by: Joe Elliott <[email protected]>

* Applied the same fix to cache key

Signed-off-by: Joe Elliott <[email protected]>

* linter i love you, but you you're bringing me down

Signed-off-by: Joe Elliott <[email protected]>

* maybe

Signed-off-by: Joe Elliott <[email protected]>

* only calculate start/end time once in tag sharder

Signed-off-by: Joe Elliott <[email protected]>

* push time.Time out one level

Signed-off-by: Joe Elliott <[email protected]>

---------

Signed-off-by: Joe Elliott <[email protected]>
2025-03-04 10:38:02 -05:00

65 lines
2.1 KiB
Go

package frontend
import (
"strconv"
"strings"
"time"
"github.com/grafana/tempo/tempodb/backend"
)
const (
cacheKeyPrefixSearchJob = "sj:"
cacheKeyPrefixSearchTag = "st:"
cacheKeyPrefixSearchTagValues = "stv:"
cacheKeyPrefixQueryRange = "qr:"
)
func searchJobCacheKey(tenant string, queryHash uint64, start, end time.Time, meta *backend.BlockMeta, startPage, pagesToSearch int) string {
return cacheKey(cacheKeyPrefixSearchJob, tenant, queryHash, start, end, meta, startPage, pagesToSearch)
}
func queryRangeCacheKey(tenant string, queryHash uint64, start, end time.Time, meta *backend.BlockMeta, startPage, pagesToSearch int) string {
return cacheKey(cacheKeyPrefixQueryRange, tenant, queryHash, start, end, meta, startPage, pagesToSearch)
}
// cacheKey returns a string that can be used as a cache key for a backend search job. if a valid key cannot be calculated
// it returns an empty string.
func cacheKey(prefix string, tenant string, queryHash uint64, start, end time.Time, meta *backend.BlockMeta, startPage, pagesToSearch int) string {
// if the query hash is 0 we can't cache. this may occur if the user is using the old search api
if queryHash == 0 {
return ""
}
// unless the search range completely encapsulates the block range we can't cache. this is b/c different search ranges will return different results
// for a given block unless the search range covers the entire block
if !(start.Before(meta.StartTime) && // search start is before block start
end.After(meta.EndTime)) { // search end is after block end
return ""
}
sb := strings.Builder{}
sb.Grow(len(prefix) +
len(tenant) +
1 + // :
20 + // query hash
1 + // :
36 + // block id
1 + // :
3 + // start page
1 + // :
2) // 2 for pages to search
sb.WriteString(prefix)
sb.WriteString(tenant)
sb.WriteString(":")
sb.WriteString(strconv.FormatUint(queryHash, 10))
sb.WriteString(":")
sb.WriteString(meta.BlockID.String())
sb.WriteString(":")
sb.WriteString(strconv.Itoa(startPage))
sb.WriteString(":")
sb.WriteString(strconv.Itoa(pagesToSearch))
return sb.String()
}