描述
Feature Description
During the grafana/xk6-output-prometheus-remote's PR review discussions, we found that extensions might need memory efficiently iterate on the tag/values because of a standard Map() is not memory efficient.
https://github.com/grafana/k6/blob/e14f14d416b0af4e495e6f565a2a9787a73ade54/metrics/tags.go#L72-L75
This leads that extensions should refer to the internals and iterate like:
func MapTagSet(t *metrics.TagSet) []*prompb.Label {
n := (*atlas.Node)(t)
if n.Len() < 1 {
return nil
}
labels := make([]*prompb.Label, 0, n.Len())
for !n.IsRoot() {
prev, key, value := n.Data()
labels = append(labels, &prompb.Label{Name: key, Value: value})
n = prev
}
return labels
}
Ideally, we should be more developer friendly and provide a way to iterate on tags without casting to an underlying type (atlas.Node).
Also, it seems like it with to mention that Map itself is not memory efficient so extension developers can learn it earlier.
Suggested Solution (optional)
An alternative can be something like:
func (ts *TagSet) Len() int {
return (*atlas.Node)(ts).Len()
}
// Iterate memory efficient way of iterating all tags
func (ts *TagSet) Iterate(fn func(key, value string)) {
if ts.Len() < 1 {
return
}
n := (*atlas.Node)(ts)
for !n.IsRoot() {
prev, key, value := n.Data()
fn(key, value)
n = prev
}
}
then the extension's method will look like:
labels := make([]*prompb.Label, 0, t.Len())
t.Iterate(func (key, value string) {
labels = append(labels, &prompb.Label{Name: key, Value: value})
})
return labels
Already existing or connected issues / PRs (optional)
https://github.com/grafana/xk6-output-prometheus-remote/pull/55