master
go 50 lines 1.11 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package metrix
4
5 import (
6 "cmp"
7 "sort"
8 )
9
10 type retentionCandidate[T cmp.Ordered] struct {
11 key string
12 lastSeen T
13 }
14
15 // evictOldestSeries enforces max-series cardinality with deterministic ordering.
16 // Oldest lastSeen values are evicted first; equal ages tie-break by series key.
17 func evictOldestSeries[T cmp.Ordered](
18 series map[string]*committedSeries,
19 maxSeries int,
20 lastSeen func(*committedSeries) T,
21 onEvict func(key string),
22 ) {
23 if maxSeries <= 0 || len(series) <= maxSeries {
24 return
25 }
26
27 candidates := make([]retentionCandidate[T], 0, len(series))
28 for key, s := range series {
29 candidates = append(candidates, retentionCandidate[T]{
30 key: key,
31 lastSeen: lastSeen(s),
32 })
33 }
34
35 sort.Slice(candidates, func(i, j int) bool {
36 if candidates[i].lastSeen != candidates[j].lastSeen {
37 return candidates[i].lastSeen < candidates[j].lastSeen
38 }
39 return candidates[i].key < candidates[j].key
40 })
41
42 evictCount := len(series) - maxSeries
43 for i := range evictCount {
44 key := candidates[i].key
45 delete(series, key)
46 if onEvict != nil {
47 onEvict(key)
48 }
49 }
50 }