mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/protoparser/datadog: optimize sanitizeName() function by using result cache for input strings
This is a follow-up for 7c2474dac7
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3105
This commit is contained in:
parent
ef435f8cc4
commit
92b3622253
1 changed files with 36 additions and 5 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"io"
|
||||
"regexp"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
|
||||
|
@ -155,15 +156,45 @@ var requestPool sync.Pool
|
|||
// sanitizeName performs DataDog-compatible santizing for metric names
|
||||
//
|
||||
// See https://docs.datadoghq.com/metrics/custom_metrics/#naming-custom-metrics
|
||||
func sanitizeName(s string) string {
|
||||
s = unsupportedDatadogChars.ReplaceAllString(s, "_")
|
||||
s = multiUnderscores.ReplaceAllString(s, "_")
|
||||
s = underscoresWithDots.ReplaceAllString(s, ".")
|
||||
return s
|
||||
func sanitizeName(name string) string {
|
||||
m := sanitizedNames.Load().(*sync.Map)
|
||||
v, ok := m.Load(name)
|
||||
if ok {
|
||||
// Fast path - the sanitized name is found in the cache.
|
||||
sp := v.(*string)
|
||||
return *sp
|
||||
}
|
||||
// Slow path - sanitize name and store it in the cache.
|
||||
sanitizedName := unsupportedDatadogChars.ReplaceAllString(name, "_")
|
||||
sanitizedName = multiUnderscores.ReplaceAllString(sanitizedName, "_")
|
||||
sanitizedName = underscoresWithDots.ReplaceAllString(sanitizedName, ".")
|
||||
// Make a copy of name in order to limit memory usage to the name length,
|
||||
// since the name may point to bigger string.
|
||||
s := string(append([]byte{}, name...))
|
||||
if sanitizedName == name {
|
||||
// point sanitizedName to just allocated s, since it may point to name,
|
||||
// which, in turn, can point to bigger string.
|
||||
sanitizedName = s
|
||||
}
|
||||
sp := &sanitizedName
|
||||
m.Store(s, sp)
|
||||
n := atomic.AddUint64(&sanitizedNamesLen, 1)
|
||||
if n > 100e3 {
|
||||
atomic.StoreUint64(&sanitizedNamesLen, 0)
|
||||
sanitizedNames.Store(&sync.Map{})
|
||||
}
|
||||
return sanitizedName
|
||||
}
|
||||
|
||||
var (
|
||||
sanitizedNames atomic.Value
|
||||
sanitizedNamesLen uint64
|
||||
|
||||
unsupportedDatadogChars = regexp.MustCompile(`[^0-9a-zA-Z_\.]+`)
|
||||
multiUnderscores = regexp.MustCompile(`_+`)
|
||||
underscoresWithDots = regexp.MustCompile(`_?\._?`)
|
||||
)
|
||||
|
||||
func init() {
|
||||
sanitizedNames.Store(&sync.Map{})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue