VOL-1497 : Add more control to kv/memory access

- Added kv locking mechanism (etcd only)
- (watch) control path access whenever possible
- (watch) use a transaction for updates and merge with memory
- cleaned up vendoring
- misc changes to fix exceptions found along the way

Amendments:

- Copyright header got removed in auto-generated file
- Changed default locking to false for KV list operation
- Updated backend api to allow the passing of locking parameter

Change-Id: Ie1a55d3ca8b9d92ae71a85ce42bb22fcf1419e2c
diff --git a/vendor/github.com/armon/go-metrics/statsd.go b/vendor/github.com/armon/go-metrics/statsd.go
index 65a5021..1bfffce 100644
--- a/vendor/github.com/armon/go-metrics/statsd.go
+++ b/vendor/github.com/armon/go-metrics/statsd.go
@@ -5,6 +5,7 @@
 	"fmt"
 	"log"
 	"net"
+	"net/url"
 	"strings"
 	"time"
 )
@@ -23,6 +24,12 @@
 	metricQueue chan string
 }
 
+// NewStatsdSinkFromURL creates an StatsdSink from a URL. It is used
+// (and tested) from NewMetricSinkFromURL.
+func NewStatsdSinkFromURL(u *url.URL) (MetricSink, error) {
+	return NewStatsdSink(u.Host)
+}
+
 // NewStatsdSink is used to create a new StatsdSink
 func NewStatsdSink(addr string) (*StatsdSink, error) {
 	s := &StatsdSink{
@@ -43,6 +50,11 @@
 	s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
 }
 
+func (s *StatsdSink) SetGaugeWithLabels(key []string, val float32, labels []Label) {
+	flatKey := s.flattenKeyLabels(key, labels)
+	s.pushMetric(fmt.Sprintf("%s:%f|g\n", flatKey, val))
+}
+
 func (s *StatsdSink) EmitKey(key []string, val float32) {
 	flatKey := s.flattenKey(key)
 	s.pushMetric(fmt.Sprintf("%s:%f|kv\n", flatKey, val))
@@ -53,11 +65,21 @@
 	s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
 }
 
+func (s *StatsdSink) IncrCounterWithLabels(key []string, val float32, labels []Label) {
+	flatKey := s.flattenKeyLabels(key, labels)
+	s.pushMetric(fmt.Sprintf("%s:%f|c\n", flatKey, val))
+}
+
 func (s *StatsdSink) AddSample(key []string, val float32) {
 	flatKey := s.flattenKey(key)
 	s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
 }
 
+func (s *StatsdSink) AddSampleWithLabels(key []string, val float32, labels []Label) {
+	flatKey := s.flattenKeyLabels(key, labels)
+	s.pushMetric(fmt.Sprintf("%s:%f|ms\n", flatKey, val))
+}
+
 // Flattens the key for formatting, removes spaces
 func (s *StatsdSink) flattenKey(parts []string) string {
 	joined := strings.Join(parts, ".")
@@ -73,6 +95,14 @@
 	}, joined)
 }
 
+// Flattens the key along with labels for formatting, removes spaces
+func (s *StatsdSink) flattenKeyLabels(parts []string, labels []Label) string {
+	for _, label := range labels {
+		parts = append(parts, label.Value)
+	}
+	return s.flattenKey(parts)
+}
+
 // Does a non-blocking push to the metrics queue
 func (s *StatsdSink) pushMetric(m string) {
 	select {