diff --git a/meter/meter.go b/meter/meter.go index d296db34..a88ed74c 100644 --- a/meter/meter.go +++ b/meter/meter.go @@ -3,6 +3,7 @@ package meter import ( "io" + "reflect" "sort" "time" ) @@ -76,66 +77,36 @@ type Summary interface { UpdateDuration(time.Time) } -// Labels holds the metrics labels with k, v -type Labels struct { - keys []string - vals []string +type byKey []string + +func (k byKey) Len() int { return len(k) / 2 } +func (k byKey) Less(i, j int) bool { return k[i*2] < k[j*2] } +func (k byKey) Swap(i, j int) { + k[i*2], k[i*2+1], k[j*2], k[j*2+1] = k[j*2], k[j*2+1], k[i*2], k[i*2+1] } -// Append adds labels to label set -func (ls Labels) Append(nls Labels) Labels { - for n := range nls.keys { - ls.keys = append(ls.keys, nls.keys[n]) - ls.vals = append(ls.vals, nls.vals[n]) +func Sort(slice *[]string) { + bk := byKey(*slice) + if bk.Len() <= 1 { + return } - return ls -} - -// Len returns number of labels -func (ls Labels) Len() int { - return len(ls.keys) -} - -type labels Labels - -func (ls labels) Len() int { - return len(ls.keys) -} - -func (ls labels) Sort() { - sort.Sort(ls) -} - -func (ls labels) Swap(i, j int) { - ls.keys[i], ls.keys[j] = ls.keys[j], ls.keys[i] - ls.vals[i], ls.vals[j] = ls.vals[j], ls.vals[i] -} - -func (ls labels) Less(i, j int) bool { - return ls.keys[i] < ls.keys[j] -} - -// LabelIter holds the -type LabelIter struct { - labels Labels - cnt int - cur int -} - -// Iter returns labels iterator -func (ls Labels) Iter() *LabelIter { - labels(ls).Sort() - return &LabelIter{labels: ls, cnt: len(ls.keys)} -} - -// Next advance itarator to new pos -func (iter *LabelIter) Next(k, v *string) bool { - if iter.cur+1 > iter.cnt { - return false + sort.Sort(bk) + v := reflect.ValueOf(slice).Elem() + cnt := 0 + key := 0 + val := 1 + for key < v.Len() { + if len(bk) > key+2 && bk[key] == bk[key+2] { + key += 2 + val += 2 + continue + } + v.Index(cnt).Set(v.Index(key)) + cnt++ + v.Index(cnt).Set(v.Index(val)) + cnt++ + key += 2 + val += 2 } - - *k = iter.labels.keys[iter.cur] - *v = iter.labels.vals[iter.cur] - iter.cur++ - return true + v.SetLen(cnt) } diff --git a/meter/meter_test.go b/meter/meter_test.go index 4c6cc583..7217d5d2 100644 --- a/meter/meter_test.go +++ b/meter/meter_test.go @@ -10,46 +10,15 @@ func TestNoopMeter(t *testing.T) { t.Fatalf("invalid options parsing: %v", m.Options()) } - cnt := m.Counter("counter", Label("server", "noop")) + cnt := m.Counter("counter", Labels("server", "noop")) cnt.Inc() } -func TestLabelsAppend(t *testing.T) { - var ls Labels - ls.keys = []string{"type", "server"} - ls.vals = []string{"noop", "http"} +func TestLabelsSort(t *testing.T) { + ls := []string{"server", "http", "register", "mdns", "broker", "broker1", "broker", "broker2", "server", "tcp"} + Sort(&ls) - var nls Labels - nls.keys = []string{"register"} - nls.vals = []string{"gossip"} - ls = ls.Append(nls) - - //ls.Sort() - - if ls.keys[0] != "type" || ls.vals[0] != "noop" { - t.Fatalf("append error: %v", ls) - } -} - -func TestIterator(t *testing.T) { - options := NewOptions( - Label("name", "svc1"), - Label("version", "0.0.1"), - Label("id", "12345"), - Label("type", "noop"), - Label("server", "http"), - Label("register", "gossip"), - Label("aa", "kk"), - Label("zz", "kk"), - ) - - iter := options.Labels.Iter() - var k, v string - cnt := 0 - for iter.Next(&k, &v) { - if cnt == 4 && (k != "server" || v != "http") { - t.Fatalf("iter error: %s != %s || %s != %s", k, "server", v, "http") - } - cnt++ + if ls[0] != "broker" || ls[1] != "broker2" { + t.Fatalf("sort error: %v", ls) } } diff --git a/meter/noop.go b/meter/noop.go index 93d1e652..76d8e48e 100644 --- a/meter/noop.go +++ b/meter/noop.go @@ -107,7 +107,7 @@ func (r *noopMeter) String() string { } type noopCounter struct { - labels Labels + labels []string } func (r *noopCounter) Add(int) { @@ -131,7 +131,7 @@ func (r *noopCounter) Set(uint64) { } type noopFloatCounter struct { - labels Labels + labels []string } func (r *noopFloatCounter) Add(float64) { @@ -151,7 +151,7 @@ func (r *noopFloatCounter) Sub(float64) { } type noopGauge struct { - labels Labels + labels []string } func (r *noopGauge) Get() float64 { @@ -159,7 +159,7 @@ func (r *noopGauge) Get() float64 { } type noopSummary struct { - labels Labels + labels []string } func (r *noopSummary) Update(float64) { @@ -171,7 +171,7 @@ func (r *noopSummary) UpdateDuration(time.Time) { } type noopHistogram struct { - labels Labels + labels []string } func (r *noopHistogram) Reset() { diff --git a/meter/options.go b/meter/options.go index 69ec0eaa..80a11e64 100644 --- a/meter/options.go +++ b/meter/options.go @@ -26,7 +26,7 @@ type Options struct { // LabelPrefix holds the prefix for all labels LabelPrefix string // Labels holds the default labels - Labels Labels + Labels []string // WriteProcessMetrics flag to write process metrics WriteProcessMetrics bool // WriteFDMetrics flag to write fd metrics @@ -88,11 +88,9 @@ func Logger(l logger.Logger) Option { } } -// Label sets the label -func Label(key, val string) Option { +func Labels(ls ...string) Option { return func(o *Options) { - o.Labels.keys = append(o.Labels.keys, key) - o.Labels.vals = append(o.Labels.vals, val) + o.Labels = ls } }