|
|
|
@ -81,6 +81,8 @@ type BaseLabelsBuilder struct { |
|
|
|
|
// LabelsBuilder is the same as labels.Builder but tailored for this package.
|
|
|
|
|
type LabelsBuilder struct { |
|
|
|
|
base labels.Labels |
|
|
|
|
baseMap map[string]string |
|
|
|
|
buf labels.Labels |
|
|
|
|
currentResult LabelsResult |
|
|
|
|
groupedResult LabelsResult |
|
|
|
|
|
|
|
|
@ -210,19 +212,33 @@ func (b *LabelsBuilder) Set(n, v string) *LabelsBuilder { |
|
|
|
|
|
|
|
|
|
// Labels returns the labels from the builder. If no modifications
|
|
|
|
|
// were made, the original labels are returned.
|
|
|
|
|
func (b *LabelsBuilder) Labels() labels.Labels { |
|
|
|
|
func (b *LabelsBuilder) labels() labels.Labels { |
|
|
|
|
b.buf = b.unsortedLabels(b.buf) |
|
|
|
|
sort.Sort(b.buf) |
|
|
|
|
return b.buf |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (b *LabelsBuilder) unsortedLabels(buf labels.Labels) labels.Labels { |
|
|
|
|
if len(b.del) == 0 && len(b.add) == 0 { |
|
|
|
|
if b.err == "" { |
|
|
|
|
return b.base |
|
|
|
|
if buf == nil { |
|
|
|
|
buf = make(labels.Labels, 0, len(b.base)+1) |
|
|
|
|
} else { |
|
|
|
|
buf = buf[:0] |
|
|
|
|
} |
|
|
|
|
res := append(b.base.Copy(), labels.Label{Name: logqlmodel.ErrorLabel, Value: b.err}) |
|
|
|
|
sort.Sort(res) |
|
|
|
|
return res |
|
|
|
|
buf = append(buf, b.base...) |
|
|
|
|
if b.err != "" { |
|
|
|
|
buf = append(buf, labels.Label{Name: logqlmodel.ErrorLabel, Value: b.err}) |
|
|
|
|
} |
|
|
|
|
return buf |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// In the general case, labels are removed, modified or moved
|
|
|
|
|
// rather than added.
|
|
|
|
|
res := make(labels.Labels, 0, len(b.base)) |
|
|
|
|
if buf == nil { |
|
|
|
|
buf = make(labels.Labels, 0, len(b.base)+len(b.add)+1) |
|
|
|
|
} else { |
|
|
|
|
buf = buf[:0] |
|
|
|
|
} |
|
|
|
|
Outer: |
|
|
|
|
for _, l := range b.base { |
|
|
|
|
for _, n := range b.del { |
|
|
|
@ -235,14 +251,30 @@ Outer: |
|
|
|
|
continue Outer |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
res = append(res, l) |
|
|
|
|
buf = append(buf, l) |
|
|
|
|
} |
|
|
|
|
res = append(res, b.add...) |
|
|
|
|
buf = append(buf, b.add...) |
|
|
|
|
if b.err != "" { |
|
|
|
|
res = append(res, labels.Label{Name: logqlmodel.ErrorLabel, Value: b.err}) |
|
|
|
|
buf = append(buf, labels.Label{Name: logqlmodel.ErrorLabel, Value: b.err}) |
|
|
|
|
} |
|
|
|
|
sort.Sort(res) |
|
|
|
|
|
|
|
|
|
return buf |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (b *LabelsBuilder) Map() map[string]string { |
|
|
|
|
if len(b.del) == 0 && len(b.add) == 0 && b.err == "" { |
|
|
|
|
if b.baseMap == nil { |
|
|
|
|
b.baseMap = b.base.Map() |
|
|
|
|
} |
|
|
|
|
return b.baseMap |
|
|
|
|
} |
|
|
|
|
b.buf = b.unsortedLabels(b.buf) |
|
|
|
|
// todo should we also cache maps since limited by the result ?
|
|
|
|
|
// Maps also don't create a copy of the labels.
|
|
|
|
|
res := make(map[string]string, len(b.buf)) |
|
|
|
|
for _, l := range b.buf { |
|
|
|
|
res[l.Name] = l.Value |
|
|
|
|
} |
|
|
|
|
return res |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -253,15 +285,15 @@ func (b *LabelsBuilder) LabelsResult() LabelsResult { |
|
|
|
|
if len(b.del) == 0 && len(b.add) == 0 && b.err == "" { |
|
|
|
|
return b.currentResult |
|
|
|
|
} |
|
|
|
|
return b.toResult(b.Labels()) |
|
|
|
|
return b.toResult(b.labels()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (b *BaseLabelsBuilder) toResult(lbs labels.Labels) LabelsResult { |
|
|
|
|
hash := b.hasher.Hash(lbs) |
|
|
|
|
func (b *BaseLabelsBuilder) toResult(buf labels.Labels) LabelsResult { |
|
|
|
|
hash := b.hasher.Hash(buf) |
|
|
|
|
if cached, ok := b.resultCache[hash]; ok { |
|
|
|
|
return cached |
|
|
|
|
} |
|
|
|
|
res := NewLabelsResult(lbs, hash) |
|
|
|
|
res := NewLabelsResult(buf.Copy(), hash) |
|
|
|
|
b.resultCache[hash] = res |
|
|
|
|
return res |
|
|
|
|
} |
|
|
|
@ -295,7 +327,11 @@ func (b *LabelsBuilder) GroupedLabels() LabelsResult { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (b *LabelsBuilder) withResult() LabelsResult { |
|
|
|
|
res := make(labels.Labels, 0, len(b.groups)) |
|
|
|
|
if b.buf == nil { |
|
|
|
|
b.buf = make(labels.Labels, 0, len(b.groups)) |
|
|
|
|
} else { |
|
|
|
|
b.buf = b.buf[:0] |
|
|
|
|
} |
|
|
|
|
Outer: |
|
|
|
|
for _, g := range b.groups { |
|
|
|
|
for _, n := range b.del { |
|
|
|
@ -305,26 +341,30 @@ Outer: |
|
|
|
|
} |
|
|
|
|
for _, la := range b.add { |
|
|
|
|
if g == la.Name { |
|
|
|
|
res = append(res, la) |
|
|
|
|
b.buf = append(b.buf, la) |
|
|
|
|
continue Outer |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for _, l := range b.base { |
|
|
|
|
if g == l.Name { |
|
|
|
|
res = append(res, l) |
|
|
|
|
b.buf = append(b.buf, l) |
|
|
|
|
continue Outer |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return b.toResult(res) |
|
|
|
|
return b.toResult(b.buf) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (b *LabelsBuilder) withoutResult() LabelsResult { |
|
|
|
|
size := len(b.base) + len(b.add) - len(b.del) - len(b.groups) |
|
|
|
|
if size < 0 { |
|
|
|
|
size = 0 |
|
|
|
|
if b.buf == nil { |
|
|
|
|
size := len(b.base) + len(b.add) - len(b.del) - len(b.groups) |
|
|
|
|
if size < 0 { |
|
|
|
|
size = 0 |
|
|
|
|
} |
|
|
|
|
b.buf = make(labels.Labels, 0, size) |
|
|
|
|
} else { |
|
|
|
|
b.buf = b.buf[:0] |
|
|
|
|
} |
|
|
|
|
res := make(labels.Labels, 0, size) |
|
|
|
|
Outer: |
|
|
|
|
for _, l := range b.base { |
|
|
|
|
for _, n := range b.del { |
|
|
|
@ -342,7 +382,7 @@ Outer: |
|
|
|
|
continue Outer |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
res = append(res, l) |
|
|
|
|
b.buf = append(b.buf, l) |
|
|
|
|
} |
|
|
|
|
OuterAdd: |
|
|
|
|
for _, la := range b.add { |
|
|
|
@ -351,10 +391,10 @@ OuterAdd: |
|
|
|
|
continue OuterAdd |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
res = append(res, la) |
|
|
|
|
b.buf = append(b.buf, la) |
|
|
|
|
} |
|
|
|
|
sort.Sort(res) |
|
|
|
|
return b.toResult(res) |
|
|
|
|
sort.Sort(b.buf) |
|
|
|
|
return b.toResult(b.buf) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (b *LabelsBuilder) toBaseGroup() LabelsResult { |
|
|
|
|