mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib: consistently use atomic.* types instead of atomic.* functions
See ea9e2b19a5
This commit is contained in:
parent
d5ca67e667
commit
7e1dd8ab9d
39 changed files with 183 additions and 189 deletions
|
@ -8,7 +8,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmagent/csvimport"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmagent/csvimport"
|
||||||
|
@ -459,7 +458,7 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
return true
|
return true
|
||||||
case "/ready":
|
case "/ready":
|
||||||
if rdy := atomic.LoadInt32(&promscrape.PendingScrapeConfigs); rdy > 0 {
|
if rdy := promscrape.PendingScrapeConfigs.Load(); rdy > 0 {
|
||||||
errMsg := fmt.Sprintf("waiting for scrapes to init, left: %d", rdy)
|
errMsg := fmt.Sprintf("waiting for scrapes to init, left: %d", rdy)
|
||||||
http.Error(w, errMsg, http.StatusTooEarly)
|
http.Error(w, errMsg, http.StatusTooEarly)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"github.com/VictoriaMetrics/metrics"
|
||||||
|
@ -354,7 +353,7 @@ func RequestHandler(w http.ResponseWriter, r *http.Request) bool {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
return true
|
return true
|
||||||
case "/ready":
|
case "/ready":
|
||||||
if rdy := atomic.LoadInt32(&promscrape.PendingScrapeConfigs); rdy > 0 {
|
if rdy := promscrape.PendingScrapeConfigs.Load(); rdy > 0 {
|
||||||
errMsg := fmt.Sprintf("waiting for scrape config to init targets, configs left: %d", rdy)
|
errMsg := fmt.Sprintf("waiting for scrape config to init targets, configs left: %d", rdy)
|
||||||
http.Error(w, errMsg, http.StatusTooEarly)
|
http.Error(w, errMsg, http.StatusTooEarly)
|
||||||
} else {
|
} else {
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -8,7 +8,7 @@ require (
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0
|
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.0
|
||||||
github.com/VictoriaMetrics/easyproto v0.1.4
|
github.com/VictoriaMetrics/easyproto v0.1.4
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.2
|
github.com/VictoriaMetrics/fastcache v1.12.2
|
||||||
github.com/VictoriaMetrics/metrics v1.32.0
|
github.com/VictoriaMetrics/metrics v1.33.0
|
||||||
github.com/VictoriaMetrics/metricsql v0.74.0
|
github.com/VictoriaMetrics/metricsql v0.74.0
|
||||||
github.com/aws/aws-sdk-go-v2 v1.25.0
|
github.com/aws/aws-sdk-go-v2 v1.25.0
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.27.0
|
github.com/aws/aws-sdk-go-v2/config v1.27.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -69,8 +69,8 @@ github.com/VictoriaMetrics/easyproto v0.1.4/go.mod h1:QlGlzaJnDfFd8Lk6Ci/fuLxfTo
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI=
|
github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI=
|
||||||
github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI=
|
github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI=
|
||||||
github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys=
|
github.com/VictoriaMetrics/metrics v1.24.0/go.mod h1:eFT25kvsTidQFHb6U0oa0rTrDRdz4xTYjpL8+UPohys=
|
||||||
github.com/VictoriaMetrics/metrics v1.32.0 h1:r9JK2zndYv0TIxFXLEHwhQqRdnu8/O3cwJiCBX4vJCM=
|
github.com/VictoriaMetrics/metrics v1.33.0 h1:EnkDEaGiL2u95t+W76GfecC/LMYpy+tFrexYzBWQIAc=
|
||||||
github.com/VictoriaMetrics/metrics v1.32.0/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8=
|
github.com/VictoriaMetrics/metrics v1.33.0/go.mod h1:r7hveu6xMdUACXvB8TYdAj8WEsKzWB0EkpJN+RDtOf8=
|
||||||
github.com/VictoriaMetrics/metricsql v0.74.0 h1:bVO7USXBBYEuEHQ3PZg/6216j0DvblZM+Q8sTRECkv0=
|
github.com/VictoriaMetrics/metricsql v0.74.0 h1:bVO7USXBBYEuEHQ3PZg/6216j0DvblZM+Q8sTRECkv0=
|
||||||
github.com/VictoriaMetrics/metricsql v0.74.0/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I=
|
github.com/VictoriaMetrics/metricsql v0.74.0/go.mod h1:k4UaP/+CjuZslIjd+kCigNG9TQmUqh5v0TP/nMEy90I=
|
||||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||||
|
|
|
@ -46,14 +46,14 @@ func (p *Part) key() string {
|
||||||
// so it must have an unique key in order to always copy it during
|
// so it must have an unique key in order to always copy it during
|
||||||
// backup, restore and server-side copy.
|
// backup, restore and server-side copy.
|
||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5005
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5005
|
||||||
id := atomic.AddUint64(&uniqueKeyID, 1)
|
id := uniqueKeyID.Add(1)
|
||||||
return fmt.Sprintf("unique-%016X", id)
|
return fmt.Sprintf("unique-%016X", id)
|
||||||
}
|
}
|
||||||
// Do not use p.FileSize in the key, since it cannot be properly initialized when resuming the restore for partially restored file
|
// Do not use p.FileSize in the key, since it cannot be properly initialized when resuming the restore for partially restored file
|
||||||
return fmt.Sprintf("%s%016X%016X%016X", p.Path, p.Offset, p.Size, p.ActualSize)
|
return fmt.Sprintf("%s%016X%016X%016X", p.Path, p.Offset, p.Size, p.ActualSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
var uniqueKeyID uint64
|
var uniqueKeyID atomic.Uint64
|
||||||
|
|
||||||
// String returns human-readable representation of the part.
|
// String returns human-readable representation of the part.
|
||||||
func (p *Part) String() string {
|
func (p *Part) String() string {
|
||||||
|
|
|
@ -172,14 +172,11 @@ func (c *Cache) cleanPerKeyMisses() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type cache struct {
|
type cache struct {
|
||||||
// Atomically updated fields must go first in the struct, so they are properly
|
requests atomic.Uint64
|
||||||
// aligned to 8 bytes on 32-bit architectures.
|
misses atomic.Uint64
|
||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/212
|
|
||||||
requests uint64
|
|
||||||
misses uint64
|
|
||||||
|
|
||||||
// sizeBytes contains an approximate size for all the blocks stored in the cache.
|
// sizeBytes contains an approximate size for all the blocks stored in the cache.
|
||||||
sizeBytes int64
|
sizeBytes atomic.Int64
|
||||||
|
|
||||||
// getMaxSizeBytes() is a callback, which returns the maximum allowed cache size in bytes.
|
// getMaxSizeBytes() is a callback, which returns the maximum allowed cache size in bytes.
|
||||||
getMaxSizeBytes func() int
|
getMaxSizeBytes func() int
|
||||||
|
@ -256,7 +253,7 @@ func (c *cache) RemoveBlocksForPart(p interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) updateSizeBytes(n int) {
|
func (c *cache) updateSizeBytes(n int) {
|
||||||
atomic.AddInt64(&c.sizeBytes, int64(n))
|
c.sizeBytes.Add(int64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) cleanPerKeyMisses() {
|
func (c *cache) cleanPerKeyMisses() {
|
||||||
|
@ -281,7 +278,7 @@ func (c *cache) cleanByTimeout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) GetBlock(k Key) Block {
|
func (c *cache) GetBlock(k Key) Block {
|
||||||
atomic.AddUint64(&c.requests, 1)
|
c.requests.Add(1)
|
||||||
var e *cacheEntry
|
var e *cacheEntry
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
@ -301,7 +298,7 @@ func (c *cache) GetBlock(k Key) Block {
|
||||||
}
|
}
|
||||||
// Slow path - the entry is missing in the cache.
|
// Slow path - the entry is missing in the cache.
|
||||||
c.perKeyMisses[k]++
|
c.perKeyMisses[k]++
|
||||||
atomic.AddUint64(&c.misses, 1)
|
c.misses.Add(1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +364,7 @@ func (c *cache) Len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) SizeBytes() int {
|
func (c *cache) SizeBytes() int {
|
||||||
return int(atomic.LoadInt64(&c.sizeBytes))
|
return int(c.sizeBytes.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) SizeMaxBytes() int {
|
func (c *cache) SizeMaxBytes() int {
|
||||||
|
@ -375,11 +372,11 @@ func (c *cache) SizeMaxBytes() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) Requests() uint64 {
|
func (c *cache) Requests() uint64 {
|
||||||
return atomic.LoadUint64(&c.requests)
|
return c.requests.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) Misses() uint64 {
|
func (c *cache) Misses() uint64 {
|
||||||
return atomic.LoadUint64(&c.misses)
|
return c.misses.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// lastAccessHeap implements heap.Interface
|
// lastAccessHeap implements heap.Interface
|
||||||
|
|
|
@ -16,11 +16,11 @@ func BenchmarkKeyHashUint64(b *testing.B) {
|
||||||
h := k.hashUint64()
|
h := k.hashUint64()
|
||||||
hSum += h
|
hSum += h
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&BenchSink, hSum)
|
BenchSink.Add(hSum)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var BenchSink uint64
|
var BenchSink atomic.Uint64
|
||||||
|
|
||||||
func BenchmarkCacheGet(b *testing.B) {
|
func BenchmarkCacheGet(b *testing.B) {
|
||||||
c := NewCache(func() int {
|
c := NewCache(func() int {
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (l *Limiter) MaxItems() int {
|
||||||
// CurrentItems return the current number of items registered in l.
|
// CurrentItems return the current number of items registered in l.
|
||||||
func (l *Limiter) CurrentItems() int {
|
func (l *Limiter) CurrentItems() int {
|
||||||
lm := l.v.Load()
|
lm := l.v.Load()
|
||||||
n := atomic.LoadUint64(&lm.currentItems)
|
n := lm.currentItems.Load()
|
||||||
return int(n)
|
return int(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ func (l *Limiter) Add(h uint64) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
type limiter struct {
|
type limiter struct {
|
||||||
currentItems uint64
|
currentItems atomic.Uint64
|
||||||
f *filter
|
f *filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,12 +83,12 @@ func newLimiter(maxItems int) *limiter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *limiter) Add(h uint64) bool {
|
func (l *limiter) Add(h uint64) bool {
|
||||||
currentItems := atomic.LoadUint64(&l.currentItems)
|
currentItems := l.currentItems.Load()
|
||||||
if currentItems >= uint64(l.f.maxItems) {
|
if currentItems >= uint64(l.f.maxItems) {
|
||||||
return l.f.Has(h)
|
return l.f.Has(h)
|
||||||
}
|
}
|
||||||
if l.f.Add(h) {
|
if l.f.Add(h) {
|
||||||
atomic.AddUint64(&l.currentItems, 1)
|
l.currentItems.Add(1)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func BenchmarkToUnsafeString(b *testing.B) {
|
||||||
n += len(s)
|
n += len(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(n))
|
Sink.Add(uint64(n))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ func BenchmarkToUnsafeBytes(b *testing.B) {
|
||||||
n += len(s)
|
n += len(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(n))
|
Sink.Add(uint64(n))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var Sink uint64
|
var Sink atomic.Uint64
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// It caches string match results and returns them back on the next calls
|
// It caches string match results and returns them back on the next calls
|
||||||
// without calling the matchFunc, which may be expensive.
|
// without calling the matchFunc, which may be expensive.
|
||||||
type FastStringMatcher struct {
|
type FastStringMatcher struct {
|
||||||
lastCleanupTime uint64
|
lastCleanupTime atomic.Uint64
|
||||||
|
|
||||||
m sync.Map
|
m sync.Map
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ type FastStringMatcher struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type fsmEntry struct {
|
type fsmEntry struct {
|
||||||
lastAccessTime uint64
|
lastAccessTime atomic.Uint64
|
||||||
ok bool
|
ok bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,11 @@ type fsmEntry struct {
|
||||||
//
|
//
|
||||||
// matchFunc must return the same result for the same input.
|
// matchFunc must return the same result for the same input.
|
||||||
func NewFastStringMatcher(matchFunc func(s string) bool) *FastStringMatcher {
|
func NewFastStringMatcher(matchFunc func(s string) bool) *FastStringMatcher {
|
||||||
return &FastStringMatcher{
|
fsm := &FastStringMatcher{
|
||||||
lastCleanupTime: fasttime.UnixTimestamp(),
|
|
||||||
matchFunc: matchFunc,
|
matchFunc: matchFunc,
|
||||||
}
|
}
|
||||||
|
fsm.lastCleanupTime.Store(fasttime.UnixTimestamp())
|
||||||
|
return fsm
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match applies matchFunc to s and returns the result.
|
// Match applies matchFunc to s and returns the result.
|
||||||
|
@ -46,19 +47,19 @@ func (fsm *FastStringMatcher) Match(s string) bool {
|
||||||
if ok {
|
if ok {
|
||||||
// Fast path - s match result is found in the cache.
|
// Fast path - s match result is found in the cache.
|
||||||
e := v.(*fsmEntry)
|
e := v.(*fsmEntry)
|
||||||
if atomic.LoadUint64(&e.lastAccessTime)+10 < ct {
|
if e.lastAccessTime.Load()+10 < ct {
|
||||||
// Reduce the frequency of e.lastAccessTime update to once per 10 seconds
|
// Reduce the frequency of e.lastAccessTime update to once per 10 seconds
|
||||||
// in order to improve the fast path speed on systems with many CPU cores.
|
// in order to improve the fast path speed on systems with many CPU cores.
|
||||||
atomic.StoreUint64(&e.lastAccessTime, ct)
|
e.lastAccessTime.Store(ct)
|
||||||
}
|
}
|
||||||
return e.ok
|
return e.ok
|
||||||
}
|
}
|
||||||
// Slow path - run matchFunc for s and store the result in the cache.
|
// Slow path - run matchFunc for s and store the result in the cache.
|
||||||
b := fsm.matchFunc(s)
|
b := fsm.matchFunc(s)
|
||||||
e := &fsmEntry{
|
e := &fsmEntry{
|
||||||
lastAccessTime: ct,
|
|
||||||
ok: b,
|
ok: b,
|
||||||
}
|
}
|
||||||
|
e.lastAccessTime.Store(ct)
|
||||||
// Make a copy of s in order to limit memory usage to the s length,
|
// Make a copy of s in order to limit memory usage to the s length,
|
||||||
// since the s may point to bigger string.
|
// since the s may point to bigger string.
|
||||||
// This also protects from the case when s contains unsafe string, which points to a temporary byte slice.
|
// This also protects from the case when s contains unsafe string, which points to a temporary byte slice.
|
||||||
|
@ -72,7 +73,7 @@ func (fsm *FastStringMatcher) Match(s string) bool {
|
||||||
deadline := ct - uint64(cacheExpireDuration.Seconds())
|
deadline := ct - uint64(cacheExpireDuration.Seconds())
|
||||||
m.Range(func(k, v interface{}) bool {
|
m.Range(func(k, v interface{}) bool {
|
||||||
e := v.(*fsmEntry)
|
e := v.(*fsmEntry)
|
||||||
if atomic.LoadUint64(&e.lastAccessTime) < deadline {
|
if e.lastAccessTime.Load() < deadline {
|
||||||
m.Delete(k)
|
m.Delete(k)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -82,13 +83,13 @@ func (fsm *FastStringMatcher) Match(s string) bool {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func needCleanup(lastCleanupTime *uint64, currentTime uint64) bool {
|
func needCleanup(lastCleanupTime *atomic.Uint64, currentTime uint64) bool {
|
||||||
lct := atomic.LoadUint64(lastCleanupTime)
|
lct := lastCleanupTime.Load()
|
||||||
if lct+61 >= currentTime {
|
if lct+61 >= currentTime {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Atomically compare and swap the current time with the lastCleanupTime
|
// Atomically compare and swap the current time with the lastCleanupTime
|
||||||
// in order to guarantee that only a single goroutine out of multiple
|
// in order to guarantee that only a single goroutine out of multiple
|
||||||
// concurrently executing goroutines gets true from the call.
|
// concurrently executing goroutines gets true from the call.
|
||||||
return atomic.CompareAndSwapUint64(lastCleanupTime, lct, currentTime)
|
return lastCleanupTime.CompareAndSwap(lct, currentTime)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package bytesutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,18 +28,19 @@ func TestFastStringMatcher(t *testing.T) {
|
||||||
func TestNeedCleanup(t *testing.T) {
|
func TestNeedCleanup(t *testing.T) {
|
||||||
f := func(lastCleanupTime, currentTime uint64, resultExpected bool) {
|
f := func(lastCleanupTime, currentTime uint64, resultExpected bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
lct := lastCleanupTime
|
var lct atomic.Uint64
|
||||||
|
lct.Store(lastCleanupTime)
|
||||||
result := needCleanup(&lct, currentTime)
|
result := needCleanup(&lct, currentTime)
|
||||||
if result != resultExpected {
|
if result != resultExpected {
|
||||||
t.Fatalf("unexpected result for needCleanup(%d, %d); got %v; want %v", lastCleanupTime, currentTime, result, resultExpected)
|
t.Fatalf("unexpected result for needCleanup(%d, %d); got %v; want %v", lastCleanupTime, currentTime, result, resultExpected)
|
||||||
}
|
}
|
||||||
if result {
|
if result {
|
||||||
if lct != currentTime {
|
if n := lct.Load(); n != currentTime {
|
||||||
t.Fatalf("unexpected value for lct; got %d; want currentTime=%d", lct, currentTime)
|
t.Fatalf("unexpected value for lct; got %d; want currentTime=%d", n, currentTime)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if lct != lastCleanupTime {
|
if n := lct.Load(); n != lastCleanupTime {
|
||||||
t.Fatalf("unexpected value for lct; got %d; want lastCleanupTime=%d", lct, lastCleanupTime)
|
t.Fatalf("unexpected value for lct; got %d; want lastCleanupTime=%d", n, lastCleanupTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package bytesutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,6 +27,6 @@ func benchmarkFastStringMatcher(b *testing.B, s string) {
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&GlobalSink, n)
|
GlobalSink.Add(n)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// It caches transformed strings and returns them back on the next calls
|
// It caches transformed strings and returns them back on the next calls
|
||||||
// without calling the transformFunc, which may be expensive.
|
// without calling the transformFunc, which may be expensive.
|
||||||
type FastStringTransformer struct {
|
type FastStringTransformer struct {
|
||||||
lastCleanupTime uint64
|
lastCleanupTime atomic.Uint64
|
||||||
|
|
||||||
m sync.Map
|
m sync.Map
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ type FastStringTransformer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type fstEntry struct {
|
type fstEntry struct {
|
||||||
lastAccessTime uint64
|
lastAccessTime atomic.Uint64
|
||||||
s string
|
s string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,11 @@ type fstEntry struct {
|
||||||
//
|
//
|
||||||
// transformFunc must return the same result for the same input.
|
// transformFunc must return the same result for the same input.
|
||||||
func NewFastStringTransformer(transformFunc func(s string) string) *FastStringTransformer {
|
func NewFastStringTransformer(transformFunc func(s string) string) *FastStringTransformer {
|
||||||
return &FastStringTransformer{
|
fst := &FastStringTransformer{
|
||||||
lastCleanupTime: fasttime.UnixTimestamp(),
|
|
||||||
transformFunc: transformFunc,
|
transformFunc: transformFunc,
|
||||||
}
|
}
|
||||||
|
fst.lastCleanupTime.Store(fasttime.UnixTimestamp())
|
||||||
|
return fst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform applies transformFunc to s and returns the result.
|
// Transform applies transformFunc to s and returns the result.
|
||||||
|
@ -52,10 +53,10 @@ func (fst *FastStringTransformer) Transform(s string) string {
|
||||||
if ok {
|
if ok {
|
||||||
// Fast path - the transformed s is found in the cache.
|
// Fast path - the transformed s is found in the cache.
|
||||||
e := v.(*fstEntry)
|
e := v.(*fstEntry)
|
||||||
if atomic.LoadUint64(&e.lastAccessTime)+10 < ct {
|
if e.lastAccessTime.Load()+10 < ct {
|
||||||
// Reduce the frequency of e.lastAccessTime update to once per 10 seconds
|
// Reduce the frequency of e.lastAccessTime update to once per 10 seconds
|
||||||
// in order to improve the fast path speed on systems with many CPU cores.
|
// in order to improve the fast path speed on systems with many CPU cores.
|
||||||
atomic.StoreUint64(&e.lastAccessTime, ct)
|
e.lastAccessTime.Store(ct)
|
||||||
}
|
}
|
||||||
return e.s
|
return e.s
|
||||||
}
|
}
|
||||||
|
@ -72,9 +73,9 @@ func (fst *FastStringTransformer) Transform(s string) string {
|
||||||
sTransformed = s
|
sTransformed = s
|
||||||
}
|
}
|
||||||
e := &fstEntry{
|
e := &fstEntry{
|
||||||
lastAccessTime: ct,
|
|
||||||
s: sTransformed,
|
s: sTransformed,
|
||||||
}
|
}
|
||||||
|
e.lastAccessTime.Store(ct)
|
||||||
fst.m.Store(s, e)
|
fst.m.Store(s, e)
|
||||||
|
|
||||||
if needCleanup(&fst.lastCleanupTime, ct) {
|
if needCleanup(&fst.lastCleanupTime, ct) {
|
||||||
|
@ -83,7 +84,7 @@ func (fst *FastStringTransformer) Transform(s string) string {
|
||||||
deadline := ct - uint64(cacheExpireDuration.Seconds())
|
deadline := ct - uint64(cacheExpireDuration.Seconds())
|
||||||
m.Range(func(k, v interface{}) bool {
|
m.Range(func(k, v interface{}) bool {
|
||||||
e := v.(*fstEntry)
|
e := v.(*fstEntry)
|
||||||
if atomic.LoadUint64(&e.lastAccessTime) < deadline {
|
if e.lastAccessTime.Load() < deadline {
|
||||||
m.Delete(k)
|
m.Delete(k)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -24,8 +24,8 @@ func benchmarkFastStringTransformer(b *testing.B, s string) {
|
||||||
sTransformed := fst.Transform(s)
|
sTransformed := fst.Transform(s)
|
||||||
n += uint64(len(sTransformed))
|
n += uint64(len(sTransformed))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&GlobalSink, n)
|
GlobalSink.Add(n)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var GlobalSink uint64
|
var GlobalSink atomic.Uint64
|
||||||
|
|
|
@ -42,19 +42,19 @@ func InternString(s string) string {
|
||||||
ct := fasttime.UnixTimestamp()
|
ct := fasttime.UnixTimestamp()
|
||||||
if v, ok := internStringsMap.Load(s); ok {
|
if v, ok := internStringsMap.Load(s); ok {
|
||||||
e := v.(*ismEntry)
|
e := v.(*ismEntry)
|
||||||
if atomic.LoadUint64(&e.lastAccessTime)+10 < ct {
|
if e.lastAccessTime.Load()+10 < ct {
|
||||||
// Reduce the frequency of e.lastAccessTime update to once per 10 seconds
|
// Reduce the frequency of e.lastAccessTime update to once per 10 seconds
|
||||||
// in order to improve the fast path speed on systems with many CPU cores.
|
// in order to improve the fast path speed on systems with many CPU cores.
|
||||||
atomic.StoreUint64(&e.lastAccessTime, ct)
|
e.lastAccessTime.Store(ct)
|
||||||
}
|
}
|
||||||
return e.s
|
return e.s
|
||||||
}
|
}
|
||||||
// Make a new copy for s in order to remove references from possible bigger string s refers to.
|
// Make a new copy for s in order to remove references from possible bigger string s refers to.
|
||||||
sCopy := strings.Clone(s)
|
sCopy := strings.Clone(s)
|
||||||
e := &ismEntry{
|
e := &ismEntry{
|
||||||
lastAccessTime: ct,
|
|
||||||
s: sCopy,
|
s: sCopy,
|
||||||
}
|
}
|
||||||
|
e.lastAccessTime.Store(ct)
|
||||||
internStringsMap.Store(sCopy, e)
|
internStringsMap.Store(sCopy, e)
|
||||||
|
|
||||||
if needCleanup(&internStringsMapLastCleanupTime, ct) {
|
if needCleanup(&internStringsMapLastCleanupTime, ct) {
|
||||||
|
@ -63,7 +63,7 @@ func InternString(s string) string {
|
||||||
deadline := ct - uint64(cacheExpireDuration.Seconds())
|
deadline := ct - uint64(cacheExpireDuration.Seconds())
|
||||||
m.Range(func(k, v interface{}) bool {
|
m.Range(func(k, v interface{}) bool {
|
||||||
e := v.(*ismEntry)
|
e := v.(*ismEntry)
|
||||||
if atomic.LoadUint64(&e.lastAccessTime) < deadline {
|
if e.lastAccessTime.Load() < deadline {
|
||||||
m.Delete(k)
|
m.Delete(k)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -74,11 +74,11 @@ func InternString(s string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ismEntry struct {
|
type ismEntry struct {
|
||||||
lastAccessTime uint64
|
lastAccessTime atomic.Uint64
|
||||||
s string
|
s string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
internStringsMap sync.Map
|
internStringsMap sync.Map
|
||||||
internStringsMapLastCleanupTime uint64
|
internStringsMapLastCleanupTime atomic.Uint64
|
||||||
)
|
)
|
||||||
|
|
|
@ -51,7 +51,7 @@ func benchmarkAppendDecimalToFloat(b *testing.B, a []int64, scale int16) {
|
||||||
var fa []float64
|
var fa []float64
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
fa = AppendDecimalToFloat(fa[:0], a, scale)
|
fa = AppendDecimalToFloat(fa[:0], a, scale)
|
||||||
atomic.AddUint64(&Sink, uint64(len(fa)))
|
Sink.Add(uint64(len(fa)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func benchmarkAppendFloatToDecimal(b *testing.B, fa []float64) {
|
||||||
sink += uint64(len(da))
|
sink += uint64(len(da))
|
||||||
sink += uint64(e)
|
sink += uint64(e)
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +138,10 @@ func BenchmarkFromFloat(b *testing.B) {
|
||||||
sink += uint64(v)
|
sink += uint64(v)
|
||||||
sink += uint64(e)
|
sink += uint64(e)
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Sink uint64
|
var Sink atomic.Uint64
|
||||||
|
|
|
@ -18,12 +18,12 @@ func BenchmarkMarshalGaugeArray(b *testing.B) {
|
||||||
if mt != MarshalTypeZSTDNearestDelta {
|
if mt != MarshalTypeZSTDNearestDelta {
|
||||||
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeZSTDNearestDelta))
|
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeZSTDNearestDelta))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var Sink uint64
|
var Sink atomic.Uint64
|
||||||
|
|
||||||
func BenchmarkUnmarshalGaugeArray(b *testing.B) {
|
func BenchmarkUnmarshalGaugeArray(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
@ -36,7 +36,7 @@ func BenchmarkUnmarshalGaugeArray(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot unmarshal gauge array: %w", err))
|
panic(fmt.Errorf("cannot unmarshal gauge array: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func BenchmarkMarshalDeltaConstArray(b *testing.B) {
|
||||||
if mt != MarshalTypeDeltaConst {
|
if mt != MarshalTypeDeltaConst {
|
||||||
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeDeltaConst))
|
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeDeltaConst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ func BenchmarkUnmarshalDeltaConstArray(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot unmarshal delta const array: %w", err))
|
panic(fmt.Errorf("cannot unmarshal delta const array: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ func BenchmarkMarshalConstArray(b *testing.B) {
|
||||||
if mt != MarshalTypeConst {
|
if mt != MarshalTypeConst {
|
||||||
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeConst))
|
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeConst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ func BenchmarkUnmarshalConstArray(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot unmarshal const array: %w", err))
|
panic(fmt.Errorf("cannot unmarshal const array: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func BenchmarkMarshalZeroConstArray(b *testing.B) {
|
||||||
if mt != MarshalTypeConst {
|
if mt != MarshalTypeConst {
|
||||||
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeConst))
|
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, MarshalTypeConst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ func BenchmarkUnmarshalZeroConstArray(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot unmarshal zero const array: %w", err))
|
panic(fmt.Errorf("cannot unmarshal zero const array: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ func BenchmarkMarshalInt64Array(b *testing.B) {
|
||||||
if mt != benchMarshalType {
|
if mt != benchMarshalType {
|
||||||
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, benchMarshalType))
|
panic(fmt.Errorf("unexpected marshal type; got %d; expecting %d", mt, benchMarshalType))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ func BenchmarkUnmarshalInt64Array(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot unmarshal int64 array: %w", err))
|
panic(fmt.Errorf("cannot unmarshal int64 array: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package encoding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +15,7 @@ func BenchmarkMarshalUint64(b *testing.B) {
|
||||||
dst = MarshalUint64(dst[:0], sink)
|
dst = MarshalUint64(dst[:0], sink)
|
||||||
sink += uint64(len(dst))
|
sink += uint64(len(dst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +28,7 @@ func BenchmarkUnmarshalUint64(b *testing.B) {
|
||||||
v := UnmarshalUint64(testMarshaledUint64Data)
|
v := UnmarshalUint64(testMarshaledUint64Data)
|
||||||
sink += v
|
sink += v
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +42,7 @@ func BenchmarkMarshalInt64(b *testing.B) {
|
||||||
dst = MarshalInt64(dst[:0], int64(sink))
|
dst = MarshalInt64(dst[:0], int64(sink))
|
||||||
sink += uint64(len(dst))
|
sink += uint64(len(dst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ func BenchmarkUnmarshalInt64(b *testing.B) {
|
||||||
v := UnmarshalInt64(testMarshaledInt64Data)
|
v := UnmarshalInt64(testMarshaledInt64Data)
|
||||||
sink += uint64(v)
|
sink += uint64(v)
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +95,7 @@ func benchmarkMarshalVarUint64s(b *testing.B, maxValue uint64) {
|
||||||
dst = MarshalVarUint64s(dst[:0], data)
|
dst = MarshalVarUint64s(dst[:0], data)
|
||||||
sink += uint64(len(dst))
|
sink += uint64(len(dst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +135,7 @@ func benchmarkMarshalVarInt64s(b *testing.B, maxValue int64) {
|
||||||
dst = MarshalVarInt64s(dst[:0], data)
|
dst = MarshalVarInt64s(dst[:0], data)
|
||||||
sink += uint64(len(dst))
|
sink += uint64(len(dst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +181,7 @@ func benchmarkUnmarshalVarUint64s(b *testing.B, maxValue uint64) {
|
||||||
}
|
}
|
||||||
sink += uint64(len(dst))
|
sink += uint64(len(dst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +227,7 @@ func benchmarkUnmarshalVarInt64s(b *testing.B, maxValue int64) {
|
||||||
}
|
}
|
||||||
sink += uint64(len(dst))
|
sink += uint64(len(dst))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, sink)
|
Sink.Add(sink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package encoding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ func benchmarkMarshalInt64NearestDelta2(b *testing.B, precisionBits uint8) {
|
||||||
var dst []byte
|
var dst []byte
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
dst, _ = marshalInt64NearestDelta2(dst[:0], benchInt64Array, precisionBits)
|
dst, _ = marshalInt64NearestDelta2(dst[:0], benchInt64Array, precisionBits)
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -37,7 +36,7 @@ func BenchmarkUnmarshalInt64NearestDelta2(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("unexpected error: %w", err))
|
panic(fmt.Errorf("unexpected error: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package encoding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ func benchmarkMarshalInt64NearestDelta(b *testing.B, precisionBits uint8) {
|
||||||
var dst []byte
|
var dst []byte
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
dst, _ = marshalInt64NearestDelta(dst[:0], benchInt64Array, precisionBits)
|
dst, _ = marshalInt64NearestDelta(dst[:0], benchInt64Array, precisionBits)
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -37,7 +36,7 @@ func BenchmarkUnmarshalInt64NearestDelta(b *testing.B) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("unexpected error: %w", err))
|
panic(fmt.Errorf("unexpected error: %w", err))
|
||||||
}
|
}
|
||||||
atomic.AddUint64(&Sink, uint64(len(dst)))
|
Sink.Add(uint64(len(dst)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,18 +11,22 @@ func init() {
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
for tm := range ticker.C {
|
for tm := range ticker.C {
|
||||||
t := uint64(tm.Unix())
|
t := uint64(tm.Unix())
|
||||||
atomic.StoreUint64(¤tTimestamp, t)
|
currentTimestamp.Store(t)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentTimestamp = uint64(time.Now().Unix())
|
var currentTimestamp = func() *atomic.Uint64 {
|
||||||
|
var x atomic.Uint64
|
||||||
|
x.Store(uint64(time.Now().Unix()))
|
||||||
|
return &x
|
||||||
|
}()
|
||||||
|
|
||||||
// UnixTimestamp returns the current unix timestamp in seconds.
|
// UnixTimestamp returns the current unix timestamp in seconds.
|
||||||
//
|
//
|
||||||
// It is faster than time.Now().Unix()
|
// It is faster than time.Now().Unix()
|
||||||
func UnixTimestamp() uint64 {
|
func UnixTimestamp() uint64 {
|
||||||
return atomic.LoadUint64(¤tTimestamp)
|
return currentTimestamp.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnixDate returns date from the current unix timestamp.
|
// UnixDate returns date from the current unix timestamp.
|
||||||
|
|
|
@ -13,7 +13,7 @@ func BenchmarkUnixTimestamp(b *testing.B) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
ts += UnixTimestamp()
|
ts += UnixTimestamp()
|
||||||
}
|
}
|
||||||
atomic.StoreUint64(&Sink, ts)
|
Sink.Store(ts)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ func BenchmarkTimeNowUnix(b *testing.B) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
ts += uint64(time.Now().Unix())
|
ts += uint64(time.Now().Unix())
|
||||||
}
|
}
|
||||||
atomic.StoreUint64(&Sink, ts)
|
Sink.Store(ts)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sink should prevent from code elimination by optimizing compiler
|
// Sink should prevent from code elimination by optimizing compiler
|
||||||
var Sink uint64
|
var Sink atomic.Uint64
|
||||||
|
|
|
@ -35,7 +35,7 @@ func NewPassword(name, description string) *Password {
|
||||||
// If the flag value is file:///path/to/file or http://host/path ,
|
// If the flag value is file:///path/to/file or http://host/path ,
|
||||||
// then its contents is automatically re-read from the given file or url
|
// then its contents is automatically re-read from the given file or url
|
||||||
type Password struct {
|
type Password struct {
|
||||||
nextRefreshTimestamp uint64
|
nextRefreshTimestamp atomic.Uint64
|
||||||
|
|
||||||
value atomic.Pointer[string]
|
value atomic.Pointer[string]
|
||||||
|
|
||||||
|
@ -62,14 +62,14 @@ func (p *Password) maybeRereadPassword() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tsCurr := fasttime.UnixTimestamp()
|
tsCurr := fasttime.UnixTimestamp()
|
||||||
tsNext := atomic.LoadUint64(&p.nextRefreshTimestamp)
|
tsNext := p.nextRefreshTimestamp.Load()
|
||||||
if tsCurr < tsNext {
|
if tsCurr < tsNext {
|
||||||
// Fast path - nothing to re-read
|
// Fast path - nothing to re-read
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-read password from p.sourcePath
|
// Re-read password from p.sourcePath
|
||||||
atomic.StoreUint64(&p.nextRefreshTimestamp, tsCurr+2)
|
p.nextRefreshTimestamp.Store(tsCurr + 2)
|
||||||
s, err := fscore.ReadPasswordFromFileOrHTTP(p.sourcePath)
|
s, err := fscore.ReadPasswordFromFileOrHTTP(p.sourcePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// cannot use lib/logger, since it can be uninitialized yet
|
// cannot use lib/logger, since it can be uninitialized yet
|
||||||
|
@ -86,7 +86,7 @@ func (p *Password) String() string {
|
||||||
|
|
||||||
// Set implements flag.Value interface.
|
// Set implements flag.Value interface.
|
||||||
func (p *Password) Set(value string) error {
|
func (p *Password) Set(value string) error {
|
||||||
atomic.StoreUint64(&p.nextRefreshTimestamp, 0)
|
p.nextRefreshTimestamp.Store(0)
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(value, "file://"):
|
case strings.HasPrefix(value, "file://"):
|
||||||
p.sourcePath = strings.TrimPrefix(value, "file://")
|
p.sourcePath = strings.TrimPrefix(value, "file://")
|
||||||
|
|
10
lib/fs/fs.go
10
lib/fs/fs.go
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tmpFileNum uint64
|
var tmpFileNum atomic.Uint64
|
||||||
|
|
||||||
// MustSyncPath syncs contents of the given path.
|
// MustSyncPath syncs contents of the given path.
|
||||||
func MustSyncPath(path string) {
|
func MustSyncPath(path string) {
|
||||||
|
@ -62,7 +62,7 @@ func MustWriteAtomic(path string, data []byte, canOverwrite bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write data to a temporary file.
|
// Write data to a temporary file.
|
||||||
n := atomic.AddUint64(&tmpFileNum, 1)
|
n := tmpFileNum.Add(1)
|
||||||
tmpPath := fmt.Sprintf("%s.tmp.%d", path, n)
|
tmpPath := fmt.Sprintf("%s.tmp.%d", path, n)
|
||||||
MustWriteSync(tmpPath, data)
|
MustWriteSync(tmpPath, data)
|
||||||
|
|
||||||
|
@ -207,7 +207,11 @@ func MustRemoveDirAtomic(dir string) {
|
||||||
MustSyncPath(parentDir)
|
MustSyncPath(parentDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
var atomicDirRemoveCounter = uint64(time.Now().UnixNano())
|
var atomicDirRemoveCounter = func() *atomic.Uint64 {
|
||||||
|
var x atomic.Uint64
|
||||||
|
x.Store(uint64(time.Now().UnixNano()))
|
||||||
|
return &x
|
||||||
|
}()
|
||||||
|
|
||||||
// MustReadDir reads directory entries at the given dir.
|
// MustReadDir reads directory entries at the given dir.
|
||||||
func MustReadDir(dir string) []os.DirEntry {
|
func MustReadDir(dir string) []os.DirEntry {
|
||||||
|
|
|
@ -5,7 +5,6 @@ package fs
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
@ -16,7 +15,7 @@ func freeSpace(stat unix.Statfs_t) uint64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustRemoveDirAtomic(dir string) {
|
func mustRemoveDirAtomic(dir string) {
|
||||||
n := atomic.AddUint64(&atomicDirRemoveCounter, 1)
|
n := atomicDirRemoveCounter.Add(1)
|
||||||
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
||||||
if err := os.Rename(dir, tmpDir); err != nil {
|
if err := os.Rename(dir, tmpDir); err != nil {
|
||||||
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
||||||
|
|
|
@ -3,7 +3,6 @@ package fs
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
@ -14,7 +13,7 @@ func freeSpace(stat unix.Statfs_t) uint64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustRemoveDirAtomic(dir string) {
|
func mustRemoveDirAtomic(dir string) {
|
||||||
n := atomic.AddUint64(&atomicDirRemoveCounter, 1)
|
n := atomicDirRemoveCounter.Add(1)
|
||||||
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
||||||
if err := os.Rename(dir, tmpDir); err != nil {
|
if err := os.Rename(dir, tmpDir); err != nil {
|
||||||
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
||||||
|
|
|
@ -3,14 +3,13 @@ package fs
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustRemoveDirAtomic(dir string) {
|
func mustRemoveDirAtomic(dir string) {
|
||||||
n := atomic.AddUint64(&atomicDirRemoveCounter, 1)
|
n := atomicDirRemoveCounter.Add(1)
|
||||||
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
||||||
if err := os.Rename(dir, tmpDir); err != nil {
|
if err := os.Rename(dir, tmpDir); err != nil {
|
||||||
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
|
||||||
|
@ -25,7 +24,7 @@ func mustSyncPath(path string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustRemoveDirAtomic(dir string) {
|
func mustRemoveDirAtomic(dir string) {
|
||||||
n := atomic.AddUint64(&atomicDirRemoveCounter, 1)
|
n := atomicDirRemoveCounter.Add(1)
|
||||||
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
tmpDir := fmt.Sprintf("%s.must-remove.%d", dir, n)
|
||||||
if err := os.Rename(dir, tmpDir); err != nil {
|
if err := os.Rename(dir, tmpDir); err != nil {
|
||||||
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
logger.Panicf("FATAL: cannot move %s to %s: %s", dir, tmpDir, err)
|
||||||
|
|
|
@ -32,8 +32,8 @@ type MustReadAtCloser interface {
|
||||||
|
|
||||||
// ReaderAt implements rand-access reader.
|
// ReaderAt implements rand-access reader.
|
||||||
type ReaderAt struct {
|
type ReaderAt struct {
|
||||||
readCalls uint64
|
readCalls atomic.Int64
|
||||||
readBytes uint64
|
readBytes atomic.Int64
|
||||||
|
|
||||||
// path contains the path to the file for reading
|
// path contains the path to the file for reading
|
||||||
path string
|
path string
|
||||||
|
@ -81,8 +81,8 @@ func (r *ReaderAt) MustReadAt(p []byte, off int64) {
|
||||||
copy(p, src)
|
copy(p, src)
|
||||||
}
|
}
|
||||||
if r.useLocalStats {
|
if r.useLocalStats {
|
||||||
atomic.AddUint64(&r.readCalls, 1)
|
r.readCalls.Add(1)
|
||||||
atomic.AddUint64(&r.readBytes, uint64(len(p)))
|
r.readBytes.Add(int64(len(p)))
|
||||||
} else {
|
} else {
|
||||||
readCalls.Inc()
|
readCalls.Inc()
|
||||||
readBytes.Add(len(p))
|
readBytes.Add(len(p))
|
||||||
|
@ -119,10 +119,10 @@ func (r *ReaderAt) MustClose() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.useLocalStats {
|
if r.useLocalStats {
|
||||||
readCalls.Add(int(r.readCalls))
|
readCalls.AddInt64(r.readCalls.Load())
|
||||||
readBytes.Add(int(r.readBytes))
|
readBytes.AddInt64(r.readBytes.Load())
|
||||||
r.readCalls = 0
|
r.readCalls.Store(0)
|
||||||
r.readBytes = 0
|
r.readBytes.Store(0)
|
||||||
r.useLocalStats = false
|
r.useLocalStats = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
shutdownDelayDeadline int64
|
shutdownDelayDeadline atomic.Int64
|
||||||
s *http.Server
|
s *http.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ func stop(addr string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
deadline := time.Now().Add(*shutdownDelay).UnixNano()
|
deadline := time.Now().Add(*shutdownDelay).UnixNano()
|
||||||
atomic.StoreInt64(&s.shutdownDelayDeadline, deadline)
|
s.shutdownDelayDeadline.Store(deadline)
|
||||||
if *shutdownDelay > 0 {
|
if *shutdownDelay > 0 {
|
||||||
// Sleep for a while until load balancer in front of the server
|
// Sleep for a while until load balancer in front of the server
|
||||||
// notifies that "/health" endpoint returns non-OK responses.
|
// notifies that "/health" endpoint returns non-OK responses.
|
||||||
|
@ -339,7 +339,7 @@ func handlerWrapper(s *server, w http.ResponseWriter, r *http.Request, rh Reques
|
||||||
switch r.URL.Path {
|
switch r.URL.Path {
|
||||||
case "/health":
|
case "/health":
|
||||||
h.Set("Content-Type", "text/plain; charset=utf-8")
|
h.Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
deadline := atomic.LoadInt64(&s.shutdownDelayDeadline)
|
deadline := s.shutdownDelayDeadline.Load()
|
||||||
if deadline <= 0 {
|
if deadline <= 0 {
|
||||||
w.Write([]byte("OK"))
|
w.Write([]byte("OK"))
|
||||||
return
|
return
|
||||||
|
|
|
@ -149,14 +149,11 @@ func (c *Cache) cleanByTimeout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type cache struct {
|
type cache struct {
|
||||||
// Atomically updated fields must go first in the struct, so they are properly
|
requests atomic.Uint64
|
||||||
// aligned to 8 bytes on 32-bit architectures.
|
misses atomic.Uint64
|
||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/212
|
|
||||||
requests uint64
|
|
||||||
misses uint64
|
|
||||||
|
|
||||||
// sizeBytes contains an approximate size for all the blocks stored in the cache.
|
// sizeBytes contains an approximate size for all the blocks stored in the cache.
|
||||||
sizeBytes int64
|
sizeBytes atomic.Int64
|
||||||
|
|
||||||
// getMaxSizeBytes() is a callback, which returns the maximum allowed cache size in bytes.
|
// getMaxSizeBytes() is a callback, which returns the maximum allowed cache size in bytes.
|
||||||
getMaxSizeBytes func() int
|
getMaxSizeBytes func() int
|
||||||
|
@ -204,7 +201,7 @@ func newCache(getMaxSizeBytes func() int) *cache {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) updateSizeBytes(n int) {
|
func (c *cache) updateSizeBytes(n int) {
|
||||||
atomic.AddInt64(&c.sizeBytes, int64(n))
|
c.sizeBytes.Add(int64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) cleanByTimeout() {
|
func (c *cache) cleanByTimeout() {
|
||||||
|
@ -223,13 +220,13 @@ func (c *cache) cleanByTimeout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) GetEntry(k string) Entry {
|
func (c *cache) GetEntry(k string) Entry {
|
||||||
atomic.AddUint64(&c.requests, 1)
|
c.requests.Add(1)
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
ce := c.m[k]
|
ce := c.m[k]
|
||||||
if ce == nil {
|
if ce == nil {
|
||||||
atomic.AddUint64(&c.misses, 1)
|
c.misses.Add(1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
currentTime := fasttime.UnixTimestamp()
|
currentTime := fasttime.UnixTimestamp()
|
||||||
|
@ -277,7 +274,7 @@ func (c *cache) Len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) SizeBytes() int {
|
func (c *cache) SizeBytes() int {
|
||||||
return int(atomic.LoadInt64(&c.sizeBytes))
|
return int(c.sizeBytes.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) SizeMaxBytes() int {
|
func (c *cache) SizeMaxBytes() int {
|
||||||
|
@ -285,11 +282,11 @@ func (c *cache) SizeMaxBytes() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) Requests() uint64 {
|
func (c *cache) Requests() uint64 {
|
||||||
return atomic.LoadUint64(&c.requests)
|
return c.requests.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cache) Misses() uint64 {
|
func (c *cache) Misses() uint64 {
|
||||||
return atomic.LoadUint64(&c.misses)
|
return c.misses.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
// lastAccessHeap implements heap.Interface
|
// lastAccessHeap implements heap.Interface
|
||||||
|
|
|
@ -44,10 +44,7 @@ func (cm *connMetrics) init(ms *metrics.Set, group, name, addr string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type statConn struct {
|
type statConn struct {
|
||||||
// Move atomic counters to the top of struct in order to properly align them on 32-bit arch.
|
closeCalls atomic.Uint64
|
||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/212
|
|
||||||
|
|
||||||
closeCalls uint64
|
|
||||||
|
|
||||||
net.Conn
|
net.Conn
|
||||||
|
|
||||||
|
@ -90,7 +87,7 @@ func (sc *statConn) Write(p []byte) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *statConn) Close() error {
|
func (sc *statConn) Close() error {
|
||||||
n := atomic.AddUint64(&sc.closeCalls, 1)
|
n := sc.closeCalls.Add(1)
|
||||||
if n > 1 {
|
if n > 1 {
|
||||||
// The connection has been already closed.
|
// The connection has been already closed.
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -104,9 +104,9 @@ func newAPIWatcher(apiServer string, ac *promauth.Config, sdc *SDConfig, swcFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aw *apiWatcher) mustStart() {
|
func (aw *apiWatcher) mustStart() {
|
||||||
atomic.AddInt32(&aw.gw.apiWatcherInflightStartCalls, 1)
|
aw.gw.apiWatcherInflightStartCalls.Add(1)
|
||||||
aw.gw.startWatchersForRole(aw.role, aw)
|
aw.gw.startWatchersForRole(aw.role, aw)
|
||||||
atomic.AddInt32(&aw.gw.apiWatcherInflightStartCalls, -1)
|
aw.gw.apiWatcherInflightStartCalls.Add(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aw *apiWatcher) updateSwosCount(multiplier int, swosByKey map[string][]interface{}) {
|
func (aw *apiWatcher) updateSwosCount(multiplier int, swosByKey map[string][]interface{}) {
|
||||||
|
@ -214,15 +214,15 @@ func (aw *apiWatcher) getScrapeWorkObjects() []interface{} {
|
||||||
type groupWatcher struct {
|
type groupWatcher struct {
|
||||||
// The number of in-flight apiWatcher.mustStart() calls for the given groupWatcher.
|
// The number of in-flight apiWatcher.mustStart() calls for the given groupWatcher.
|
||||||
// This field is used by groupWatchersCleaner() in order to determine when the given groupWatcher can be stopped.
|
// This field is used by groupWatchersCleaner() in order to determine when the given groupWatcher can be stopped.
|
||||||
apiWatcherInflightStartCalls int32
|
apiWatcherInflightStartCalls atomic.Int32
|
||||||
|
|
||||||
// Old Kubernetes doesn't support /apis/networking.k8s.io/v1/, so /apis/networking.k8s.io/v1beta1/ must be used instead.
|
// Old Kubernetes doesn't support /apis/networking.k8s.io/v1/, so /apis/networking.k8s.io/v1beta1/ must be used instead.
|
||||||
// This flag is used for automatic substitution of v1 API path with v1beta1 API path during requests to apiServer.
|
// This flag is used for automatic substitution of v1 API path with v1beta1 API path during requests to apiServer.
|
||||||
useNetworkingV1Beta1 uint32
|
useNetworkingV1Beta1 atomic.Bool
|
||||||
|
|
||||||
// Old Kubernetes doesn't support /apis/discovery.k8s.io/v1/, so discovery.k8s.io/v1beta1/ must be used instead.
|
// Old Kubernetes doesn't support /apis/discovery.k8s.io/v1/, so discovery.k8s.io/v1beta1/ must be used instead.
|
||||||
// This flag is used for automatic substitution of v1 API path with v1beta1 API path during requests to apiServer.
|
// This flag is used for automatic substitution of v1 API path with v1beta1 API path during requests to apiServer.
|
||||||
useDiscoveryV1Beta1 uint32
|
useDiscoveryV1Beta1 atomic.Bool
|
||||||
|
|
||||||
apiServer string
|
apiServer string
|
||||||
namespaces []string
|
namespaces []string
|
||||||
|
@ -343,7 +343,7 @@ func groupWatchersCleaner() {
|
||||||
awsTotal += len(uw.aws) + len(uw.awsPending)
|
awsTotal += len(uw.aws) + len(uw.awsPending)
|
||||||
}
|
}
|
||||||
|
|
||||||
if awsTotal == 0 && atomic.LoadInt32(&gw.apiWatcherInflightStartCalls) == 0 {
|
if awsTotal == 0 && gw.apiWatcherInflightStartCalls.Load() == 0 {
|
||||||
// There are no API watchers subscribed to gw and there are no in-flight apiWatcher.mustStart() calls.
|
// There are no API watchers subscribed to gw and there are no in-flight apiWatcher.mustStart() calls.
|
||||||
// Stop all the urlWatcher instances at gw and drop gw from groupWatchers in this case,
|
// Stop all the urlWatcher instances at gw and drop gw from groupWatchers in this case,
|
||||||
// but do it only on the second iteration in order to reduce urlWatcher churn
|
// but do it only on the second iteration in order to reduce urlWatcher churn
|
||||||
|
@ -471,11 +471,11 @@ func (gw *groupWatcher) startWatchersForRole(role string, aw *apiWatcher) {
|
||||||
|
|
||||||
// doRequest performs http request to the given requestURL.
|
// doRequest performs http request to the given requestURL.
|
||||||
func (gw *groupWatcher) doRequest(ctx context.Context, requestURL string) (*http.Response, error) {
|
func (gw *groupWatcher) doRequest(ctx context.Context, requestURL string) (*http.Response, error) {
|
||||||
if strings.Contains(requestURL, "/apis/networking.k8s.io/v1/") && atomic.LoadUint32(&gw.useNetworkingV1Beta1) == 1 {
|
if strings.Contains(requestURL, "/apis/networking.k8s.io/v1/") && gw.useNetworkingV1Beta1.Load() {
|
||||||
// Update networking URL for old Kubernetes API, which supports only v1beta1 path.
|
// Update networking URL for old Kubernetes API, which supports only v1beta1 path.
|
||||||
requestURL = strings.Replace(requestURL, "/apis/networking.k8s.io/v1/", "/apis/networking.k8s.io/v1beta1/", 1)
|
requestURL = strings.Replace(requestURL, "/apis/networking.k8s.io/v1/", "/apis/networking.k8s.io/v1beta1/", 1)
|
||||||
}
|
}
|
||||||
if strings.Contains(requestURL, "/apis/discovery.k8s.io/v1/") && atomic.LoadUint32(&gw.useDiscoveryV1Beta1) == 1 {
|
if strings.Contains(requestURL, "/apis/discovery.k8s.io/v1/") && gw.useDiscoveryV1Beta1.Load() {
|
||||||
// Update discovery URL for old Kubernetes API, which supports only v1beta1 path.
|
// Update discovery URL for old Kubernetes API, which supports only v1beta1 path.
|
||||||
requestURL = strings.Replace(requestURL, "/apis/discovery.k8s.io/v1/", "/apis/discovery.k8s.io/v1beta1/", 1)
|
requestURL = strings.Replace(requestURL, "/apis/discovery.k8s.io/v1/", "/apis/discovery.k8s.io/v1beta1/", 1)
|
||||||
}
|
}
|
||||||
|
@ -491,12 +491,12 @@ func (gw *groupWatcher) doRequest(ctx context.Context, requestURL string) (*http
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if resp.StatusCode == http.StatusNotFound {
|
if resp.StatusCode == http.StatusNotFound {
|
||||||
if strings.Contains(requestURL, "/apis/networking.k8s.io/v1/") && atomic.LoadUint32(&gw.useNetworkingV1Beta1) == 0 {
|
if strings.Contains(requestURL, "/apis/networking.k8s.io/v1/") && !gw.useNetworkingV1Beta1.Load() {
|
||||||
atomic.StoreUint32(&gw.useNetworkingV1Beta1, 1)
|
gw.useNetworkingV1Beta1.Store(true)
|
||||||
return gw.doRequest(ctx, requestURL)
|
return gw.doRequest(ctx, requestURL)
|
||||||
}
|
}
|
||||||
if strings.Contains(requestURL, "/apis/discovery.k8s.io/v1/") && atomic.LoadUint32(&gw.useDiscoveryV1Beta1) == 0 {
|
if strings.Contains(requestURL, "/apis/discovery.k8s.io/v1/") && !gw.useDiscoveryV1Beta1.Load() {
|
||||||
atomic.StoreUint32(&gw.useDiscoveryV1Beta1, 1)
|
gw.useDiscoveryV1Beta1.Store(true)
|
||||||
return gw.doRequest(ctx, requestURL)
|
return gw.doRequest(ctx, requestURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,9 +79,9 @@ func Stop() {
|
||||||
var (
|
var (
|
||||||
globalStopChan chan struct{}
|
globalStopChan chan struct{}
|
||||||
scraperWG sync.WaitGroup
|
scraperWG sync.WaitGroup
|
||||||
// PendingScrapeConfigs - zero value means, that
|
|
||||||
// all scrapeConfigs are inited and ready for work.
|
// PendingScrapeConfigs - zero value means, that all scrapeConfigs are inited and ready for work.
|
||||||
PendingScrapeConfigs int32
|
PendingScrapeConfigs atomic.Int32
|
||||||
|
|
||||||
// configData contains -promscrape.config data
|
// configData contains -promscrape.config data
|
||||||
configData atomic.Pointer[[]byte]
|
configData atomic.Pointer[[]byte]
|
||||||
|
@ -225,7 +225,7 @@ func newScrapeConfigs(pushData func(at *auth.Token, wr *prompbmarshal.WriteReque
|
||||||
}
|
}
|
||||||
|
|
||||||
func (scs *scrapeConfigs) add(name string, checkInterval time.Duration, getScrapeWork func(cfg *Config, swsPrev []*ScrapeWork) []*ScrapeWork) {
|
func (scs *scrapeConfigs) add(name string, checkInterval time.Duration, getScrapeWork func(cfg *Config, swsPrev []*ScrapeWork) []*ScrapeWork) {
|
||||||
atomic.AddInt32(&PendingScrapeConfigs, 1)
|
PendingScrapeConfigs.Add(1)
|
||||||
scfg := &scrapeConfig{
|
scfg := &scrapeConfig{
|
||||||
name: name,
|
name: name,
|
||||||
pushData: scs.pushData,
|
pushData: scs.pushData,
|
||||||
|
@ -292,7 +292,7 @@ func (scfg *scrapeConfig) run(globalStopCh <-chan struct{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateScrapeWork(cfg)
|
updateScrapeWork(cfg)
|
||||||
atomic.AddInt32(&PendingScrapeConfigs, -1)
|
PendingScrapeConfigs.Add(-1)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type statConn struct {
|
type statConn struct {
|
||||||
closed uint64
|
closed atomic.Int32
|
||||||
net.Conn
|
net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ func (sc *statConn) Write(p []byte) (int, error) {
|
||||||
|
|
||||||
func (sc *statConn) Close() error {
|
func (sc *statConn) Close() error {
|
||||||
err := sc.Conn.Close()
|
err := sc.Conn.Close()
|
||||||
if atomic.AddUint64(&sc.closed, 1) == 1 {
|
if sc.closed.Add(1) == 1 {
|
||||||
conns.Dec()
|
conns.Dec()
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -41,7 +41,11 @@ func NewName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextSnapshotIdx() uint64 {
|
func nextSnapshotIdx() uint64 {
|
||||||
return atomic.AddUint64(&snapshotIdx, 1)
|
return snapshotIdx.Add(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var snapshotIdx = uint64(time.Now().UnixNano())
|
var snapshotIdx = func() *atomic.Uint64 {
|
||||||
|
var x atomic.Uint64
|
||||||
|
x.Store(uint64(time.Now().UnixNano()))
|
||||||
|
return &x
|
||||||
|
}()
|
||||||
|
|
|
@ -43,7 +43,7 @@ type Cache struct {
|
||||||
// In this case using prev would result in RAM waste,
|
// In this case using prev would result in RAM waste,
|
||||||
// it is better to use only curr cache with doubled size.
|
// it is better to use only curr cache with doubled size.
|
||||||
// After the process of switching, this flag will be set to whole.
|
// After the process of switching, this flag will be set to whole.
|
||||||
mode uint32
|
mode atomic.Uint32
|
||||||
|
|
||||||
// The maxBytes value passed to New() or to Load().
|
// The maxBytes value passed to New() or to Load().
|
||||||
maxBytes int
|
maxBytes int
|
||||||
|
@ -110,7 +110,7 @@ func newCacheInternal(curr, prev *fastcache.Cache, mode, maxBytes int) *Cache {
|
||||||
c.curr.Store(curr)
|
c.curr.Store(curr)
|
||||||
c.prev.Store(prev)
|
c.prev.Store(prev)
|
||||||
c.stopCh = make(chan struct{})
|
c.stopCh = make(chan struct{})
|
||||||
c.setMode(mode)
|
c.mode.Store(uint32(mode))
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ func (c *Cache) expirationWatcher(expireDuration time.Duration) {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
}
|
}
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
if atomic.LoadUint32(&c.mode) != split {
|
if c.mode.Load() != split {
|
||||||
// Stop the expirationWatcher on non-split mode.
|
// Stop the expirationWatcher on non-split mode.
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
return
|
return
|
||||||
|
@ -183,7 +183,7 @@ func (c *Cache) prevCacheWatcher() {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
}
|
}
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
if atomic.LoadUint32(&c.mode) != split {
|
if c.mode.Load() != split {
|
||||||
// Do nothing in non-split mode.
|
// Do nothing in non-split mode.
|
||||||
c.mu.Unlock()
|
c.mu.Unlock()
|
||||||
return
|
return
|
||||||
|
@ -227,7 +227,7 @@ func (c *Cache) cacheSizeWatcher() {
|
||||||
return
|
return
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
}
|
}
|
||||||
if c.loadMode() != split {
|
if c.mode.Load() != split {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var cs fastcache.Stats
|
var cs fastcache.Stats
|
||||||
|
@ -252,7 +252,7 @@ func (c *Cache) cacheSizeWatcher() {
|
||||||
// 6) drop prev cache
|
// 6) drop prev cache
|
||||||
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
c.setMode(switching)
|
c.mode.Store(switching)
|
||||||
prev := c.prev.Load()
|
prev := c.prev.Load()
|
||||||
curr := c.curr.Load()
|
curr := c.curr.Load()
|
||||||
c.prev.Store(curr)
|
c.prev.Store(curr)
|
||||||
|
@ -280,7 +280,7 @@ func (c *Cache) cacheSizeWatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
c.setMode(whole)
|
c.mode.Store(whole)
|
||||||
prev = c.prev.Load()
|
prev = c.prev.Load()
|
||||||
c.prev.Store(fastcache.New(1024))
|
c.prev.Store(fastcache.New(1024))
|
||||||
cs.Reset()
|
cs.Reset()
|
||||||
|
@ -318,15 +318,7 @@ func (c *Cache) Reset() {
|
||||||
updateCacheStatsHistory(&c.csHistory, &cs)
|
updateCacheStatsHistory(&c.csHistory, &cs)
|
||||||
curr.Reset()
|
curr.Reset()
|
||||||
// Reset the mode to `split` in the hope the working set size becomes smaller after the reset.
|
// Reset the mode to `split` in the hope the working set size becomes smaller after the reset.
|
||||||
c.setMode(split)
|
c.mode.Store(split)
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Cache) setMode(mode int) {
|
|
||||||
atomic.StoreUint32(&c.mode, uint32(mode))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Cache) loadMode() int {
|
|
||||||
return int(atomic.LoadUint32(&c.mode))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateStats updates fcs with cache stats.
|
// UpdateStats updates fcs with cache stats.
|
||||||
|
@ -374,7 +366,7 @@ func (c *Cache) Get(dst, key []byte) []byte {
|
||||||
// Fast path - the entry is found in the current cache.
|
// Fast path - the entry is found in the current cache.
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
if c.loadMode() == whole {
|
if c.mode.Load() == whole {
|
||||||
// Nothing found.
|
// Nothing found.
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -397,7 +389,7 @@ func (c *Cache) Has(key []byte) bool {
|
||||||
if curr.Has(key) {
|
if curr.Has(key) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if c.loadMode() == whole {
|
if c.mode.Load() == whole {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
prev := c.prev.Load()
|
prev := c.prev.Load()
|
||||||
|
@ -428,7 +420,7 @@ func (c *Cache) GetBig(dst, key []byte) []byte {
|
||||||
// Fast path - the entry is found in the current cache.
|
// Fast path - the entry is found in the current cache.
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
if c.loadMode() == whole {
|
if c.mode.Load() == whole {
|
||||||
// Nothing found.
|
// Nothing found.
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
5
vendor/github.com/VictoriaMetrics/metrics/counter.go
generated
vendored
5
vendor/github.com/VictoriaMetrics/metrics/counter.go
generated
vendored
|
@ -42,6 +42,11 @@ func (c *Counter) Add(n int) {
|
||||||
atomic.AddUint64(&c.n, uint64(n))
|
atomic.AddUint64(&c.n, uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddInt64 adds n to c.
|
||||||
|
func (c *Counter) AddInt64(n int64) {
|
||||||
|
atomic.AddUint64(&c.n, uint64(n))
|
||||||
|
}
|
||||||
|
|
||||||
// Get returns the current value for c.
|
// Get returns the current value for c.
|
||||||
func (c *Counter) Get() uint64 {
|
func (c *Counter) Get() uint64 {
|
||||||
return atomic.LoadUint64(&c.n)
|
return atomic.LoadUint64(&c.n)
|
||||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -99,7 +99,7 @@ github.com/VictoriaMetrics/easyproto
|
||||||
# github.com/VictoriaMetrics/fastcache v1.12.2
|
# github.com/VictoriaMetrics/fastcache v1.12.2
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/VictoriaMetrics/fastcache
|
github.com/VictoriaMetrics/fastcache
|
||||||
# github.com/VictoriaMetrics/metrics v1.32.0
|
# github.com/VictoriaMetrics/metrics v1.33.0
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/VictoriaMetrics/metrics
|
github.com/VictoriaMetrics/metrics
|
||||||
# github.com/VictoriaMetrics/metricsql v0.74.0
|
# github.com/VictoriaMetrics/metricsql v0.74.0
|
||||||
|
|
Loading…
Reference in a new issue