From e4009234e9a25e4ebf32ed3e473a11a66aa59bc2 Mon Sep 17 00:00:00 2001 From: Daniel Nelson Date: Thu, 12 Apr 2018 18:09:31 -0700 Subject: [PATCH] Fix HashID conflicts in pathological cases Use "\n" as delimiter as it cannot occur in the series name. --- metric/metric.go | 3 +++ metric/metric_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/metric/metric.go b/metric/metric.go index 0af445c2d..2c8fdb9c9 100644 --- a/metric/metric.go +++ b/metric/metric.go @@ -232,9 +232,12 @@ func (m *metric) IsAggregate() bool { func (m *metric) HashID() uint64 { h := fnv.New64a() h.Write([]byte(m.name)) + h.Write([]byte("\n")) for _, tag := range m.tags { h.Write([]byte(tag.Key)) + h.Write([]byte("\n")) h.Write([]byte(tag.Value)) + h.Write([]byte("\n")) } return h.Sum64() } diff --git a/metric/metric_test.go b/metric/metric_test.go index 31f1729d8..1fecf2e44 100644 --- a/metric/metric_test.go +++ b/metric/metric_test.go @@ -267,6 +267,32 @@ func TestHashID_Consistency(t *testing.T) { assert.Equal(t, m2.HashID(), m3.HashID()) } +func TestHashID_Delimiting(t *testing.T) { + m1, _ := New( + "cpu", + map[string]string{ + "a": "x", + "b": "y", + "c": "z", + }, + map[string]interface{}{ + "value": float64(1), + }, + time.Now(), + ) + m2, _ := New( + "cpu", + map[string]string{ + "a": "xbycz", + }, + map[string]interface{}{ + "value": float64(1), + }, + time.Now(), + ) + assert.NotEqual(t, m1.HashID(), m2.HashID()) +} + func TestSetName(t *testing.T) { m := baseMetric() m.SetName("foo")