From e4009234e9a25e4ebf32ed3e473a11a66aa59bc2 Mon Sep 17 00:00:00 2001
From: Daniel Nelson <daniel.nelson@influxdb.com>
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 0af445c2..2c8fdb9c 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 31f1729d..1fecf2e4 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")
-- 
GitLab