From f1591a42c3fd7b66611d0409ef0e2e1177417e8b Mon Sep 17 00:00:00 2001 From: alanprot Date: Wed, 1 May 2024 11:03:27 -0700 Subject: [PATCH] Chore: Update thanos Signed-off-by: alanprot --- go.mod | 2 +- go.sum | 4 +- .../hashicorp/golang-lru/.gitignore | 23 -- .../hashicorp/golang-lru/.golangci.yml | 30 -- vendor/github.com/hashicorp/golang-lru/2q.go | 222 --------------- .../github.com/hashicorp/golang-lru/README.md | 25 -- vendor/github.com/hashicorp/golang-lru/arc.go | 256 ----------------- vendor/github.com/hashicorp/golang-lru/doc.go | 21 -- vendor/github.com/hashicorp/golang-lru/lru.go | 231 --------------- .../hashicorp/golang-lru/testing.go | 16 -- .../pkg/block/indexheader/binary_reader.go | 12 +- .../thanos-io/thanos/pkg/cache/inmemory.go | 27 +- .../thanos-io/thanos/pkg/losertree/tree.go | 161 +++++++++++ .../thanos-io/thanos/pkg/query/endpointset.go | 11 +- .../thanos-io/thanos/pkg/query/querier.go | 21 +- .../thanos/pkg/querysharding/analyzer.go | 8 +- .../thanos-io/thanos/pkg/store/bucket.go | 68 +++-- .../thanos/pkg/store/cache/inmemory.go | 16 +- .../thanos/pkg/store/lazy_postings.go | 11 +- .../thanos-io/thanos/pkg/store/prometheus.go | 14 +- .../thanos-io/thanos/pkg/store/proxy.go | 48 +++- .../store/{proxy_heap.go => proxy_merge.go} | 152 +++------- .../thanos/pkg/store/storepb/rpc.pb.go | 267 ++++++++++++------ .../thanos/pkg/store/storepb/rpc.proto | 6 + .../thanos/pkg/store/storepb/shard_info.go | 3 + .../thanos-io/thanos/pkg/store/tsdb.go | 14 +- vendor/modules.txt | 4 +- 27 files changed, 585 insertions(+), 1088 deletions(-) delete mode 100644 vendor/github.com/hashicorp/golang-lru/.gitignore delete mode 100644 vendor/github.com/hashicorp/golang-lru/.golangci.yml delete mode 100644 vendor/github.com/hashicorp/golang-lru/2q.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/README.md delete mode 100644 vendor/github.com/hashicorp/golang-lru/arc.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/doc.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/lru.go delete mode 100644 vendor/github.com/hashicorp/golang-lru/testing.go create mode 100644 vendor/github.com/thanos-io/thanos/pkg/losertree/tree.go rename vendor/github.com/thanos-io/thanos/pkg/store/{proxy_heap.go => proxy_merge.go} (86%) diff --git a/go.mod b/go.mod index 66e0d785b6..ea6030824c 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/thanos-io/objstore v0.0.0-20240309075357-e8336a5fd5f3 github.com/thanos-io/promql-engine v0.0.0-20240405095051-b7d0da367508 - github.com/thanos-io/thanos v0.34.2-0.20240423183430-7c8fe85682a5 + github.com/thanos-io/thanos v0.34.2-0.20240501161908-1e745af6720c github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/weaveworks/common v0.0.0-20230728070032-dd9e68f319d5 go.etcd.io/etcd/api/v3 v3.5.13 diff --git a/go.sum b/go.sum index 56adf83fb4..55f7e68c07 100644 --- a/go.sum +++ b/go.sum @@ -1412,8 +1412,8 @@ github.com/thanos-io/objstore v0.0.0-20240309075357-e8336a5fd5f3 h1:Q0BjHI7FMe5K github.com/thanos-io/objstore v0.0.0-20240309075357-e8336a5fd5f3/go.mod h1:ptMYNPgbyAR7a2Ab2t7zHA2/0be2ePyawVR7lp7fZtg= github.com/thanos-io/promql-engine v0.0.0-20240405095051-b7d0da367508 h1:4X0ThYb7/wTTKS73wT13ixw0lj5OJ87g45RWIZhPZDA= github.com/thanos-io/promql-engine v0.0.0-20240405095051-b7d0da367508/go.mod h1:FEPnabuTql1bDA4OUM41mwcZOJ20R436k8vq+xtGEG0= -github.com/thanos-io/thanos v0.34.2-0.20240423183430-7c8fe85682a5 h1:OQ37YLhqB3hFgNHjByYCS/VTW5nPJwlJRY9ON9oZL4Y= -github.com/thanos-io/thanos v0.34.2-0.20240423183430-7c8fe85682a5/go.mod h1:Kjpf/IaJzIGNLxLhoavoS/S8TibhuvjAZjRT9IAXw2o= +github.com/thanos-io/thanos v0.34.2-0.20240501161908-1e745af6720c h1:clWAhj5L7+Dnw/apO874hUaVxDRHfkm9If4Qv/6CbIo= +github.com/thanos-io/thanos v0.34.2-0.20240501161908-1e745af6720c/go.mod h1:WHGZyM/qwp857mJr8Q0d7K6eQoLtLv+6p7RNpT/yeIE= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.28.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= diff --git a/vendor/github.com/hashicorp/golang-lru/.gitignore b/vendor/github.com/hashicorp/golang-lru/.gitignore deleted file mode 100644 index 836562412f..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test diff --git a/vendor/github.com/hashicorp/golang-lru/.golangci.yml b/vendor/github.com/hashicorp/golang-lru/.golangci.yml deleted file mode 100644 index 49202fc41e..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/.golangci.yml +++ /dev/null @@ -1,30 +0,0 @@ -linters: - enable: - - megacheck - - revive - - govet - - unconvert - - megacheck - - gas - - gocyclo - - dupl - - misspell - - unparam - - unused - - typecheck - - ineffassign - - stylecheck - - exportloopref - - gocritic - - nakedret - - gosimple - - prealloc - fast: false - disable-all: true - -issues: - exclude-rules: - - path: _test\.go - linters: - - dupl - exclude-use-default: false diff --git a/vendor/github.com/hashicorp/golang-lru/2q.go b/vendor/github.com/hashicorp/golang-lru/2q.go deleted file mode 100644 index 15fcad0306..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/2q.go +++ /dev/null @@ -1,222 +0,0 @@ -package lru - -import ( - "fmt" - "sync" - - "github.com/hashicorp/golang-lru/simplelru" -) - -const ( - // Default2QRecentRatio is the ratio of the 2Q cache dedicated - // to recently added entries that have only been accessed once. - Default2QRecentRatio = 0.25 - - // Default2QGhostEntries is the default ratio of ghost - // entries kept to track entries recently evicted - Default2QGhostEntries = 0.50 -) - -// TwoQueueCache is a thread-safe fixed size 2Q cache. -// 2Q is an enhancement over the standard LRU cache -// in that it tracks both frequently and recently used -// entries separately. This avoids a burst in access to new -// entries from evicting frequently used entries. It adds some -// additional tracking overhead to the standard LRU cache, and is -// computationally about 2x the cost, and adds some metadata over -// head. The ARCCache is similar, but does not require setting any -// parameters. -type TwoQueueCache struct { - size int - recentSize int - - recent simplelru.LRUCache - frequent simplelru.LRUCache - recentEvict simplelru.LRUCache - lock sync.RWMutex -} - -// New2Q creates a new TwoQueueCache using the default -// values for the parameters. -func New2Q(size int) (*TwoQueueCache, error) { - return New2QParams(size, Default2QRecentRatio, Default2QGhostEntries) -} - -// New2QParams creates a new TwoQueueCache using the provided -// parameter values. -func New2QParams(size int, recentRatio, ghostRatio float64) (*TwoQueueCache, error) { - if size <= 0 { - return nil, fmt.Errorf("invalid size") - } - if recentRatio < 0.0 || recentRatio > 1.0 { - return nil, fmt.Errorf("invalid recent ratio") - } - if ghostRatio < 0.0 || ghostRatio > 1.0 { - return nil, fmt.Errorf("invalid ghost ratio") - } - - // Determine the sub-sizes - recentSize := int(float64(size) * recentRatio) - evictSize := int(float64(size) * ghostRatio) - - // Allocate the LRUs - recent, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - frequent, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - recentEvict, err := simplelru.NewLRU(evictSize, nil) - if err != nil { - return nil, err - } - - // Initialize the cache - c := &TwoQueueCache{ - size: size, - recentSize: recentSize, - recent: recent, - frequent: frequent, - recentEvict: recentEvict, - } - return c, nil -} - -// Get looks up a key's value from the cache. -func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) { - c.lock.Lock() - defer c.lock.Unlock() - - // Check if this is a frequent value - if val, ok := c.frequent.Get(key); ok { - return val, ok - } - - // If the value is contained in recent, then we - // promote it to frequent - if val, ok := c.recent.Peek(key); ok { - c.recent.Remove(key) - c.frequent.Add(key, val) - return val, ok - } - - // No hit - return nil, false -} - -// Add adds a value to the cache. -func (c *TwoQueueCache) Add(key, value interface{}) { - c.lock.Lock() - defer c.lock.Unlock() - - // Check if the value is frequently used already, - // and just update the value - if c.frequent.Contains(key) { - c.frequent.Add(key, value) - return - } - - // Check if the value is recently used, and promote - // the value into the frequent list - if c.recent.Contains(key) { - c.recent.Remove(key) - c.frequent.Add(key, value) - return - } - - // If the value was recently evicted, add it to the - // frequently used list - if c.recentEvict.Contains(key) { - c.ensureSpace(true) - c.recentEvict.Remove(key) - c.frequent.Add(key, value) - return - } - - // Add to the recently seen list - c.ensureSpace(false) - c.recent.Add(key, value) -} - -// ensureSpace is used to ensure we have space in the cache -func (c *TwoQueueCache) ensureSpace(recentEvict bool) { - // If we have space, nothing to do - recentLen := c.recent.Len() - freqLen := c.frequent.Len() - if recentLen+freqLen < c.size { - return - } - - // If the recent buffer is larger than - // the target, evict from there - if recentLen > 0 && (recentLen > c.recentSize || (recentLen == c.recentSize && !recentEvict)) { - k, _, _ := c.recent.RemoveOldest() - c.recentEvict.Add(k, nil) - return - } - - // Remove from the frequent list otherwise - c.frequent.RemoveOldest() -} - -// Len returns the number of items in the cache. -func (c *TwoQueueCache) Len() int { - c.lock.RLock() - defer c.lock.RUnlock() - return c.recent.Len() + c.frequent.Len() -} - -// Keys returns a slice of the keys in the cache. -// The frequently used keys are first in the returned slice. -func (c *TwoQueueCache) Keys() []interface{} { - c.lock.RLock() - defer c.lock.RUnlock() - k1 := c.frequent.Keys() - k2 := c.recent.Keys() - return append(k1, k2...) -} - -// Remove removes the provided key from the cache. -func (c *TwoQueueCache) Remove(key interface{}) { - c.lock.Lock() - defer c.lock.Unlock() - if c.frequent.Remove(key) { - return - } - if c.recent.Remove(key) { - return - } - if c.recentEvict.Remove(key) { - return - } -} - -// Purge is used to completely clear the cache. -func (c *TwoQueueCache) Purge() { - c.lock.Lock() - defer c.lock.Unlock() - c.recent.Purge() - c.frequent.Purge() - c.recentEvict.Purge() -} - -// Contains is used to check if the cache contains a key -// without updating recency or frequency. -func (c *TwoQueueCache) Contains(key interface{}) bool { - c.lock.RLock() - defer c.lock.RUnlock() - return c.frequent.Contains(key) || c.recent.Contains(key) -} - -// Peek is used to inspect the cache value of a key -// without updating recency or frequency. -func (c *TwoQueueCache) Peek(key interface{}) (value interface{}, ok bool) { - c.lock.RLock() - defer c.lock.RUnlock() - if val, ok := c.frequent.Peek(key); ok { - return val, ok - } - return c.recent.Peek(key) -} diff --git a/vendor/github.com/hashicorp/golang-lru/README.md b/vendor/github.com/hashicorp/golang-lru/README.md deleted file mode 100644 index 063bb16056..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/README.md +++ /dev/null @@ -1,25 +0,0 @@ -golang-lru -========== - -This provides the `lru` package which implements a fixed-size -thread safe LRU cache. It is based on the cache in Groupcache. - -Documentation -============= - -Full docs are available on [Godoc](https://pkg.go.dev/github.com/hashicorp/golang-lru) - -Example -======= - -Using the LRU is very simple: - -```go -l, _ := New(128) -for i := 0; i < 256; i++ { - l.Add(i, nil) -} -if l.Len() != 128 { - panic(fmt.Sprintf("bad len: %v", l.Len())) -} -``` diff --git a/vendor/github.com/hashicorp/golang-lru/arc.go b/vendor/github.com/hashicorp/golang-lru/arc.go deleted file mode 100644 index e396f8428a..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/arc.go +++ /dev/null @@ -1,256 +0,0 @@ -package lru - -import ( - "sync" - - "github.com/hashicorp/golang-lru/simplelru" -) - -// ARCCache is a thread-safe fixed size Adaptive Replacement Cache (ARC). -// ARC is an enhancement over the standard LRU cache in that tracks both -// frequency and recency of use. This avoids a burst in access to new -// entries from evicting the frequently used older entries. It adds some -// additional tracking overhead to a standard LRU cache, computationally -// it is roughly 2x the cost, and the extra memory overhead is linear -// with the size of the cache. ARC has been patented by IBM, but is -// similar to the TwoQueueCache (2Q) which requires setting parameters. -type ARCCache struct { - size int // Size is the total capacity of the cache - p int // P is the dynamic preference towards T1 or T2 - - t1 simplelru.LRUCache // T1 is the LRU for recently accessed items - b1 simplelru.LRUCache // B1 is the LRU for evictions from t1 - - t2 simplelru.LRUCache // T2 is the LRU for frequently accessed items - b2 simplelru.LRUCache // B2 is the LRU for evictions from t2 - - lock sync.RWMutex -} - -// NewARC creates an ARC of the given size -func NewARC(size int) (*ARCCache, error) { - // Create the sub LRUs - b1, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - b2, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - t1, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - t2, err := simplelru.NewLRU(size, nil) - if err != nil { - return nil, err - } - - // Initialize the ARC - c := &ARCCache{ - size: size, - p: 0, - t1: t1, - b1: b1, - t2: t2, - b2: b2, - } - return c, nil -} - -// Get looks up a key's value from the cache. -func (c *ARCCache) Get(key interface{}) (value interface{}, ok bool) { - c.lock.Lock() - defer c.lock.Unlock() - - // If the value is contained in T1 (recent), then - // promote it to T2 (frequent) - if val, ok := c.t1.Peek(key); ok { - c.t1.Remove(key) - c.t2.Add(key, val) - return val, ok - } - - // Check if the value is contained in T2 (frequent) - if val, ok := c.t2.Get(key); ok { - return val, ok - } - - // No hit - return nil, false -} - -// Add adds a value to the cache. -func (c *ARCCache) Add(key, value interface{}) { - c.lock.Lock() - defer c.lock.Unlock() - - // Check if the value is contained in T1 (recent), and potentially - // promote it to frequent T2 - if c.t1.Contains(key) { - c.t1.Remove(key) - c.t2.Add(key, value) - return - } - - // Check if the value is already in T2 (frequent) and update it - if c.t2.Contains(key) { - c.t2.Add(key, value) - return - } - - // Check if this value was recently evicted as part of the - // recently used list - if c.b1.Contains(key) { - // T1 set is too small, increase P appropriately - delta := 1 - b1Len := c.b1.Len() - b2Len := c.b2.Len() - if b2Len > b1Len { - delta = b2Len / b1Len - } - if c.p+delta >= c.size { - c.p = c.size - } else { - c.p += delta - } - - // Potentially need to make room in the cache - if c.t1.Len()+c.t2.Len() >= c.size { - c.replace(false) - } - - // Remove from B1 - c.b1.Remove(key) - - // Add the key to the frequently used list - c.t2.Add(key, value) - return - } - - // Check if this value was recently evicted as part of the - // frequently used list - if c.b2.Contains(key) { - // T2 set is too small, decrease P appropriately - delta := 1 - b1Len := c.b1.Len() - b2Len := c.b2.Len() - if b1Len > b2Len { - delta = b1Len / b2Len - } - if delta >= c.p { - c.p = 0 - } else { - c.p -= delta - } - - // Potentially need to make room in the cache - if c.t1.Len()+c.t2.Len() >= c.size { - c.replace(true) - } - - // Remove from B2 - c.b2.Remove(key) - - // Add the key to the frequently used list - c.t2.Add(key, value) - return - } - - // Potentially need to make room in the cache - if c.t1.Len()+c.t2.Len() >= c.size { - c.replace(false) - } - - // Keep the size of the ghost buffers trim - if c.b1.Len() > c.size-c.p { - c.b1.RemoveOldest() - } - if c.b2.Len() > c.p { - c.b2.RemoveOldest() - } - - // Add to the recently seen list - c.t1.Add(key, value) -} - -// replace is used to adaptively evict from either T1 or T2 -// based on the current learned value of P -func (c *ARCCache) replace(b2ContainsKey bool) { - t1Len := c.t1.Len() - if t1Len > 0 && (t1Len > c.p || (t1Len == c.p && b2ContainsKey)) { - k, _, ok := c.t1.RemoveOldest() - if ok { - c.b1.Add(k, nil) - } - } else { - k, _, ok := c.t2.RemoveOldest() - if ok { - c.b2.Add(k, nil) - } - } -} - -// Len returns the number of cached entries -func (c *ARCCache) Len() int { - c.lock.RLock() - defer c.lock.RUnlock() - return c.t1.Len() + c.t2.Len() -} - -// Keys returns all the cached keys -func (c *ARCCache) Keys() []interface{} { - c.lock.RLock() - defer c.lock.RUnlock() - k1 := c.t1.Keys() - k2 := c.t2.Keys() - return append(k1, k2...) -} - -// Remove is used to purge a key from the cache -func (c *ARCCache) Remove(key interface{}) { - c.lock.Lock() - defer c.lock.Unlock() - if c.t1.Remove(key) { - return - } - if c.t2.Remove(key) { - return - } - if c.b1.Remove(key) { - return - } - if c.b2.Remove(key) { - return - } -} - -// Purge is used to clear the cache -func (c *ARCCache) Purge() { - c.lock.Lock() - defer c.lock.Unlock() - c.t1.Purge() - c.t2.Purge() - c.b1.Purge() - c.b2.Purge() -} - -// Contains is used to check if the cache contains a key -// without updating recency or frequency. -func (c *ARCCache) Contains(key interface{}) bool { - c.lock.RLock() - defer c.lock.RUnlock() - return c.t1.Contains(key) || c.t2.Contains(key) -} - -// Peek is used to inspect the cache value of a key -// without updating recency or frequency. -func (c *ARCCache) Peek(key interface{}) (value interface{}, ok bool) { - c.lock.RLock() - defer c.lock.RUnlock() - if val, ok := c.t1.Peek(key); ok { - return val, ok - } - return c.t2.Peek(key) -} diff --git a/vendor/github.com/hashicorp/golang-lru/doc.go b/vendor/github.com/hashicorp/golang-lru/doc.go deleted file mode 100644 index 2547df979d..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -// Package lru provides three different LRU caches of varying sophistication. -// -// Cache is a simple LRU cache. It is based on the -// LRU implementation in groupcache: -// https://github.com/golang/groupcache/tree/master/lru -// -// TwoQueueCache tracks frequently used and recently used entries separately. -// This avoids a burst of accesses from taking out frequently used entries, -// at the cost of about 2x computational overhead and some extra bookkeeping. -// -// ARCCache is an adaptive replacement cache. It tracks recent evictions as -// well as recent usage in both the frequent and recent caches. Its -// computational overhead is comparable to TwoQueueCache, but the memory -// overhead is linear with the size of the cache. -// -// ARC has been patented by IBM, so do not use it if that is problematic for -// your program. -// -// All caches in this package take locks while operating, and are therefore -// thread-safe for consumers. -package lru diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go deleted file mode 100644 index 895d8e3ea0..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/lru.go +++ /dev/null @@ -1,231 +0,0 @@ -package lru - -import ( - "sync" - - "github.com/hashicorp/golang-lru/simplelru" -) - -const ( - // DefaultEvictedBufferSize defines the default buffer size to store evicted key/val - DefaultEvictedBufferSize = 16 -) - -// Cache is a thread-safe fixed size LRU cache. -type Cache struct { - lru *simplelru.LRU - evictedKeys, evictedVals []interface{} - onEvictedCB func(k, v interface{}) - lock sync.RWMutex -} - -// New creates an LRU of the given size. -func New(size int) (*Cache, error) { - return NewWithEvict(size, nil) -} - -// NewWithEvict constructs a fixed size cache with the given eviction -// callback. -func NewWithEvict(size int, onEvicted func(key, value interface{})) (c *Cache, err error) { - // create a cache with default settings - c = &Cache{ - onEvictedCB: onEvicted, - } - if onEvicted != nil { - c.initEvictBuffers() - onEvicted = c.onEvicted - } - c.lru, err = simplelru.NewLRU(size, onEvicted) - return -} - -func (c *Cache) initEvictBuffers() { - c.evictedKeys = make([]interface{}, 0, DefaultEvictedBufferSize) - c.evictedVals = make([]interface{}, 0, DefaultEvictedBufferSize) -} - -// onEvicted save evicted key/val and sent in externally registered callback -// outside of critical section -func (c *Cache) onEvicted(k, v interface{}) { - c.evictedKeys = append(c.evictedKeys, k) - c.evictedVals = append(c.evictedVals, v) -} - -// Purge is used to completely clear the cache. -func (c *Cache) Purge() { - var ks, vs []interface{} - c.lock.Lock() - c.lru.Purge() - if c.onEvictedCB != nil && len(c.evictedKeys) > 0 { - ks, vs = c.evictedKeys, c.evictedVals - c.initEvictBuffers() - } - c.lock.Unlock() - // invoke callback outside of critical section - if c.onEvictedCB != nil { - for i := 0; i < len(ks); i++ { - c.onEvictedCB(ks[i], vs[i]) - } - } -} - -// Add adds a value to the cache. Returns true if an eviction occurred. -func (c *Cache) Add(key, value interface{}) (evicted bool) { - var k, v interface{} - c.lock.Lock() - evicted = c.lru.Add(key, value) - if c.onEvictedCB != nil && evicted { - k, v = c.evictedKeys[0], c.evictedVals[0] - c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] - } - c.lock.Unlock() - if c.onEvictedCB != nil && evicted { - c.onEvictedCB(k, v) - } - return -} - -// Get looks up a key's value from the cache. -func (c *Cache) Get(key interface{}) (value interface{}, ok bool) { - c.lock.Lock() - value, ok = c.lru.Get(key) - c.lock.Unlock() - return value, ok -} - -// Contains checks if a key is in the cache, without updating the -// recent-ness or deleting it for being stale. -func (c *Cache) Contains(key interface{}) bool { - c.lock.RLock() - containKey := c.lru.Contains(key) - c.lock.RUnlock() - return containKey -} - -// Peek returns the key value (or undefined if not found) without updating -// the "recently used"-ness of the key. -func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) { - c.lock.RLock() - value, ok = c.lru.Peek(key) - c.lock.RUnlock() - return value, ok -} - -// ContainsOrAdd checks if a key is in the cache without updating the -// recent-ness or deleting it for being stale, and if not, adds the value. -// Returns whether found and whether an eviction occurred. -func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { - var k, v interface{} - c.lock.Lock() - if c.lru.Contains(key) { - c.lock.Unlock() - return true, false - } - evicted = c.lru.Add(key, value) - if c.onEvictedCB != nil && evicted { - k, v = c.evictedKeys[0], c.evictedVals[0] - c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] - } - c.lock.Unlock() - if c.onEvictedCB != nil && evicted { - c.onEvictedCB(k, v) - } - return false, evicted -} - -// PeekOrAdd checks if a key is in the cache without updating the -// recent-ness or deleting it for being stale, and if not, adds the value. -// Returns whether found and whether an eviction occurred. -func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) { - var k, v interface{} - c.lock.Lock() - previous, ok = c.lru.Peek(key) - if ok { - c.lock.Unlock() - return previous, true, false - } - evicted = c.lru.Add(key, value) - if c.onEvictedCB != nil && evicted { - k, v = c.evictedKeys[0], c.evictedVals[0] - c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] - } - c.lock.Unlock() - if c.onEvictedCB != nil && evicted { - c.onEvictedCB(k, v) - } - return nil, false, evicted -} - -// Remove removes the provided key from the cache. -func (c *Cache) Remove(key interface{}) (present bool) { - var k, v interface{} - c.lock.Lock() - present = c.lru.Remove(key) - if c.onEvictedCB != nil && present { - k, v = c.evictedKeys[0], c.evictedVals[0] - c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] - } - c.lock.Unlock() - if c.onEvictedCB != nil && present { - c.onEvictedCB(k, v) - } - return -} - -// Resize changes the cache size. -func (c *Cache) Resize(size int) (evicted int) { - var ks, vs []interface{} - c.lock.Lock() - evicted = c.lru.Resize(size) - if c.onEvictedCB != nil && evicted > 0 { - ks, vs = c.evictedKeys, c.evictedVals - c.initEvictBuffers() - } - c.lock.Unlock() - if c.onEvictedCB != nil && evicted > 0 { - for i := 0; i < len(ks); i++ { - c.onEvictedCB(ks[i], vs[i]) - } - } - return evicted -} - -// RemoveOldest removes the oldest item from the cache. -func (c *Cache) RemoveOldest() (key, value interface{}, ok bool) { - var k, v interface{} - c.lock.Lock() - key, value, ok = c.lru.RemoveOldest() - if c.onEvictedCB != nil && ok { - k, v = c.evictedKeys[0], c.evictedVals[0] - c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] - } - c.lock.Unlock() - if c.onEvictedCB != nil && ok { - c.onEvictedCB(k, v) - } - return -} - -// GetOldest returns the oldest entry -func (c *Cache) GetOldest() (key, value interface{}, ok bool) { - c.lock.RLock() - key, value, ok = c.lru.GetOldest() - c.lock.RUnlock() - return -} - -// Keys returns a slice of the keys in the cache, from oldest to newest. -func (c *Cache) Keys() []interface{} { - c.lock.RLock() - keys := c.lru.Keys() - c.lock.RUnlock() - return keys -} - -// Len returns the number of items in the cache. -func (c *Cache) Len() int { - c.lock.RLock() - length := c.lru.Len() - c.lock.RUnlock() - return length -} diff --git a/vendor/github.com/hashicorp/golang-lru/testing.go b/vendor/github.com/hashicorp/golang-lru/testing.go deleted file mode 100644 index 492760782c..0000000000 --- a/vendor/github.com/hashicorp/golang-lru/testing.go +++ /dev/null @@ -1,16 +0,0 @@ -package lru - -import ( - "crypto/rand" - "math" - "math/big" - "testing" -) - -func getRand(tb testing.TB) int64 { - out, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) - if err != nil { - tb.Fatal(err) - } - return out.Int64() -} diff --git a/vendor/github.com/thanos-io/thanos/pkg/block/indexheader/binary_reader.go b/vendor/github.com/thanos-io/thanos/pkg/block/indexheader/binary_reader.go index c86185bfbf..1afaabb786 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/block/indexheader/binary_reader.go +++ b/vendor/github.com/thanos-io/thanos/pkg/block/indexheader/binary_reader.go @@ -875,6 +875,7 @@ func (r *BinaryReader) postingsOffset(name string, values ...string) ([]index.Ra // Iterate on the offset table. newSameRngs = newSameRngs[:0] + Iter: for d.Err() == nil { // Posting format entry is as follows: // │ ┌────────────────────────────────────────┐ │ @@ -916,6 +917,15 @@ func (r *BinaryReader) postingsOffset(name string, values ...string) ([]index.Ra break } wantedValue = values[valueIndex] + // Only do this if there is no new range added. If there is an existing + // range we want to continue iterating the offset table to get the end. + if len(newSameRngs) == 0 && i+1 < len(e.offsets) { + // We want to limit this loop within e.offsets[i, i+1). So when the wanted value + // is >= e.offsets[i+1], go out of the loop and binary search again. + if wantedValue >= e.offsets[i+1].value { + break Iter + } + } } if i+1 == len(e.offsets) { @@ -942,7 +952,7 @@ func (r *BinaryReader) postingsOffset(name string, values ...string) ([]index.Ra if len(newSameRngs) > 0 { // We added some ranges in this iteration. Use next posting offset as the end of our ranges. - // We know it exists as we never go further in this loop than e.offsets[i, i+1]. + // We know it exists as we never go further in this loop than e.offsets[i, i+1). skipNAndName(&d, &buf) d.UvarintBytes() // Label value. diff --git a/vendor/github.com/thanos-io/thanos/pkg/cache/inmemory.go b/vendor/github.com/thanos-io/thanos/pkg/cache/inmemory.go index a413842fbb..165d4ecbb5 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/cache/inmemory.go +++ b/vendor/github.com/thanos-io/thanos/pkg/cache/inmemory.go @@ -10,7 +10,7 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" - lru "github.com/hashicorp/golang-lru/simplelru" + lru "github.com/hashicorp/golang-lru/v2/simplelru" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -46,7 +46,7 @@ type InMemoryCache struct { mtx sync.Mutex curSize uint64 - lru *lru.LRU + lru *lru.LRU[string, cacheDataWithTTLWrapper] evicted prometheus.Counter requests prometheus.Counter hits prometheus.Counter @@ -62,11 +62,12 @@ type InMemoryCache struct { type cacheDataWithTTLWrapper struct { data []byte - // The objects that are over the TTL are not destroyed eagerly. - // When there is a hit for an item that is over the TTL, the object is removed from the cache - // and null is returned. - // There is ongoing effort to integrate TTL within the Hashicorp golang cache itself. - // This https://github.com/hashicorp/golang-lru/pull/41 can be used here once complete. + // Items exceeding their Time-To-Live (TTL) are not immediately removed from the cache. + // Instead, when an access attempt is made for an item past its TTL, the item is evicted from the cache, and a null value is returned. + // Efforts are underway to incorporate TTL directly into the Hashicorp golang cache. + // Although this pull request (https://github.com/hashicorp/golang-lru/pull/41) has been completed, it's challenging to apply here due to the following reasons: + // The Hashicorp LRU API requires setting the TTL during the constructor phase, whereas in Thanos, we set the TTL for each Set()/Store() operation. + // Refer to this link for more details: https://github.com/thanos-io/thanos/blob/23d205286436291fa0c55c25c392ee08f42d5fbf/pkg/store/cache/caching_bucket.go#L167-L175 expiryTime time.Time } @@ -176,7 +177,7 @@ func NewInMemoryCacheWithConfig(name string, logger log.Logger, reg prometheus.R // Initialize LRU cache with a high size limit since we will manage evictions ourselves // based on stored size using `RemoveOldest` method. - l, err := lru.NewLRU(maxInt, c.onEvict) + l, err := lru.NewLRU[string, cacheDataWithTTLWrapper](maxInt, c.onEvict) if err != nil { return nil, err } @@ -191,9 +192,9 @@ func NewInMemoryCacheWithConfig(name string, logger log.Logger, reg prometheus.R return c, nil } -func (c *InMemoryCache) onEvict(key, val interface{}) { - keySize := uint64(len(key.(string))) - entrySize := uint64(len(val.(cacheDataWithTTLWrapper).data)) +func (c *InMemoryCache) onEvict(key string, val cacheDataWithTTLWrapper) { + keySize := uint64(len(key)) + entrySize := uint64(len(val.data)) c.evicted.Inc() c.current.Dec() @@ -214,13 +215,13 @@ func (c *InMemoryCache) get(key string) ([]byte, bool) { } // If the present time is greater than the TTL for the object from cache, the object will be // removed from the cache and a nil will be returned - if time.Now().After(v.(cacheDataWithTTLWrapper).expiryTime) { + if time.Now().After(v.expiryTime) { c.hitsExpired.Inc() c.lru.Remove(key) return nil, false } c.hits.Inc() - return v.(cacheDataWithTTLWrapper).data, true + return v.data, true } func (c *InMemoryCache) set(key string, val []byte, ttl time.Duration) { diff --git a/vendor/github.com/thanos-io/thanos/pkg/losertree/tree.go b/vendor/github.com/thanos-io/thanos/pkg/losertree/tree.go new file mode 100644 index 0000000000..d0194d35ec --- /dev/null +++ b/vendor/github.com/thanos-io/thanos/pkg/losertree/tree.go @@ -0,0 +1,161 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +// Original version copyright Bryan Boreham, 2024. +// https://github.com/bboreham/go-loser/tree/any. +// Loser tree, from https://en.wikipedia.org/wiki/K-way_merge_algorithm#Tournament_Tree + +package losertree + +type Sequence interface { + Next() bool // Advances and returns true if there is a value at this new position. +} + +func New[E any, S Sequence](sequences []S, maxVal E, at func(S) E, less func(E, E) bool, close func(S)) *Tree[E, S] { + nSequences := len(sequences) + t := Tree[E, S]{ + maxVal: maxVal, + at: at, + less: less, + close: close, + nodes: make([]node[E, S], nSequences*2), + } + for i, s := range sequences { + t.nodes[i+nSequences].items = s + t.moveNext(i + nSequences) // Must call Next on each item so that At() has a value. + } + if nSequences > 0 { + t.nodes[0].index = -1 // flag to be initialized on first call to Next(). + } + return &t +} + +// Call the close function on all sequences that are still open. +func (t *Tree[E, S]) Close() { + for _, e := range t.nodes[len(t.nodes)/2 : len(t.nodes)] { + if e.index == -1 { + continue + } + t.close(e.items) + } +} + +// A loser tree is a binary tree laid out such that nodes N and N+1 have parent N/2. +// We store M leaf nodes in positions M...2M-1, and M-1 internal nodes in positions 1..M-1. +// Node 0 is a special node, containing the winner of the contest. +type Tree[E any, S Sequence] struct { + maxVal E + at func(S) E + less func(E, E) bool + close func(S) // Called when Next() returns false. + nodes []node[E, S] +} + +type node[E any, S Sequence] struct { + index int // This is the loser for all nodes except the 0th, where it is the winner. + value E // Value copied from the loser node, or winner for node 0. + items S // Only populated for leaf nodes. +} + +func (t *Tree[E, S]) moveNext(index int) bool { + n := &t.nodes[index] + if n.items.Next() { + n.value = t.at(n.items) + return true + } + t.close(n.items) // Next() returned false; close it and mark as finished. + n.value = t.maxVal + n.index = -1 + return false +} + +func (t *Tree[E, S]) Winner() S { + return t.nodes[t.nodes[0].index].items +} + +func (t *Tree[E, S]) At() E { + return t.nodes[0].value +} + +func (t *Tree[E, S]) Next() bool { + nodes := t.nodes + if len(nodes) == 0 { + return false + } + if nodes[0].index == -1 { // If tree has not been initialized yet, do that. + t.initialize() + return nodes[nodes[0].index].index != -1 + } + if nodes[nodes[0].index].index == -1 { // already exhausted. + return false + } + t.moveNext(nodes[0].index) + t.replayGames(nodes[0].index) + return nodes[nodes[0].index].index != -1 +} + +// Current winner has been advanced independently; fix up the loser tree. +func (t *Tree[E, S]) Fix(closed bool) { + nodes := t.nodes + cur := &nodes[nodes[0].index] + if closed { + cur.value = t.maxVal + cur.index = -1 + } else { + cur.value = t.at(cur.items) + } + t.replayGames(nodes[0].index) +} + +func (t *Tree[E, S]) IsEmpty() bool { + nodes := t.nodes + if nodes[0].index == -1 { // If tree has not been initialized yet, do that. + t.initialize() + } + return nodes[nodes[0].index].index == -1 +} + +func (t *Tree[E, S]) initialize() { + winner := t.playGame(1) + t.nodes[0].index = winner + t.nodes[0].value = t.nodes[winner].value +} + +// Find the winner at position pos; if it is a non-leaf node, store the loser. +// pos must be >= 1 and < len(t.nodes). +func (t *Tree[E, S]) playGame(pos int) int { + nodes := t.nodes + if pos >= len(nodes)/2 { + return pos + } + left := t.playGame(pos * 2) + right := t.playGame(pos*2 + 1) + var loser, winner int + if t.less(nodes[left].value, nodes[right].value) { + loser, winner = right, left + } else { + loser, winner = left, right + } + nodes[pos].index = loser + nodes[pos].value = nodes[loser].value + return winner +} + +// Starting at pos, which is a winner, re-consider all values up to the root. +func (t *Tree[E, S]) replayGames(pos int) { + nodes := t.nodes + winningValue := nodes[pos].value + for n := parent(pos); n != 0; n = parent(n) { + node := &nodes[n] + if t.less(node.value, winningValue) { + // Record pos as the loser here, and the old loser is the new winner. + node.index, pos = pos, node.index + node.value, winningValue = winningValue, node.value + } + } + // pos is now the winner; store it in node 0. + nodes[0].index = pos + nodes[0].value = winningValue +} + +func parent(i int) int { return i >> 1 } diff --git a/vendor/github.com/thanos-io/thanos/pkg/query/endpointset.go b/vendor/github.com/thanos-io/thanos/pkg/query/endpointset.go index a8005c571d..6dbf8c85cb 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/query/endpointset.go +++ b/vendor/github.com/thanos-io/thanos/pkg/query/endpointset.go @@ -13,15 +13,16 @@ import ( "time" "unicode/utf8" - "github.com/thanos-io/thanos/pkg/api/query/querypb" - "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/model/labels" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "github.com/thanos-io/thanos/pkg/api/query/querypb" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/exemplars/exemplarspb" "github.com/thanos-io/thanos/pkg/info/infopb" @@ -74,7 +75,11 @@ func (es *GRPCEndpointSpec) Addr() string { func (es *endpointRef) Metadata(ctx context.Context, infoClient infopb.InfoClient, storeClient storepb.StoreClient) (*endpointMetadata, error) { if infoClient != nil { resp, err := infoClient.Info(ctx, &infopb.InfoRequest{}, grpc.WaitForReady(true)) - if err == nil { + if err != nil { + if status.Convert(err).Code() != codes.Unimplemented { + return nil, err + } + } else { return &endpointMetadata{resp}, nil } } diff --git a/vendor/github.com/thanos-io/thanos/pkg/query/querier.go b/vendor/github.com/thanos-io/thanos/pkg/query/querier.go index d55285b459..c26bd025ce 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/query/querier.go +++ b/vendor/github.com/thanos-io/thanos/pkg/query/querier.go @@ -399,14 +399,19 @@ func (q *querier) LabelValues(ctx context.Context, name string, matchers ...*lab if err != nil { return nil, nil, errors.Wrap(err, "converting prom matchers to storepb matchers") } - - resp, err := q.proxy.LabelValues(ctx, &storepb.LabelValuesRequest{ + req := &storepb.LabelValuesRequest{ Label: name, PartialResponseStrategy: q.partialResponseStrategy, Start: q.mint, End: q.maxt, Matchers: pbMatchers, - }) + } + + if q.isDedupEnabled() { + req.WithoutReplicaLabels = q.replicaLabels + } + + resp, err := q.proxy.LabelValues(ctx, req) if err != nil { return nil, nil, errors.Wrap(err, "proxy LabelValues()") } @@ -433,12 +438,18 @@ func (q *querier) LabelNames(ctx context.Context, matchers ...*labels.Matcher) ( return nil, nil, errors.Wrap(err, "converting prom matchers to storepb matchers") } - resp, err := q.proxy.LabelNames(ctx, &storepb.LabelNamesRequest{ + req := &storepb.LabelNamesRequest{ PartialResponseStrategy: q.partialResponseStrategy, Start: q.mint, End: q.maxt, Matchers: pbMatchers, - }) + } + + if q.isDedupEnabled() { + req.WithoutReplicaLabels = q.replicaLabels + } + + resp, err := q.proxy.LabelNames(ctx, req) if err != nil { return nil, nil, errors.Wrap(err, "proxy LabelNames()") } diff --git a/vendor/github.com/thanos-io/thanos/pkg/querysharding/analyzer.go b/vendor/github.com/thanos-io/thanos/pkg/querysharding/analyzer.go index c90ecf20d3..7b8e849bca 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/querysharding/analyzer.go +++ b/vendor/github.com/thanos-io/thanos/pkg/querysharding/analyzer.go @@ -19,7 +19,7 @@ package querysharding import ( "fmt" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/promql/parser" ) @@ -38,14 +38,14 @@ type QueryAnalyzer struct{} type CachedQueryAnalyzer struct { analyzer *QueryAnalyzer - cache *lru.Cache + cache *lru.Cache[string, cachedValue] } // NewQueryAnalyzer creates a new QueryAnalyzer. func NewQueryAnalyzer() *CachedQueryAnalyzer { // Ignore the error check since it throws error // only if size is <= 0. - cache, _ := lru.New(256) + cache, _ := lru.New[string, cachedValue](256) return &CachedQueryAnalyzer{ analyzer: &QueryAnalyzer{}, cache: cache, @@ -61,7 +61,7 @@ func (a *CachedQueryAnalyzer) Analyze(query string) (QueryAnalysis, error) { if a.cache.Contains(query) { value, ok := a.cache.Get(query) if ok { - return value.(cachedValue).QueryAnalysis, value.(cachedValue).err + return value.QueryAnalysis, value.err } } diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/bucket.go b/vendor/github.com/thanos-io/thanos/pkg/store/bucket.go index 1951c217bf..43ac0d6c1a 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/bucket.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/bucket.go @@ -42,7 +42,6 @@ import ( "google.golang.org/grpc/status" "github.com/thanos-io/objstore" - "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/indexheader" "github.com/thanos-io/thanos/pkg/block/metadata" @@ -874,18 +873,39 @@ func (s *BucketStore) TSDBInfos() []infopb.TSDBInfo { s.mtx.RLock() defer s.mtx.RUnlock() - infos := make([]infopb.TSDBInfo, 0, len(s.blocks)) + infoMap := make(map[uint64][]infopb.TSDBInfo, len(s.blocks)) for _, b := range s.blocks { - infos = append(infos, infopb.TSDBInfo{ + lbls := labels.FromMap(b.meta.Thanos.Labels) + hash := lbls.Hash() + infoMap[hash] = append(infoMap[hash], infopb.TSDBInfo{ Labels: labelpb.ZLabelSet{ - Labels: labelpb.ZLabelsFromPromLabels(labels.FromMap(b.meta.Thanos.Labels)), + Labels: labelpb.ZLabelsFromPromLabels(lbls), }, MinTime: b.meta.MinTime, MaxTime: b.meta.MaxTime, }) } - return infos + // join adjacent blocks so we emit less TSDBInfos + res := make([]infopb.TSDBInfo, 0, len(s.blocks)) + for _, infos := range infoMap { + sort.Slice(infos, func(i, j int) bool { return infos[i].MinTime < infos[j].MinTime }) + + cur := infos[0] + for i, info := range infos { + if info.MinTime > cur.MaxTime { + res = append(res, cur) + cur = info + continue + } + cur.MaxTime = info.MaxTime + if i == len(infos)-1 { + res = append(res, cur) + } + } + } + + return res } func (s *BucketStore) LabelSet() []labelpb.ZLabelSet { @@ -1640,13 +1660,8 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, seriesSrv storepb.Store // Merge the sub-results from each selected block. tracing.DoInSpan(ctx, "bucket_store_merge_all", func(ctx context.Context) { - defer func() { - for _, resp := range respSets { - resp.Close() - } - }() begin := time.Now() - set := NewDedupResponseHeap(NewProxyResponseHeap(respSets...)) + set := NewResponseDeduplicator(NewProxyResponseLoserTree(respSets...)) for set.Next() { at := set.At() warn := at.GetWarning() @@ -1734,6 +1749,12 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq return nil, status.Error(codes.InvalidArgument, errors.Wrap(err, "translate request hints labels matchers").Error()) } } + extLsetToRemove := make(map[string]struct{}) + if len(req.WithoutReplicaLabels) > 0 { + for _, l := range req.WithoutReplicaLabels { + extLsetToRemove[l] = struct{}{} + } + } g, gctx := errgroup.WithContext(ctx) @@ -1790,15 +1811,18 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq // b.extLset is already sorted by label name, no need to sort it again. extRes := make([]string, 0, b.extLset.Len()) b.extLset.Range(func(l labels.Label) { - extRes = append(extRes, l.Name) + if _, ok := extLsetToRemove[l.Name]; !ok { + extRes = append(extRes, l.Name) + } }) result = strutil.MergeSlices(res, extRes) } else { seriesReq := &storepb.SeriesRequest{ - MinTime: req.Start, - MaxTime: req.End, - SkipChunks: true, + MinTime: req.Start, + MaxTime: req.End, + SkipChunks: true, + WithoutReplicaLabels: req.WithoutReplicaLabels, } blockClient := newBlockSeriesClient( newCtx, @@ -1815,7 +1839,7 @@ func (s *BucketStore) LabelNames(ctx context.Context, req *storepb.LabelNamesReq s.metrics.seriesFetchDurationSum, nil, nil, - nil, + extLsetToRemove, s.enabledLazyExpandedPostings, s.metrics.lazyExpandedPostingsCount, s.metrics.lazyExpandedPostingSizeBytes, @@ -1917,6 +1941,11 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR if err != nil { return nil, status.Error(codes.InvalidArgument, errors.Wrap(err, "translate request labels matchers").Error()) } + for i := range req.WithoutReplicaLabels { + if req.Label == req.WithoutReplicaLabels[i] { + return &storepb.LabelValuesResponse{}, nil + } + } tenant, _ := tenancy.GetTenantFromGRPCMetadata(ctx) @@ -2001,9 +2030,10 @@ func (s *BucketStore) LabelValues(ctx context.Context, req *storepb.LabelValuesR result = res } else { seriesReq := &storepb.SeriesRequest{ - MinTime: req.Start, - MaxTime: req.End, - SkipChunks: true, + MinTime: req.Start, + MaxTime: req.End, + SkipChunks: true, + WithoutReplicaLabels: req.WithoutReplicaLabels, } blockClient := newBlockSeriesClient( newCtx, diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/cache/inmemory.go b/vendor/github.com/thanos-io/thanos/pkg/store/cache/inmemory.go index e198d69ca6..42e6de55a7 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/cache/inmemory.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/cache/inmemory.go @@ -10,7 +10,7 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" - lru "github.com/hashicorp/golang-lru/simplelru" + lru "github.com/hashicorp/golang-lru/v2/simplelru" "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" @@ -36,7 +36,7 @@ type InMemoryIndexCache struct { mtx sync.Mutex logger log.Logger - lru *lru.LRU + lru *lru.LRU[CacheKey, []byte] maxSizeBytes uint64 maxItemSizeBytes uint64 @@ -170,7 +170,7 @@ func NewInMemoryIndexCacheWithConfig(logger log.Logger, commonMetrics *CommonMet // Initialize LRU cache with a high size limit since we will manage evictions ourselves // based on stored size using `RemoveOldest` method. - l, err := lru.NewLRU(maxInt, c.onEvict) + l, err := lru.NewLRU[CacheKey, []byte](maxInt, c.onEvict) if err != nil { return nil, err } @@ -185,14 +185,14 @@ func NewInMemoryIndexCacheWithConfig(logger log.Logger, commonMetrics *CommonMet return c, nil } -func (c *InMemoryIndexCache) onEvict(key, val interface{}) { - k := key.(CacheKey).KeyType() - entrySize := sliceHeaderSize + uint64(len(val.([]byte))) +func (c *InMemoryIndexCache) onEvict(key CacheKey, val []byte) { + k := key.KeyType() + entrySize := sliceHeaderSize + uint64(len(val)) c.evicted.WithLabelValues(k).Inc() c.current.WithLabelValues(k).Dec() c.currentSize.WithLabelValues(k).Sub(float64(entrySize)) - c.totalCurrentSize.WithLabelValues(k).Sub(float64(entrySize + key.(CacheKey).Size())) + c.totalCurrentSize.WithLabelValues(k).Sub(float64(entrySize + key.Size())) c.curSize -= entrySize } @@ -205,7 +205,7 @@ func (c *InMemoryIndexCache) get(key CacheKey) ([]byte, bool) { if !ok { return nil, false } - return v.([]byte), true + return v, true } func (c *InMemoryIndexCache) set(typ string, key CacheKey, val []byte) { diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/lazy_postings.go b/vendor/github.com/thanos-io/thanos/pkg/store/lazy_postings.go index 9469be9b47..cfcf987e14 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/lazy_postings.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/lazy_postings.go @@ -8,6 +8,7 @@ import ( "math" "strings" + "github.com/go-kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/model/labels" @@ -54,14 +55,18 @@ func optimizePostingsFetchByDownloadedBytes(r *bucketIndexReader, postingGroups return nil, false, errors.Wrapf(err, "postings offsets for %s", pg.name) } - for _, r := range rngs { - if r == indexheader.NotFoundRange { + for _, rng := range rngs { + if rng == indexheader.NotFoundRange { continue } + if rng.End <= rng.Start { + level.Error(r.block.logger).Log("msg", "invalid index range, fallback to non lazy posting optimization") + return postingGroups, false, nil + } // Each range starts from the #entries field which is 4 bytes. // Need to subtract it when calculating number of postings. // https://github.com/prometheus/prometheus/blob/v2.46.0/tsdb/docs/format/index.md. - pg.cardinality += (r.End - r.Start - 4) / 4 + pg.cardinality += (rng.End - rng.Start - 4) / 4 } // If the posting group adds keys, 0 cardinality means the posting doesn't exist. // If the posting group removes keys, no posting ranges found is fine as it is a noop. diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/prometheus.go b/vendor/github.com/thanos-io/thanos/pkg/store/prometheus.go index c03d489a95..d52fcb07d9 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/prometheus.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/prometheus.go @@ -606,9 +606,16 @@ func (p *PrometheusStore) LabelNames(ctx context.Context, r *storepb.LabelNamesR } } + extLsetToRemove := map[string]struct{}{} + for _, lbl := range r.WithoutReplicaLabels { + extLsetToRemove[lbl] = struct{}{} + } + if len(lbls) > 0 { extLset.Range(func(l labels.Label) { - lbls = append(lbls, l.Name) + if _, ok := extLsetToRemove[l.Name]; !ok { + lbls = append(lbls, l.Name) + } }) sort.Strings(lbls) } @@ -621,6 +628,11 @@ func (p *PrometheusStore) LabelValues(ctx context.Context, r *storepb.LabelValue if r.Label == "" { return nil, status.Error(codes.InvalidArgument, "label name parameter cannot be empty") } + for i := range r.WithoutReplicaLabels { + if r.Label == r.WithoutReplicaLabels[i] { + return &storepb.LabelValuesResponse{}, nil + } + } extLset := p.externalLabelsFn() diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/proxy.go b/vendor/github.com/thanos-io/thanos/pkg/store/proxy.go index 666f130ece..778879e117 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/proxy.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/proxy.go @@ -274,8 +274,12 @@ func (s *ProxyStore) TimeRange() (int64, int64) { func (s *ProxyStore) TSDBInfos() []infopb.TSDBInfo { infos := make([]infopb.TSDBInfo, 0) - for _, store := range s.stores() { - infos = append(infos, store.TSDBInfos()...) + for _, st := range s.stores() { + matches, _ := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) + if !matches { + continue + } + infos = append(infos, st.TSDBInfos()...) } return infos } @@ -283,7 +287,10 @@ func (s *ProxyStore) TSDBInfos() []infopb.TSDBInfo { func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { // TODO(bwplotka): This should be part of request logger, otherwise it does not make much sense. Also, could be // tiggered by tracing span to reduce cognitive load. - reqLogger := log.With(s.logger, "component", "proxy", "request", originalRequest.String()) + reqLogger := log.With(s.logger, "component", "proxy") + if s.debugLogging { + reqLogger = log.With(reqLogger, "request", originalRequest.String()) + } match, matchers, err := matchesExternalLabels(originalRequest.Matchers, s.selectorLabels) if err != nil { @@ -333,13 +340,15 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. // We might be able to skip the store if its meta information indicates it cannot have series matching our query. if ok, reason := storeMatches(ctx, st, s.debugLogging, originalRequest.MinTime, originalRequest.MaxTime, matchers...); !ok { if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("store %s filtered out: %v", st, reason)) + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) } continue } - matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) if !matches { + if s.debugLogging { + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) + } continue } storeLabelSets = append(storeLabelSets, extraMatchers...) @@ -357,7 +366,7 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. for _, st := range stores { st := st if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("store %s queried", st)) + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s queried", st)) } respSet, err := newAsyncRespSet(ctx, st, r, s.responseTimeout, s.retrievalStrategy, &s.buffers, r.ShardInfo, reqLogger, s.metrics.emptyStreamResponses) @@ -380,7 +389,7 @@ func (s *ProxyStore) Series(originalRequest *storepb.SeriesRequest, srv storepb. level.Debug(reqLogger).Log("msg", "Series: started fanout streams", "status", strings.Join(storeDebugMsgs, ";")) - respHeap := NewDedupResponseHeap(NewProxyResponseHeap(storeResponses...)) + respHeap := NewResponseDeduplicator(NewProxyResponseLoserTree(storeResponses...)) for respHeap.Next() { resp := respHeap.At() @@ -500,10 +509,18 @@ func (s *ProxyStore) LabelNames(ctx context.Context, r *storepb.LabelNamesReques // We might be able to skip the store if its meta information indicates it cannot have series matching our query. if ok, reason := storeMatches(gctx, st, s.debugLogging, r.Start, r.End); !ok { if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to %v", st, reason)) + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) + } + continue + } + matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) + if !matches { + if s.debugLogging { + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) } continue } + if s.debugLogging { storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s queried", st)) } @@ -513,7 +530,8 @@ func (s *ProxyStore) LabelNames(ctx context.Context, r *storepb.LabelNamesReques PartialResponseDisabled: r.PartialResponseDisabled, Start: r.Start, End: r.End, - Matchers: r.Matchers, + Matchers: append(r.Matchers, MatchersForLabelSets(extraMatchers)...), + WithoutReplicaLabels: r.WithoutReplicaLabels, }) if err != nil { err = errors.Wrapf(err, "fetch label names from store %s", st) @@ -587,7 +605,14 @@ func (s *ProxyStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequ // We might be able to skip the store if its meta information indicates it cannot have series matching our query. if ok, reason := storeMatches(gctx, st, s.debugLogging, r.Start, r.End); !ok { if s.debugLogging { - storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to %v", st, reason)) + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, reason)) + } + continue + } + matches, extraMatchers := s.tsdbSelector.MatchLabelSets(st.LabelSets()...) + if !matches { + if s.debugLogging { + storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("Store %s filtered out due to: %v", st, "tsdb selector")) } continue } @@ -608,7 +633,8 @@ func (s *ProxyStore) LabelValues(ctx context.Context, r *storepb.LabelValuesRequ PartialResponseDisabled: r.PartialResponseDisabled, Start: r.Start, End: r.End, - Matchers: r.Matchers, + Matchers: append(r.Matchers, MatchersForLabelSets(extraMatchers)...), + WithoutReplicaLabels: r.WithoutReplicaLabels, }) if err != nil { msg := "fetch label values from store %s" diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/proxy_heap.go b/vendor/github.com/thanos-io/thanos/pkg/store/proxy_merge.go similarity index 86% rename from vendor/github.com/thanos-io/thanos/pkg/store/proxy_heap.go rename to vendor/github.com/thanos-io/thanos/pkg/store/proxy_merge.go index e77628c7c2..0235958b4f 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/proxy_heap.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/proxy_merge.go @@ -4,7 +4,6 @@ package store import ( - "container/heap" "context" "fmt" "io" @@ -21,13 +20,14 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/prometheus/model/labels" + "github.com/thanos-io/thanos/pkg/losertree" "github.com/thanos-io/thanos/pkg/store/labelpb" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/tracing" ) -type dedupResponseHeap struct { - h *ProxyResponseHeap +type responseDeduplicator struct { + h *losertree.Tree[*storepb.SeriesResponse, respSet] bufferedSameSeries []*storepb.SeriesResponse @@ -38,22 +38,22 @@ type dedupResponseHeap struct { ok bool } -// NewDedupResponseHeap returns a wrapper around ProxyResponseHeap that merged duplicated series messages into one. +// NewResponseDeduplicator returns a wrapper around a loser tree that merges duplicated series messages into one. // It also deduplicates identical chunks identified by the same checksum from each series message. -func NewDedupResponseHeap(h *ProxyResponseHeap) *dedupResponseHeap { +func NewResponseDeduplicator(h *losertree.Tree[*storepb.SeriesResponse, respSet]) *responseDeduplicator { ok := h.Next() var prev *storepb.SeriesResponse if ok { prev = h.At() } - return &dedupResponseHeap{ + return &responseDeduplicator{ h: h, ok: ok, prev: prev, } } -func (d *dedupResponseHeap) Next() bool { +func (d *responseDeduplicator) Next() bool { if d.buffRespI+1 < len(d.bufferedResp) { d.buffRespI++ return true @@ -153,105 +153,43 @@ func chainSeriesAndRemIdenticalChunks(series []*storepb.SeriesResponse) *storepb }) } -func (d *dedupResponseHeap) At() *storepb.SeriesResponse { +func (d *responseDeduplicator) At() *storepb.SeriesResponse { return d.bufferedResp[d.buffRespI] } -// ProxyResponseHeap is a heap for storepb.SeriesSets. -// It performs k-way merge between all of those sets. -// TODO(GiedriusS): can be improved with a tournament tree. -// This is O(n*logk) but can be Theta(n*logk). However, -// tournament trees need n-1 auxiliary nodes so there -// might not be much of a difference. -type ProxyResponseHeap struct { - nodes []ProxyResponseHeapNode -} - -func (h *ProxyResponseHeap) Less(i, j int) bool { - iResp := h.nodes[i].rs.At() - jResp := h.nodes[j].rs.At() - - if iResp.GetSeries() != nil && jResp.GetSeries() != nil { - iLbls := labelpb.ZLabelsToPromLabels(iResp.GetSeries().Labels) - jLbls := labelpb.ZLabelsToPromLabels(jResp.GetSeries().Labels) - - return labels.Compare(iLbls, jLbls) < 0 - } else if iResp.GetSeries() == nil && jResp.GetSeries() != nil { - return true - } else if iResp.GetSeries() != nil && jResp.GetSeries() == nil { - return false - } - - // If it is not a series then the order does not matter. What matters - // is that we get different types of responses one after another. - return false -} - -func (h *ProxyResponseHeap) Len() int { - return len(h.nodes) -} - -func (h *ProxyResponseHeap) Swap(i, j int) { - h.nodes[i], h.nodes[j] = h.nodes[j], h.nodes[i] -} - -func (h *ProxyResponseHeap) Push(x interface{}) { - h.nodes = append(h.nodes, x.(ProxyResponseHeapNode)) -} - -func (h *ProxyResponseHeap) Pop() (v interface{}) { - h.nodes, v = h.nodes[:h.Len()-1], h.nodes[h.Len()-1] - return -} - -func (h *ProxyResponseHeap) Empty() bool { - return h.Len() == 0 -} - -func (h *ProxyResponseHeap) Min() *ProxyResponseHeapNode { - return &h.nodes[0] -} - -type ProxyResponseHeapNode struct { - rs respSet -} - -// NewProxyResponseHeap returns heap that k-way merge series together. +// NewProxyResponseLoserTree returns heap that k-way merge series together. // It's agnostic to duplicates and overlaps, it forwards all duplicated series in random order. -func NewProxyResponseHeap(seriesSets ...respSet) *ProxyResponseHeap { - ret := ProxyResponseHeap{ - nodes: make([]ProxyResponseHeapNode, 0, len(seriesSets)), - } +func NewProxyResponseLoserTree(seriesSets ...respSet) *losertree.Tree[*storepb.SeriesResponse, respSet] { + var maxVal *storepb.SeriesResponse = storepb.NewSeriesResponse(nil) - for _, ss := range seriesSets { - if ss.Empty() { - continue + less := func(a, b *storepb.SeriesResponse) bool { + if a == maxVal && b != maxVal { + return false } - ss := ss - ret.Push(ProxyResponseHeapNode{rs: ss}) - } - - heap.Init(&ret) - - return &ret -} - -func (h *ProxyResponseHeap) Next() bool { - return !h.Empty() -} - -func (h *ProxyResponseHeap) At() *storepb.SeriesResponse { - min := h.Min().rs - - atResp := min.At() + if a != maxVal && b == maxVal { + return true + } + if a == maxVal && b == maxVal { + return true + } + if a.GetSeries() != nil && b.GetSeries() != nil { + iLbls := labelpb.ZLabelsToPromLabels(a.GetSeries().Labels) + jLbls := labelpb.ZLabelsToPromLabels(b.GetSeries().Labels) - if min.Next() { - heap.Fix(h, 0) - } else { - heap.Remove(h, 0) + return labels.Compare(iLbls, jLbls) < 0 + } else if a.GetSeries() == nil && b.GetSeries() != nil { + return true + } else if a.GetSeries() != nil && b.GetSeries() == nil { + return false + } + return false } - return atResp + return losertree.New[*storepb.SeriesResponse, respSet](seriesSets, maxVal, func(s respSet) *storepb.SeriesResponse { + return s.At() + }, less, func(s respSet) { + s.Close() + }) } func (l *lazyRespSet) StoreID() string { @@ -320,6 +258,8 @@ func (l *lazyRespSet) Next() bool { l.bufferedResponsesMtx.Lock() defer l.bufferedResponsesMtx.Unlock() + l.initialized = true + if l.noMoreData && len(l.bufferedResponses) == 0 { l.lastResp = nil @@ -335,7 +275,9 @@ func (l *lazyRespSet) Next() bool { if len(l.bufferedResponses) > 0 { l.lastResp = l.bufferedResponses[0] - l.bufferedResponses = l.bufferedResponses[1:] + if l.initialized { + l.bufferedResponses = l.bufferedResponses[1:] + } return true } @@ -344,14 +286,10 @@ func (l *lazyRespSet) Next() bool { } func (l *lazyRespSet) At() *storepb.SeriesResponse { - // We need to wait for at least one response so that we would be able to properly build the heap. if !l.initialized { - l.Next() - l.initialized = true - return l.lastResp + panic("please call Next before At") } - // Next() was called previously. return l.lastResp } @@ -803,7 +741,9 @@ func sortWithoutLabels(set []*storepb.SeriesResponse, labelsToRemove map[string] } func (l *eagerRespSet) Close() { - l.closeSeries() + if l.closeSeries != nil { + l.closeSeries() + } l.shardMatcher.Close() } @@ -814,7 +754,7 @@ func (l *eagerRespSet) At() *storepb.SeriesResponse { return nil } - return l.bufferedResponses[l.i] + return l.bufferedResponses[l.i-1] } func (l *eagerRespSet) Next() bool { @@ -822,7 +762,7 @@ func (l *eagerRespSet) Next() bool { l.i++ - return l.i < len(l.bufferedResponses) + return l.i <= len(l.bufferedResponses) } func (l *eagerRespSet) Empty() bool { diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.pb.go b/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.pb.go index db64cf60c8..b5e85d69d8 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.pb.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.pb.go @@ -657,6 +657,8 @@ type LabelNamesRequest struct { // implementation of a specific store. Hints *types.Any `protobuf:"bytes,5,opt,name=hints,proto3" json:"hints,omitempty"` Matchers []LabelMatcher `protobuf:"bytes,6,rep,name=matchers,proto3" json:"matchers"` + // same as in series request. + WithoutReplicaLabels []string `protobuf:"bytes,7,rep,name=without_replica_labels,json=withoutReplicaLabels,proto3" json:"without_replica_labels,omitempty"` } func (m *LabelNamesRequest) Reset() { *m = LabelNamesRequest{} } @@ -746,6 +748,8 @@ type LabelValuesRequest struct { // implementation of a specific store. Hints *types.Any `protobuf:"bytes,6,opt,name=hints,proto3" json:"hints,omitempty"` Matchers []LabelMatcher `protobuf:"bytes,7,rep,name=matchers,proto3" json:"matchers"` + // same as in series request. + WithoutReplicaLabels []string `protobuf:"bytes,8,rep,name=without_replica_labels,json=withoutReplicaLabels,proto3" json:"without_replica_labels,omitempty"` } func (m *LabelValuesRequest) Reset() { *m = LabelValuesRequest{} } @@ -846,90 +850,91 @@ func init() { func init() { proto.RegisterFile("store/storepb/rpc.proto", fileDescriptor_a938d55a388af629) } var fileDescriptor_a938d55a388af629 = []byte{ - // 1323 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xdd, 0x6e, 0x13, 0xc7, - 0x17, 0xf7, 0x7a, 0xbd, 0xfe, 0x38, 0x4e, 0xf2, 0x37, 0x83, 0x09, 0x1b, 0x23, 0x39, 0xfe, 0xbb, - 0xaa, 0x64, 0x21, 0x6a, 0x53, 0x83, 0x90, 0x5a, 0x71, 0x93, 0x04, 0x43, 0xa2, 0x12, 0x53, 0xc6, - 0x09, 0x69, 0xa9, 0x2a, 0x6b, 0x6d, 0x4f, 0xd6, 0x2b, 0xec, 0xdd, 0x65, 0x67, 0xb6, 0x89, 0x6f, - 0xdb, 0xdb, 0xaa, 0xaa, 0xfa, 0x08, 0x7d, 0x8a, 0x3e, 0x02, 0x77, 0xe5, 0xb2, 0xea, 0x05, 0x6a, - 0xe1, 0x45, 0xaa, 0x39, 0x3b, 0x6b, 0x7b, 0xd3, 0x00, 0x45, 0x70, 0x13, 0xcd, 0xf9, 0xfd, 0xce, - 0x9c, 0x39, 0xdf, 0xde, 0xc0, 0x65, 0x2e, 0xbc, 0x80, 0xb5, 0xf0, 0xaf, 0x3f, 0x68, 0x05, 0xfe, - 0xb0, 0xe9, 0x07, 0x9e, 0xf0, 0x48, 0x56, 0x8c, 0x2d, 0xd7, 0xe3, 0x95, 0x8d, 0xa4, 0x82, 0x98, - 0xf9, 0x8c, 0x47, 0x2a, 0x95, 0xb2, 0xed, 0xd9, 0x1e, 0x1e, 0x5b, 0xf2, 0xa4, 0xd0, 0x5a, 0xf2, - 0x82, 0x1f, 0x78, 0xd3, 0x33, 0xf7, 0x94, 0xc9, 0x89, 0x35, 0x60, 0x93, 0xb3, 0x94, 0xed, 0x79, - 0xf6, 0x84, 0xb5, 0x50, 0x1a, 0x84, 0xc7, 0x2d, 0xcb, 0x9d, 0x45, 0x54, 0xfd, 0x7f, 0xb0, 0x7a, - 0x14, 0x38, 0x82, 0x51, 0xc6, 0x7d, 0xcf, 0xe5, 0xac, 0xfe, 0x83, 0x06, 0x2b, 0x0a, 0x79, 0x1a, - 0x32, 0x2e, 0xc8, 0x16, 0x80, 0x70, 0xa6, 0x8c, 0xb3, 0xc0, 0x61, 0xdc, 0xd4, 0x6a, 0x7a, 0xa3, - 0xd8, 0xbe, 0x22, 0x6f, 0x4f, 0x99, 0x18, 0xb3, 0x90, 0xf7, 0x87, 0x9e, 0x3f, 0x6b, 0x1e, 0x38, - 0x53, 0xd6, 0x43, 0x95, 0xed, 0xcc, 0xb3, 0x17, 0x9b, 0x29, 0xba, 0x74, 0x89, 0xac, 0x43, 0x56, - 0x30, 0xd7, 0x72, 0x85, 0x99, 0xae, 0x69, 0x8d, 0x02, 0x55, 0x12, 0x31, 0x21, 0x17, 0x30, 0x7f, - 0xe2, 0x0c, 0x2d, 0x53, 0xaf, 0x69, 0x0d, 0x9d, 0xc6, 0x62, 0x7d, 0x15, 0x8a, 0x7b, 0xee, 0xb1, - 0xa7, 0x7c, 0xa8, 0xff, 0x92, 0x86, 0x95, 0x48, 0x8e, 0xbc, 0x24, 0x43, 0xc8, 0x62, 0xa0, 0xb1, - 0x43, 0xab, 0xcd, 0x28, 0xb1, 0xcd, 0xfb, 0x12, 0xdd, 0xbe, 0x2d, 0x5d, 0xf8, 0xf3, 0xc5, 0xe6, - 0x4d, 0xdb, 0x11, 0xe3, 0x70, 0xd0, 0x1c, 0x7a, 0xd3, 0x56, 0xa4, 0xf0, 0x89, 0xe3, 0xa9, 0x53, - 0xcb, 0x7f, 0x62, 0xb7, 0x12, 0x39, 0x6b, 0x3e, 0xc6, 0xdb, 0x54, 0x99, 0x26, 0x1b, 0x90, 0x9f, - 0x3a, 0x6e, 0x5f, 0x06, 0x82, 0x8e, 0xeb, 0x34, 0x37, 0x75, 0x5c, 0x19, 0x29, 0x52, 0xd6, 0x69, - 0x44, 0x29, 0xd7, 0xa7, 0xd6, 0x29, 0x52, 0x2d, 0x28, 0xa0, 0xd5, 0x83, 0x99, 0xcf, 0xcc, 0x4c, - 0x4d, 0x6b, 0xac, 0xb5, 0x2f, 0xc4, 0xde, 0xf5, 0x62, 0x82, 0x2e, 0x74, 0xc8, 0x2d, 0x00, 0x7c, - 0xb0, 0xcf, 0x99, 0xe0, 0xa6, 0x81, 0xf1, 0xcc, 0x6f, 0x44, 0x2e, 0xf5, 0x98, 0x50, 0x69, 0x2d, - 0x4c, 0x94, 0xcc, 0xeb, 0x3f, 0x1a, 0xb0, 0x1a, 0xa5, 0x3c, 0x2e, 0xd5, 0xb2, 0xc3, 0xda, 0xeb, - 0x1d, 0x4e, 0x27, 0x1d, 0xbe, 0x25, 0x29, 0x31, 0x1c, 0xb3, 0x80, 0x9b, 0x3a, 0xbe, 0x5e, 0x4e, - 0x64, 0x73, 0x3f, 0x22, 0x95, 0x03, 0x73, 0x5d, 0xd2, 0x86, 0x4b, 0xd2, 0x64, 0xc0, 0xb8, 0x37, - 0x09, 0x85, 0xe3, 0xb9, 0xfd, 0x13, 0xc7, 0x1d, 0x79, 0x27, 0x18, 0xb4, 0x4e, 0x2f, 0x4e, 0xad, - 0x53, 0x3a, 0xe7, 0x8e, 0x90, 0x22, 0xd7, 0x00, 0x2c, 0xdb, 0x0e, 0x98, 0x6d, 0x09, 0x16, 0xc5, - 0xba, 0xd6, 0x5e, 0x89, 0x5f, 0xdb, 0xb2, 0xed, 0x80, 0x2e, 0xf1, 0xe4, 0x73, 0xd8, 0xf0, 0xad, - 0x40, 0x38, 0xd6, 0x44, 0xbe, 0x82, 0x95, 0xef, 0x8f, 0x1c, 0x6e, 0x0d, 0x26, 0x6c, 0x64, 0x66, - 0x6b, 0x5a, 0x23, 0x4f, 0x2f, 0x2b, 0x85, 0xb8, 0x33, 0xee, 0x28, 0x9a, 0x7c, 0x73, 0xce, 0x5d, - 0x2e, 0x02, 0x4b, 0x30, 0x7b, 0x66, 0xe6, 0xb0, 0x2c, 0x9b, 0xf1, 0xc3, 0x5f, 0x26, 0x6d, 0xf4, - 0x94, 0xda, 0xbf, 0x8c, 0xc7, 0x04, 0xd9, 0x84, 0x22, 0x7f, 0xe2, 0xf8, 0xfd, 0xe1, 0x38, 0x74, - 0x9f, 0x70, 0x33, 0x8f, 0xae, 0x80, 0x84, 0x76, 0x10, 0x21, 0x57, 0xc1, 0x18, 0x3b, 0xae, 0xe0, - 0x66, 0xa1, 0xa6, 0x61, 0x42, 0xa3, 0x09, 0x6c, 0xc6, 0x13, 0xd8, 0xdc, 0x72, 0x67, 0x34, 0x52, - 0x21, 0x04, 0x32, 0x5c, 0x30, 0xdf, 0x04, 0x4c, 0x1b, 0x9e, 0x49, 0x19, 0x8c, 0xc0, 0x72, 0x6d, - 0x66, 0x16, 0x11, 0x8c, 0x04, 0x72, 0x03, 0x8a, 0x4f, 0x43, 0x16, 0xcc, 0xfa, 0x91, 0xed, 0x15, - 0xb4, 0x4d, 0xe2, 0x28, 0x1e, 0x4a, 0x6a, 0x57, 0x32, 0x14, 0x9e, 0xce, 0xcf, 0xe4, 0x3a, 0x00, - 0x1f, 0x5b, 0xc1, 0xa8, 0xef, 0xb8, 0xc7, 0x9e, 0xb9, 0x8a, 0x77, 0x16, 0x0d, 0x29, 0x19, 0x9c, - 0xac, 0x02, 0x8f, 0x8f, 0xe4, 0x26, 0xac, 0x9f, 0x38, 0x62, 0xec, 0x85, 0xa2, 0xaf, 0xe6, 0xb1, - 0xaf, 0x86, 0x6d, 0xad, 0xa6, 0x37, 0x0a, 0xb4, 0xac, 0x58, 0x1a, 0x91, 0xd8, 0x24, 0xbc, 0xfe, - 0xab, 0x06, 0xb0, 0x70, 0x01, 0x53, 0x24, 0x98, 0xdf, 0x9f, 0x3a, 0x93, 0x89, 0xc3, 0x55, 0x3b, - 0x82, 0x84, 0xf6, 0x11, 0x21, 0x35, 0xc8, 0x1c, 0x87, 0xee, 0x10, 0xbb, 0xb1, 0xb8, 0x68, 0x82, - 0xbb, 0xa1, 0x3b, 0xa4, 0xc8, 0x90, 0x6b, 0x90, 0xb7, 0x03, 0x2f, 0xf4, 0x1d, 0xd7, 0xc6, 0x9e, - 0x2a, 0xb6, 0x4b, 0xb1, 0xd6, 0x3d, 0x85, 0xd3, 0xb9, 0x06, 0xf9, 0x28, 0x4e, 0x99, 0x81, 0xaa, - 0xf3, 0x8d, 0x40, 0x25, 0xa8, 0x32, 0x58, 0x3f, 0x81, 0xc2, 0x3c, 0x64, 0x74, 0x51, 0x65, 0x66, - 0xc4, 0x4e, 0xe7, 0x2e, 0x46, 0xfc, 0x88, 0x9d, 0x92, 0xff, 0xc3, 0x8a, 0xf0, 0x84, 0x35, 0xe9, - 0x23, 0xc6, 0xd5, 0xe0, 0x14, 0x11, 0x43, 0x33, 0x9c, 0xac, 0x41, 0x7a, 0x30, 0xc3, 0x15, 0x90, - 0xa7, 0xe9, 0xc1, 0x4c, 0xae, 0x3a, 0x95, 0xab, 0x0c, 0xe6, 0x4a, 0x49, 0xf5, 0x0a, 0x64, 0x64, - 0x64, 0xb2, 0xd8, 0xae, 0xa5, 0xc6, 0xb3, 0x40, 0xf1, 0x5c, 0x6f, 0x43, 0x3e, 0x8e, 0x47, 0xd9, - 0xd3, 0xce, 0xb1, 0xa7, 0x27, 0xec, 0x6d, 0x82, 0x81, 0x81, 0x49, 0x85, 0x44, 0x8a, 0x95, 0x54, - 0xff, 0x49, 0x83, 0xb5, 0x78, 0x3b, 0xa8, 0xa5, 0xd9, 0x80, 0xec, 0x7c, 0x8b, 0xcb, 0x14, 0xad, - 0xcd, 0xbb, 0x00, 0xd1, 0xdd, 0x14, 0x55, 0x3c, 0xa9, 0x40, 0xee, 0xc4, 0x0a, 0x5c, 0x99, 0x78, - 0xdc, 0xd8, 0xbb, 0x29, 0x1a, 0x03, 0xe4, 0x5a, 0xdc, 0xda, 0xfa, 0xeb, 0x5b, 0x7b, 0x37, 0xa5, - 0x9a, 0x7b, 0x3b, 0x0f, 0xd9, 0x80, 0xf1, 0x70, 0x22, 0xea, 0xbf, 0xa5, 0xe1, 0x02, 0xb6, 0x4a, - 0xd7, 0x9a, 0x2e, 0x56, 0xd6, 0x1b, 0x47, 0x5c, 0x7b, 0x8f, 0x11, 0x4f, 0xbf, 0xe7, 0x88, 0x97, - 0xc1, 0xe0, 0xc2, 0x0a, 0x84, 0x5a, 0xef, 0x91, 0x40, 0x4a, 0xa0, 0x33, 0x77, 0xa4, 0x36, 0x9c, - 0x3c, 0x2e, 0x26, 0xdd, 0x78, 0xfb, 0xa4, 0x2f, 0x6f, 0xda, 0xec, 0x7f, 0xdf, 0xb4, 0xf5, 0x00, - 0xc8, 0x72, 0xe6, 0x54, 0x39, 0xcb, 0x60, 0xc8, 0xf6, 0x89, 0x7e, 0x02, 0x0b, 0x34, 0x12, 0x48, - 0x05, 0xf2, 0xaa, 0x52, 0xb2, 0x5f, 0x25, 0x31, 0x97, 0x17, 0xbe, 0xea, 0x6f, 0xf5, 0xb5, 0xfe, - 0x7b, 0x5a, 0x3d, 0xfa, 0xc8, 0x9a, 0x84, 0x8b, 0x7a, 0x95, 0xc1, 0xc0, 0x0e, 0x54, 0x0d, 0x1c, - 0x09, 0x6f, 0xae, 0x62, 0xfa, 0x3d, 0xaa, 0xa8, 0x7f, 0xa8, 0x2a, 0x66, 0xce, 0xa9, 0xa2, 0x71, - 0x4e, 0x15, 0xb3, 0xef, 0x56, 0xc5, 0xdc, 0x3b, 0x54, 0x31, 0x84, 0x8b, 0x89, 0x84, 0xaa, 0x32, - 0xae, 0x43, 0xf6, 0x3b, 0x44, 0x54, 0x1d, 0x95, 0xf4, 0xa1, 0x0a, 0x79, 0xf5, 0x5b, 0x28, 0xcc, - 0x3f, 0x3b, 0x48, 0x11, 0x72, 0x87, 0xdd, 0x2f, 0xba, 0x0f, 0x8e, 0xba, 0xa5, 0x14, 0x29, 0x80, - 0xf1, 0xf0, 0xb0, 0x43, 0xbf, 0x2e, 0x69, 0x24, 0x0f, 0x19, 0x7a, 0x78, 0xbf, 0x53, 0x4a, 0x4b, - 0x8d, 0xde, 0xde, 0x9d, 0xce, 0xce, 0x16, 0x2d, 0xe9, 0x52, 0xa3, 0x77, 0xf0, 0x80, 0x76, 0x4a, - 0x19, 0x89, 0xd3, 0xce, 0x4e, 0x67, 0xef, 0x51, 0xa7, 0x64, 0x48, 0xfc, 0x4e, 0x67, 0xfb, 0xf0, - 0x5e, 0x29, 0x7b, 0x75, 0x1b, 0x32, 0xf2, 0x77, 0x9b, 0xe4, 0x40, 0xa7, 0x5b, 0x47, 0x91, 0xd5, - 0x9d, 0x07, 0x87, 0xdd, 0x83, 0x92, 0x26, 0xb1, 0xde, 0xe1, 0x7e, 0x29, 0x2d, 0x0f, 0xfb, 0x7b, - 0xdd, 0x92, 0x8e, 0x87, 0xad, 0xaf, 0x22, 0x73, 0xa8, 0xd5, 0xa1, 0x25, 0xa3, 0xfd, 0x7d, 0x1a, - 0x0c, 0xf4, 0x91, 0x7c, 0x0a, 0x19, 0x5c, 0xcd, 0x17, 0xe3, 0x8c, 0x2e, 0x7d, 0x05, 0x56, 0xca, - 0x49, 0x50, 0xe5, 0xef, 0x33, 0xc8, 0x46, 0xfb, 0x8b, 0x5c, 0x4a, 0xee, 0xb3, 0xf8, 0xda, 0xfa, - 0x59, 0x38, 0xba, 0x78, 0x5d, 0x23, 0x3b, 0x00, 0x8b, 0xb9, 0x22, 0x1b, 0x89, 0x2a, 0x2e, 0x6f, - 0xa9, 0x4a, 0xe5, 0x3c, 0x4a, 0xbd, 0x7f, 0x17, 0x8a, 0x4b, 0x65, 0x25, 0x49, 0xd5, 0xc4, 0xf0, - 0x54, 0xae, 0x9c, 0xcb, 0x45, 0x76, 0xda, 0x5d, 0x58, 0xc3, 0xef, 0x6e, 0x39, 0x15, 0x51, 0x32, - 0x6e, 0x43, 0x91, 0xb2, 0xa9, 0x27, 0x18, 0xe2, 0x64, 0x1e, 0xfe, 0xf2, 0xe7, 0x79, 0xe5, 0xd2, - 0x19, 0x54, 0x7d, 0xc6, 0xa7, 0xb6, 0x3f, 0x7e, 0xf6, 0x77, 0x35, 0xf5, 0xec, 0x65, 0x55, 0x7b, - 0xfe, 0xb2, 0xaa, 0xfd, 0xf5, 0xb2, 0xaa, 0xfd, 0xfc, 0xaa, 0x9a, 0x7a, 0xfe, 0xaa, 0x9a, 0xfa, - 0xe3, 0x55, 0x35, 0xf5, 0x38, 0xa7, 0xfe, 0x93, 0x18, 0x64, 0xb1, 0x67, 0x6e, 0xfc, 0x13, 0x00, - 0x00, 0xff, 0xff, 0x73, 0x1f, 0x05, 0x4d, 0xb3, 0x0c, 0x00, 0x00, + // 1331 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x13, 0x47, + 0x14, 0xf7, 0x7a, 0xbd, 0xfe, 0xf3, 0x9c, 0xb8, 0x66, 0x30, 0x61, 0x63, 0x24, 0xc7, 0x75, 0x55, + 0xc9, 0x42, 0xd4, 0xa6, 0x06, 0x21, 0xb5, 0xe2, 0x92, 0x04, 0x43, 0xa2, 0x12, 0x53, 0xc6, 0x09, + 0x69, 0xa9, 0x2a, 0x6b, 0x6d, 0x4f, 0xd6, 0x2b, 0xec, 0xdd, 0x65, 0x67, 0xb6, 0x89, 0xaf, 0xad, + 0x7a, 0xab, 0xaa, 0xaa, 0x1f, 0xa1, 0x9f, 0x86, 0x23, 0xc7, 0xaa, 0x07, 0xd4, 0xc2, 0xbd, 0x9f, + 0xa1, 0x9a, 0x3f, 0xbb, 0xf6, 0xa6, 0x21, 0x08, 0x91, 0x4b, 0x34, 0xef, 0xf7, 0x7b, 0xf3, 0xe6, + 0xfd, 0xcf, 0x1a, 0xae, 0x52, 0xe6, 0x05, 0xa4, 0x2d, 0xfe, 0xfa, 0xc3, 0x76, 0xe0, 0x8f, 0x5a, + 0x7e, 0xe0, 0x31, 0x0f, 0x65, 0xd9, 0xc4, 0x72, 0x3d, 0x5a, 0x5d, 0x4f, 0x2a, 0xb0, 0xb9, 0x4f, + 0xa8, 0x54, 0xa9, 0x56, 0x6c, 0xcf, 0xf6, 0xc4, 0xb1, 0xcd, 0x4f, 0x0a, 0xad, 0x27, 0x2f, 0xf8, + 0x81, 0x37, 0x3b, 0x75, 0x4f, 0x99, 0x9c, 0x5a, 0x43, 0x32, 0x3d, 0x4d, 0xd9, 0x9e, 0x67, 0x4f, + 0x49, 0x5b, 0x48, 0xc3, 0xf0, 0xa8, 0x6d, 0xb9, 0x73, 0x49, 0x35, 0x3e, 0x82, 0xd5, 0xc3, 0xc0, + 0x61, 0x04, 0x13, 0xea, 0x7b, 0x2e, 0x25, 0x8d, 0x9f, 0x34, 0x58, 0x51, 0xc8, 0xf3, 0x90, 0x50, + 0x86, 0x36, 0x01, 0x98, 0x33, 0x23, 0x94, 0x04, 0x0e, 0xa1, 0xa6, 0x56, 0xd7, 0x9b, 0xc5, 0xce, + 0x35, 0x7e, 0x7b, 0x46, 0xd8, 0x84, 0x84, 0x74, 0x30, 0xf2, 0xfc, 0x79, 0x6b, 0xdf, 0x99, 0x91, + 0xbe, 0x50, 0xd9, 0xca, 0xbc, 0x78, 0xb5, 0x91, 0xc2, 0x4b, 0x97, 0xd0, 0x1a, 0x64, 0x19, 0x71, + 0x2d, 0x97, 0x99, 0xe9, 0xba, 0xd6, 0x2c, 0x60, 0x25, 0x21, 0x13, 0x72, 0x01, 0xf1, 0xa7, 0xce, + 0xc8, 0x32, 0xf5, 0xba, 0xd6, 0xd4, 0x71, 0x24, 0x36, 0x56, 0xa1, 0xb8, 0xeb, 0x1e, 0x79, 0xca, + 0x87, 0xc6, 0xef, 0x69, 0x58, 0x91, 0xb2, 0xf4, 0x12, 0x8d, 0x20, 0x2b, 0x02, 0x8d, 0x1c, 0x5a, + 0x6d, 0xc9, 0xc4, 0xb6, 0x1e, 0x72, 0x74, 0xeb, 0x2e, 0x77, 0xe1, 0xaf, 0x57, 0x1b, 0xb7, 0x6d, + 0x87, 0x4d, 0xc2, 0x61, 0x6b, 0xe4, 0xcd, 0xda, 0x52, 0xe1, 0x33, 0xc7, 0x53, 0xa7, 0xb6, 0xff, + 0xcc, 0x6e, 0x27, 0x72, 0xd6, 0x7a, 0x2a, 0x6e, 0x63, 0x65, 0x1a, 0xad, 0x43, 0x7e, 0xe6, 0xb8, + 0x03, 0x1e, 0x88, 0x70, 0x5c, 0xc7, 0xb9, 0x99, 0xe3, 0xf2, 0x48, 0x05, 0x65, 0x9d, 0x48, 0x4a, + 0xb9, 0x3e, 0xb3, 0x4e, 0x04, 0xd5, 0x86, 0x82, 0xb0, 0xba, 0x3f, 0xf7, 0x89, 0x99, 0xa9, 0x6b, + 0xcd, 0x52, 0xe7, 0x52, 0xe4, 0x5d, 0x3f, 0x22, 0xf0, 0x42, 0x07, 0xdd, 0x01, 0x10, 0x0f, 0x0e, + 0x28, 0x61, 0xd4, 0x34, 0x44, 0x3c, 0xf1, 0x0d, 0xe9, 0x52, 0x9f, 0x30, 0x95, 0xd6, 0xc2, 0x54, + 0xc9, 0xb4, 0xf1, 0x8b, 0x01, 0xab, 0x32, 0xe5, 0x51, 0xa9, 0x96, 0x1d, 0xd6, 0xde, 0xee, 0x70, + 0x3a, 0xe9, 0xf0, 0x1d, 0x4e, 0xb1, 0xd1, 0x84, 0x04, 0xd4, 0xd4, 0xc5, 0xeb, 0x95, 0x44, 0x36, + 0xf7, 0x24, 0xa9, 0x1c, 0x88, 0x75, 0x51, 0x07, 0xae, 0x70, 0x93, 0x01, 0xa1, 0xde, 0x34, 0x64, + 0x8e, 0xe7, 0x0e, 0x8e, 0x1d, 0x77, 0xec, 0x1d, 0x8b, 0xa0, 0x75, 0x7c, 0x79, 0x66, 0x9d, 0xe0, + 0x98, 0x3b, 0x14, 0x14, 0xba, 0x01, 0x60, 0xd9, 0x76, 0x40, 0x6c, 0x8b, 0x11, 0x19, 0x6b, 0xa9, + 0xb3, 0x12, 0xbd, 0xb6, 0x69, 0xdb, 0x01, 0x5e, 0xe2, 0xd1, 0x97, 0xb0, 0xee, 0x5b, 0x01, 0x73, + 0xac, 0x29, 0x7f, 0x45, 0x54, 0x7e, 0x30, 0x76, 0xa8, 0x35, 0x9c, 0x92, 0xb1, 0x99, 0xad, 0x6b, + 0xcd, 0x3c, 0xbe, 0xaa, 0x14, 0xa2, 0xce, 0xb8, 0xa7, 0x68, 0xf4, 0xdd, 0x19, 0x77, 0x29, 0x0b, + 0x2c, 0x46, 0xec, 0xb9, 0x99, 0x13, 0x65, 0xd9, 0x88, 0x1e, 0xfe, 0x3a, 0x69, 0xa3, 0xaf, 0xd4, + 0xfe, 0x67, 0x3c, 0x22, 0xd0, 0x06, 0x14, 0xe9, 0x33, 0xc7, 0x1f, 0x8c, 0x26, 0xa1, 0xfb, 0x8c, + 0x9a, 0x79, 0xe1, 0x0a, 0x70, 0x68, 0x5b, 0x20, 0xe8, 0x3a, 0x18, 0x13, 0xc7, 0x65, 0xd4, 0x2c, + 0xd4, 0x35, 0x91, 0x50, 0x39, 0x81, 0xad, 0x68, 0x02, 0x5b, 0x9b, 0xee, 0x1c, 0x4b, 0x15, 0x84, + 0x20, 0x43, 0x19, 0xf1, 0x4d, 0x10, 0x69, 0x13, 0x67, 0x54, 0x01, 0x23, 0xb0, 0x5c, 0x9b, 0x98, + 0x45, 0x01, 0x4a, 0x01, 0xdd, 0x82, 0xe2, 0xf3, 0x90, 0x04, 0xf3, 0x81, 0xb4, 0xbd, 0x22, 0x6c, + 0xa3, 0x28, 0x8a, 0xc7, 0x9c, 0xda, 0xe1, 0x0c, 0x86, 0xe7, 0xf1, 0x19, 0xdd, 0x04, 0xa0, 0x13, + 0x2b, 0x18, 0x0f, 0x1c, 0xf7, 0xc8, 0x33, 0x57, 0xc5, 0x9d, 0x45, 0x43, 0x72, 0x46, 0x4c, 0x56, + 0x81, 0x46, 0x47, 0x74, 0x1b, 0xd6, 0x8e, 0x1d, 0x36, 0xf1, 0x42, 0x36, 0x50, 0xf3, 0x38, 0x50, + 0xc3, 0x56, 0xaa, 0xeb, 0xcd, 0x02, 0xae, 0x28, 0x16, 0x4b, 0x52, 0x34, 0x09, 0x6d, 0xfc, 0xa1, + 0x01, 0x2c, 0x5c, 0x10, 0x29, 0x62, 0xc4, 0x1f, 0xcc, 0x9c, 0xe9, 0xd4, 0xa1, 0xaa, 0x1d, 0x81, + 0x43, 0x7b, 0x02, 0x41, 0x75, 0xc8, 0x1c, 0x85, 0xee, 0x48, 0x74, 0x63, 0x71, 0xd1, 0x04, 0xf7, + 0x43, 0x77, 0x84, 0x05, 0x83, 0x6e, 0x40, 0xde, 0x0e, 0xbc, 0xd0, 0x77, 0x5c, 0x5b, 0xf4, 0x54, + 0xb1, 0x53, 0x8e, 0xb4, 0x1e, 0x28, 0x1c, 0xc7, 0x1a, 0xe8, 0x93, 0x28, 0x65, 0x86, 0x50, 0x8d, + 0x37, 0x02, 0xe6, 0xa0, 0xca, 0x60, 0xe3, 0x18, 0x0a, 0x71, 0xc8, 0xc2, 0x45, 0x95, 0x99, 0x31, + 0x39, 0x89, 0x5d, 0x94, 0xfc, 0x98, 0x9c, 0xa0, 0x8f, 0x61, 0x85, 0x79, 0xcc, 0x9a, 0x0e, 0x04, + 0x46, 0xd5, 0xe0, 0x14, 0x05, 0x26, 0xcc, 0x50, 0x54, 0x82, 0xf4, 0x70, 0x2e, 0x56, 0x40, 0x1e, + 0xa7, 0x87, 0x73, 0xbe, 0xea, 0x54, 0xae, 0x32, 0x22, 0x57, 0x4a, 0x6a, 0x54, 0x21, 0xc3, 0x23, + 0xe3, 0xc5, 0x76, 0x2d, 0x35, 0x9e, 0x05, 0x2c, 0xce, 0x8d, 0x0e, 0xe4, 0xa3, 0x78, 0x94, 0x3d, + 0xed, 0x0c, 0x7b, 0x7a, 0xc2, 0xde, 0x06, 0x18, 0x22, 0x30, 0xae, 0x90, 0x48, 0xb1, 0x92, 0x1a, + 0xbf, 0x6a, 0x50, 0x8a, 0xb6, 0x83, 0x5a, 0x9a, 0x4d, 0xc8, 0xc6, 0x5b, 0x9c, 0xa7, 0xa8, 0x14, + 0x77, 0x81, 0x40, 0x77, 0x52, 0x58, 0xf1, 0xa8, 0x0a, 0xb9, 0x63, 0x2b, 0x70, 0x79, 0xe2, 0xc5, + 0xc6, 0xde, 0x49, 0xe1, 0x08, 0x40, 0x37, 0xa2, 0xd6, 0xd6, 0xdf, 0xde, 0xda, 0x3b, 0x29, 0xd5, + 0xdc, 0x5b, 0x79, 0xc8, 0x06, 0x84, 0x86, 0x53, 0xd6, 0xf8, 0x37, 0x0d, 0x97, 0x44, 0xab, 0xf4, + 0xac, 0xd9, 0x62, 0x65, 0x9d, 0x3b, 0xe2, 0xda, 0x07, 0x8c, 0x78, 0xfa, 0x03, 0x47, 0xbc, 0x02, + 0x06, 0x65, 0x56, 0xc0, 0xd4, 0x7a, 0x97, 0x02, 0x2a, 0x83, 0x4e, 0xdc, 0xb1, 0xda, 0x70, 0xfc, + 0xb8, 0x98, 0x74, 0xe3, 0xdd, 0x93, 0xbe, 0xbc, 0x69, 0xb3, 0xef, 0xb1, 0x69, 0xdf, 0x3e, 0x90, + 0xb9, 0x73, 0x06, 0x32, 0x00, 0xb4, 0x9c, 0x6f, 0xd5, 0x04, 0x15, 0x30, 0x78, 0xd3, 0xc9, 0x7f, + 0x9c, 0x05, 0x2c, 0x05, 0x54, 0x85, 0xbc, 0xaa, 0x2f, 0xef, 0x72, 0x4e, 0xc4, 0xf2, 0x22, 0x42, + 0xfd, 0x9d, 0x11, 0x36, 0x7e, 0xd6, 0xd5, 0xa3, 0x4f, 0xac, 0x69, 0xb8, 0xa8, 0x72, 0x05, 0x0c, + 0xe1, 0xb0, 0x6a, 0x7b, 0x29, 0x9c, 0x5f, 0xfb, 0xf4, 0x07, 0xd4, 0x5e, 0xbf, 0xa8, 0xda, 0x67, + 0xce, 0xa8, 0xbd, 0x71, 0x46, 0xed, 0xb3, 0xef, 0x57, 0xfb, 0xdc, 0x85, 0xd4, 0x3e, 0x7f, 0x4e, + 0xed, 0x43, 0xb8, 0x9c, 0x28, 0x83, 0x2a, 0xfe, 0x1a, 0x64, 0x7f, 0x10, 0x88, 0xaa, 0xbe, 0x92, + 0x2e, 0xaa, 0xfc, 0xd7, 0xbf, 0x87, 0x42, 0xfc, 0x89, 0x83, 0x8a, 0x90, 0x3b, 0xe8, 0x7d, 0xd5, + 0x7b, 0x74, 0xd8, 0x2b, 0xa7, 0x50, 0x01, 0x8c, 0xc7, 0x07, 0x5d, 0xfc, 0x6d, 0x59, 0x43, 0x79, + 0xc8, 0xe0, 0x83, 0x87, 0xdd, 0x72, 0x9a, 0x6b, 0xf4, 0x77, 0xef, 0x75, 0xb7, 0x37, 0x71, 0x59, + 0xe7, 0x1a, 0xfd, 0xfd, 0x47, 0xb8, 0x5b, 0xce, 0x70, 0x1c, 0x77, 0xb7, 0xbb, 0xbb, 0x4f, 0xba, + 0x65, 0x83, 0xe3, 0xf7, 0xba, 0x5b, 0x07, 0x0f, 0xca, 0xd9, 0xeb, 0x5b, 0x90, 0xe1, 0xdf, 0x08, + 0x28, 0x07, 0x3a, 0xde, 0x3c, 0x94, 0x56, 0xb7, 0x1f, 0x1d, 0xf4, 0xf6, 0xcb, 0x1a, 0xc7, 0xfa, + 0x07, 0x7b, 0xe5, 0x34, 0x3f, 0xec, 0xed, 0xf6, 0xca, 0xba, 0x38, 0x6c, 0x7e, 0x23, 0xcd, 0x09, + 0xad, 0x2e, 0x2e, 0x1b, 0x9d, 0x1f, 0xd3, 0x60, 0x08, 0x1f, 0xd1, 0xe7, 0x90, 0x11, 0xff, 0x06, + 0x2e, 0x47, 0x75, 0x58, 0xfa, 0xe2, 0xac, 0x56, 0x92, 0xa0, 0xca, 0xdf, 0x17, 0x90, 0x95, 0xbb, + 0x12, 0x5d, 0x49, 0xee, 0xce, 0xe8, 0xda, 0xda, 0x69, 0x58, 0x5e, 0xbc, 0xa9, 0xa1, 0x6d, 0x80, + 0xc5, 0x34, 0xa2, 0xf5, 0x44, 0xed, 0x97, 0x37, 0x62, 0xb5, 0x7a, 0x16, 0xa5, 0xde, 0xbf, 0x0f, + 0xc5, 0xa5, 0xb2, 0xa2, 0xa4, 0x6a, 0x62, 0xe4, 0xaa, 0xd7, 0xce, 0xe4, 0xa4, 0x9d, 0x4e, 0x0f, + 0x4a, 0xe2, 0x1b, 0x9f, 0xcf, 0x92, 0x4c, 0xc6, 0x5d, 0x28, 0x62, 0x32, 0xf3, 0x18, 0x11, 0x38, + 0x8a, 0xc3, 0x5f, 0xfe, 0x29, 0x50, 0xbd, 0x72, 0x0a, 0x55, 0x3f, 0x19, 0x52, 0x5b, 0x9f, 0xbe, + 0xf8, 0xa7, 0x96, 0x7a, 0xf1, 0xba, 0xa6, 0xbd, 0x7c, 0x5d, 0xd3, 0xfe, 0x7e, 0x5d, 0xd3, 0x7e, + 0x7b, 0x53, 0x4b, 0xbd, 0x7c, 0x53, 0x4b, 0xfd, 0xf9, 0xa6, 0x96, 0x7a, 0x9a, 0x53, 0xbf, 0x5a, + 0x86, 0x59, 0xd1, 0x33, 0xb7, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x14, 0xa2, 0x0f, 0x1f, + 0x0d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1885,6 +1890,15 @@ func (m *LabelNamesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.WithoutReplicaLabels) > 0 { + for iNdEx := len(m.WithoutReplicaLabels) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.WithoutReplicaLabels[iNdEx]) + copy(dAtA[i:], m.WithoutReplicaLabels[iNdEx]) + i = encodeVarintRpc(dAtA, i, uint64(len(m.WithoutReplicaLabels[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } if len(m.Matchers) > 0 { for iNdEx := len(m.Matchers) - 1; iNdEx >= 0; iNdEx-- { { @@ -2012,6 +2026,15 @@ func (m *LabelValuesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.WithoutReplicaLabels) > 0 { + for iNdEx := len(m.WithoutReplicaLabels) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.WithoutReplicaLabels[iNdEx]) + copy(dAtA[i:], m.WithoutReplicaLabels[iNdEx]) + i = encodeVarintRpc(dAtA, i, uint64(len(m.WithoutReplicaLabels[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } if len(m.Matchers) > 0 { for iNdEx := len(m.Matchers) - 1; iNdEx >= 0; iNdEx-- { { @@ -2436,6 +2459,12 @@ func (m *LabelNamesRequest) Size() (n int) { n += 1 + l + sovRpc(uint64(l)) } } + if len(m.WithoutReplicaLabels) > 0 { + for _, s := range m.WithoutReplicaLabels { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } return n } @@ -2496,6 +2525,12 @@ func (m *LabelValuesRequest) Size() (n int) { n += 1 + l + sovRpc(uint64(l)) } } + if len(m.WithoutReplicaLabels) > 0 { + for _, s := range m.WithoutReplicaLabels { + l = len(s) + n += 1 + l + sovRpc(uint64(l)) + } + } return n } @@ -4285,6 +4320,38 @@ func (m *LabelNamesRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WithoutReplicaLabels", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WithoutReplicaLabels = append(m.WithoutReplicaLabels, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) @@ -4664,6 +4731,38 @@ func (m *LabelValuesRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WithoutReplicaLabels", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WithoutReplicaLabels = append(m.WithoutReplicaLabels, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.proto b/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.proto index 9e5ebaa693..2a9e9e3eaf 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.proto +++ b/vendor/github.com/thanos-io/thanos/pkg/store/storepb/rpc.proto @@ -232,6 +232,9 @@ message LabelNamesRequest { google.protobuf.Any hints = 5; repeated LabelMatcher matchers = 6 [(gogoproto.nullable) = false]; + + // same as in series request. + repeated string without_replica_labels = 7; } message LabelNamesResponse { @@ -262,6 +265,9 @@ message LabelValuesRequest { google.protobuf.Any hints = 6; repeated LabelMatcher matchers = 7 [(gogoproto.nullable) = false]; + + // same as in series request. + repeated string without_replica_labels = 8; } message LabelValuesResponse { diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/storepb/shard_info.go b/vendor/github.com/thanos-io/thanos/pkg/store/storepb/shard_info.go index e69617dd2f..28d559b49a 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/storepb/shard_info.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/storepb/shard_info.go @@ -29,6 +29,9 @@ func (s *ShardMatcher) IsSharded() bool { } func (s *ShardMatcher) Close() { + if s == nil { + return + } if s.buffers != nil { s.buffers.Put(s.buf) } diff --git a/vendor/github.com/thanos-io/thanos/pkg/store/tsdb.go b/vendor/github.com/thanos-io/thanos/pkg/store/tsdb.go index 68ad31547a..6985c716fa 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/store/tsdb.go +++ b/vendor/github.com/thanos-io/thanos/pkg/store/tsdb.go @@ -307,10 +307,16 @@ func (s *TSDBStore) LabelNames(ctx context.Context, r *storepb.LabelNamesRequest if err != nil { return nil, status.Error(codes.Internal, err.Error()) } + extLsetToRemove := map[string]struct{}{} + for _, lbl := range r.WithoutReplicaLabels { + extLsetToRemove[lbl] = struct{}{} + } if len(res) > 0 { s.getExtLset().Range(func(l labels.Label) { - res = append(res, l.Name) + if _, ok := extLsetToRemove[l.Name]; !ok { + res = append(res, l.Name) + } }) sort.Strings(res) } @@ -335,6 +341,12 @@ func (s *TSDBStore) LabelValues(ctx context.Context, r *storepb.LabelValuesReque return nil, status.Error(codes.InvalidArgument, "label name parameter cannot be empty") } + for i := range r.WithoutReplicaLabels { + if r.Label == r.WithoutReplicaLabels[i] { + return &storepb.LabelValuesResponse{}, nil + } + } + match, matchers, err := matchesExternalLabels(r.Matchers, s.getExtLset()) if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) diff --git a/vendor/modules.txt b/vendor/modules.txt index a5b0a12ac9..97f4e7b54f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -554,7 +554,6 @@ github.com/hashicorp/go-sockaddr github.com/hashicorp/go-version # github.com/hashicorp/golang-lru v0.6.0 ## explicit; go 1.12 -github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru/simplelru # github.com/hashicorp/golang-lru/v2 v2.0.7 ## explicit; go 1.18 @@ -943,7 +942,7 @@ github.com/thanos-io/promql-engine/query github.com/thanos-io/promql-engine/ringbuffer github.com/thanos-io/promql-engine/storage github.com/thanos-io/promql-engine/storage/prometheus -# github.com/thanos-io/thanos v0.34.2-0.20240423183430-7c8fe85682a5 +# github.com/thanos-io/thanos v0.34.2-0.20240501161908-1e745af6720c ## explicit; go 1.21 github.com/thanos-io/thanos/pkg/api/query/querypb github.com/thanos-io/thanos/pkg/block @@ -969,6 +968,7 @@ github.com/thanos-io/thanos/pkg/extprom github.com/thanos-io/thanos/pkg/extprom/http github.com/thanos-io/thanos/pkg/gate github.com/thanos-io/thanos/pkg/info/infopb +github.com/thanos-io/thanos/pkg/losertree github.com/thanos-io/thanos/pkg/metadata/metadatapb github.com/thanos-io/thanos/pkg/model github.com/thanos-io/thanos/pkg/pool