Skip to content

Commit 0aae467

Browse files
authored
Merge pull request #1 from stone-z/curry-tests
Drop LabelValues partial match, add tests
2 parents 9a8cb32 + a3a1a58 commit 0aae467

File tree

2 files changed

+37
-105
lines changed

2 files changed

+37
-105
lines changed

prometheus/vec.go

Lines changed: 21 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,6 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
8080
return m.metricMap.deleteByHashWithLabelValues(h, lvs, m.curry)
8181
}
8282

83-
// DeletePartialMatchLabelValues deletes all metrics where the variable labels
84-
// contain all of the values passed. The order of the passed values does not matter.
85-
// It returns the number of metrics deleted.
86-
87-
// This method deletes a metric if the given value is present for any label.
88-
// To delete a metric based on a partial match for a particular label, use DeletePartialMatch().
89-
func (m *MetricVec) DeletePartialMatchLabelValues(lvs ...string) int {
90-
return m.metricMap.deleteByLabelValues(lvs)
91-
}
92-
9383
// Delete deletes the metric where the variable labels are the same as those
9484
// passed in as labels. It returns true if a metric was deleted.
9585
//
@@ -116,7 +106,7 @@ func (m *MetricVec) Delete(labels Labels) bool {
116106
// This method deletes a metric if the given label: value pair is found in that metric.
117107
// To delete a metric if a particular value is found associated with any label, use DeletePartialMatchLabelValues().
118108
func (m *MetricVec) DeletePartialMatch(labels Labels) int {
119-
return m.metricMap.deleteByLabels(labels)
109+
return m.metricMap.deleteByLabels(labels, m.curry)
120110
}
121111

122112
// Without explicit forwarding of Describe, Collect, Reset, those methods won't
@@ -373,51 +363,6 @@ func (m *metricMap) deleteByHashWithLabelValues(
373363
return true
374364
}
375365

376-
// deleteByLabelValues deletes a metric if the given values (lvs) are present in the metric.
377-
func (m *metricMap) deleteByLabelValues(lvs []string) int {
378-
m.mtx.Lock()
379-
defer m.mtx.Unlock()
380-
381-
var numDeleted int
382-
383-
for h, metrics := range m.metrics {
384-
i := findMetricWithPartialLabelValues(metrics, lvs)
385-
if i >= len(metrics) {
386-
// Didn't find matching label values in this metric slice.
387-
continue
388-
}
389-
delete(m.metrics, h)
390-
numDeleted++
391-
}
392-
393-
return numDeleted
394-
}
395-
396-
// findMetricWithPartialLabelValues returns the index of the matching metric or
397-
// len(metrics) if not found.
398-
func findMetricWithPartialLabelValues(
399-
metrics []metricWithLabelValues, lvs []string,
400-
) int {
401-
for i, metric := range metrics {
402-
if matchPartialLabelValues(metric.values, lvs) {
403-
return i
404-
}
405-
}
406-
return len(metrics)
407-
}
408-
409-
// matchPartialLabelValues searches the current metric values and returns whether all of the target values are present.
410-
func matchPartialLabelValues(values []string, lvs []string) bool {
411-
for _, v := range lvs {
412-
// Check if the target value exists in our metrics and get the index.
413-
if _, validValue := indexOf(v, values); validValue {
414-
continue
415-
}
416-
return false
417-
}
418-
return true
419-
}
420-
421366
// deleteByHashWithLabels removes the metric from the hash bucket h. If there
422367
// are multiple matches in the bucket, use lvs to select a metric and remove
423368
// only that metric.
@@ -447,14 +392,14 @@ func (m *metricMap) deleteByHashWithLabels(
447392
}
448393

449394
// deleteByLabels deletes a metric if the given labels are present in the metric.
450-
func (m *metricMap) deleteByLabels(labels Labels) int {
395+
func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int {
451396
m.mtx.Lock()
452397
defer m.mtx.Unlock()
453398

454399
var numDeleted int
455400

456401
for h, metrics := range m.metrics {
457-
i := findMetricWithPartialLabels(m.desc, metrics, labels)
402+
i := findMetricWithPartialLabels(m.desc, metrics, labels, curry)
458403
if i >= len(metrics) {
459404
// Didn't find matching labels in this metric slice.
460405
continue
@@ -469,10 +414,10 @@ func (m *metricMap) deleteByLabels(labels Labels) int {
469414
// findMetricWithPartialLabel returns the index of the matching metric or
470415
// len(metrics) if not found.
471416
func findMetricWithPartialLabels(
472-
desc *Desc, metrics []metricWithLabelValues, labels Labels,
417+
desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,
473418
) int {
474419
for i, metric := range metrics {
475-
if matchPartialLabels(desc, metric.values, labels) {
420+
if matchPartialLabels(desc, metric.values, labels, curry) {
476421
return i
477422
}
478423
}
@@ -490,13 +435,28 @@ func indexOf(target string, items []string) (int, bool) {
490435
return len(items), false
491436
}
492437

438+
// valueOrCurriedValue determines if a value was previously curried,
439+
// and returns either the "base" value or the curried value accordingly.
440+
func valueOrCurriedValue(index int, values []string, curry []curriedLabelValue) string {
441+
for _, curriedValue := range curry {
442+
if curriedValue.index == index {
443+
return curriedValue.value
444+
}
445+
}
446+
return values[index]
447+
}
448+
493449
// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present.
494-
func matchPartialLabels(desc *Desc, values []string, labels Labels) bool {
450+
func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {
495451
for l, v := range labels {
496452
// Check if the target label exists in our metrics and get the index.
497453
varLabelIndex, validLabel := indexOf(l, desc.variableLabels)
498454
if validLabel {
499455
// Check the value of that label against the target value.
456+
// if valueOrCurriedValue(varLabelIndex, values, curry) == v {
457+
// continue
458+
// }
459+
500460
if values[varLabelIndex] == v {
501461
continue
502462

prometheus/vec_test.go

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -164,71 +164,43 @@ func testDeletePartialMatch(t *testing.T, vec *GaugeVec) {
164164
// Try to delete with a single valid label which matches multiple metrics.
165165
vec.With(Labels{"l1": "v1", "l2": "v2"}).(Gauge).Set(42)
166166
vec.With(Labels{"l1": "v1", "l2": "vv22"}).(Gauge).Set(84)
167+
c3 := vec.MustCurryWith(Labels{"l2": "l2C3CurriedValue"}) // Used below
168+
vec.With(Labels{"l1": "v3", "l2": "v3"}).(Gauge).Set(168)
167169
if got, want := vec.DeletePartialMatch(Labels{"l1": "v1"}), 2; got != want {
168170
t.Errorf("got %v, want %v", got, want)
169171
}
170172

173+
// Try to delete a value which shouldn't be in our base vector (only the curried one c3).
174+
if got, want := vec.DeletePartialMatch(Labels{"l2": "l2C3CurriedValue"}), 0; got != want {
175+
t.Errorf("got %v, want %v", got, want)
176+
}
177+
171178
c2 := vec.MustCurryWith(Labels{"l2": "l2CurriedValue"})
172179
c2.With(Labels{"l1": "11"}).Inc()
173180

174181
// Delete with valid curried pair l2: l2CurriedValue.
175182
if got, want := c2.DeletePartialMatch(Labels{"l2": "l2CurriedValue"}), 1; got != want {
176183
t.Errorf("got %v, want %v", got, want)
177184
}
178-
179-
// Same labels, value matches.
180-
vec.With(Labels{"l1": "v1", "l2": "v2"}).(Gauge).Set(42)
181-
if got, want := vec.DeletePartialMatch(Labels{"l1": "v1"}), 1; got != want {
185+
// Try to delete with a label value from before currying.
186+
if got, want := c2.DeletePartialMatch(Labels{"l2": "v3"}), 0; got != want {
182187
t.Errorf("got %v, want %v", got, want)
183188
}
184-
}
185-
186-
func TestDeletePartialMatchLabelValues(t *testing.T) {
187-
vec := NewGaugeVec(
188-
GaugeOpts{
189-
Name: "test",
190-
Help: "helpless",
191-
},
192-
[]string{"l1", "l2"},
193-
)
194-
testDeletePartialMatchLabelValues(t, vec)
195-
}
196189

197-
func testDeletePartialMatchLabelValues(t *testing.T, vec *GaugeVec) {
198-
// No metric value is set.
199-
if got, want := vec.DeletePartialMatchLabelValues("v1", "v2"), 0; got != want {
200-
t.Errorf("got %v, want %v", got, want)
201-
}
190+
c3.With(Labels{"l1": "11"}).Inc()
202191

203-
// Try to delete with a single valid value.
204-
vec.With(Labels{"l1": "v1", "l2": "v2"}).(Gauge).Set(42)
205-
if got, want := vec.DeletePartialMatchLabelValues("v1"), 1; got != want {
192+
// Try to delete with invalid curried pair l1: v1.
193+
if got, want := c3.DeletePartialMatch(Labels{"l1": "v1"}), 0; got != want {
206194
t.Errorf("got %v, want %v", got, want)
207195
}
208-
209-
// Try to delete with partially invalid values.
210-
vec.With(Labels{"l1": "v1", "l2": "v2"}).(Gauge).Set(42)
211-
if got, want := vec.DeletePartialMatchLabelValues("v1", "xv2"), 0; got != want {
196+
// Delete valid curried pair l2: l2C3CurriedValue.
197+
if got, want := c3.DeletePartialMatch(Labels{"l2": "l2C3CurriedValue"}), 1; got != want {
212198
t.Errorf("got %v, want %v", got, want)
213199
}
214200

215-
// Try to delete with a single valid value which matches multiple metrics.
201+
// Same labels, value matches.
216202
vec.With(Labels{"l1": "v1", "l2": "v2"}).(Gauge).Set(42)
217-
vec.With(Labels{"l1": "v1", "l2": "vv22"}).(Gauge).Set(84)
218-
if got, want := vec.DeletePartialMatchLabelValues("v1"), 2; got != want {
219-
t.Errorf("got %v, want %v", got, want)
220-
}
221-
222-
c1 := vec.MustCurryWith(Labels{"l1": "cv1"})
223-
c1.WithLabelValues("2").Inc()
224-
225-
// Try to delete with nonexistent value z1.
226-
if got, want := c1.DeletePartialMatchLabelValues("z1"), 0; got != want {
227-
t.Errorf("got %v, want %v", got, want)
228-
}
229-
230-
// Delete with valid curried value cv1.
231-
if got, want := c1.DeletePartialMatchLabelValues("cv1"), 1; got != want {
203+
if got, want := vec.DeletePartialMatch(Labels{"l1": "v1"}), 1; got != want {
232204
t.Errorf("got %v, want %v", got, want)
233205
}
234206
}

0 commit comments

Comments
 (0)