refactor(metricstore): document prune serialization; drop dead GetSelectors leftovers

This commit is contained in:
Aditya Ujeniya
2026-07-22 13:51:49 +02:00
parent 633414d666
commit 28bd9cea68
2 changed files with 5 additions and 56 deletions
+5 -45
View File
@@ -130,45 +130,6 @@ func (l *Level) findLevelOrCreate(selector []string, nMetrics int) *Level {
return child.findLevelOrCreate(selector[1:], nMetrics) return child.findLevelOrCreate(selector[1:], nMetrics)
} }
// collectPaths gathers all selector paths at the specified depth in the tree.
//
// Recursively traverses children, collecting paths when currentDepth+1 == targetDepth.
// Each path is a selector that can be used with findLevel() or findBuffers().
//
// Explicitly copies slices to avoid shared underlying arrays between siblings, preventing
// unintended mutations.
//
// Parameters:
// - currentDepth: Depth of current level (0 = root)
// - targetDepth: Depth to collect paths from
// - currentPath: Path accumulated so far
// - results: Output slice (appended to)
//
// Example: collectPaths(0, 2, []string{}, &results) collects all 2-level paths
// like []string{"emmy", "node001"}, []string{"emmy", "node002"}, etc.
func (l *Level) collectPaths(currentDepth, targetDepth int, currentPath []string, results *[][]string) {
l.lock.RLock()
defer l.lock.RUnlock()
for key, child := range l.children {
if child == nil {
continue
}
// We explicitly make a new slice and copy data to avoid sharing underlying arrays between siblings
newPath := make([]string, len(currentPath))
copy(newPath, currentPath)
newPath = append(newPath, key)
// Check depth, and just return if depth reached
if currentDepth+1 == targetDepth {
*results = append(*results, newPath)
} else {
child.collectPaths(currentDepth+1, targetDepth, newPath, results)
}
}
}
// free removes buffers older than the retention threshold from the entire subtree. // free removes buffers older than the retention threshold from the entire subtree.
// //
// Recursively frees buffers in this level's metrics and all child levels. Buffers // Recursively frees buffers in this level's metrics and all child levels. Buffers
@@ -243,15 +204,17 @@ func (l *Level) freeAndCheckEmpty(t int64) (int, bool, error) {
// retention path when a NodeProvider reports nodes in use by running jobs: // retention path when a NodeProvider reports nodes in use by running jobs:
// used nodes are never freed, so never empty, so never pruned. Holding the root // used nodes are never freed, so never empty, so never pruned. Holding the root
// write lock for the full pass matches the existing root free (ms.Free(nil, t)). // write lock for the full pass matches the existing root free (ms.Free(nil, t)).
//
// Holding the root lock for the entire traversal is intentional: it serializes
// this pass against findLevelOrCreate (which RLocks root first), preventing a
// writer from grabbing a node pointer that this pass then deletes as empty,
// which would silently lose data. Do not "optimize" this to per-cluster locking.
func (l *Level) freeExcludingUsed(t int64, used map[string][]string) (int, error) { func (l *Level) freeExcludingUsed(t int64, used map[string][]string) (int, error) {
l.lock.Lock() l.lock.Lock()
defer l.lock.Unlock() defer l.lock.Unlock()
total := 0 total := 0
for cluster, clusterLvl := range l.children { for cluster, clusterLvl := range l.children {
if clusterLvl == nil {
continue
}
n, empty, err := clusterLvl.freeNodesExcludingUsed(t, used[cluster]) n, empty, err := clusterLvl.freeNodesExcludingUsed(t, used[cluster])
total += n total += n
if err != nil { if err != nil {
@@ -274,9 +237,6 @@ func (l *Level) freeNodesExcludingUsed(t int64, usedHosts []string) (int, bool,
n := 0 n := 0
for node, nodeLvl := range l.children { for node, nodeLvl := range l.children {
if nodeLvl == nil {
continue
}
if _, found := slices.BinarySearch(usedHosts, node); found { if _, found := slices.BinarySearch(usedHosts, node); found {
continue // used node: preserve entirely continue // used node: preserve entirely
} }
-11
View File
@@ -555,17 +555,6 @@ func isNodeUsed(used map[string][]string, cluster, host string) bool {
return found return found
} }
// GetPaths returns a list of lists (paths) to the specified depth.
func (ms *MemoryStore) GetPaths(targetDepth int) [][]string {
var results [][]string
// Start recursion. Initial path is empty.
// We treat Root as depth 0.
ms.root.collectPaths(0, targetDepth, []string{}, &results)
return results
}
// Write all values in `metrics` to the level specified by `selector` for time `ts`. // Write all values in `metrics` to the level specified by `selector` for time `ts`.
// Look at `findLevelOrCreate` for how selectors work. // Look at `findLevelOrCreate` for how selectors work.
func (m *MemoryStore) Write(selector []string, ts int64, metrics []Metric) error { func (m *MemoryStore) Write(selector []string, ts int64, metrics []Metric) error {