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/start.go b/vendor/github.com/armon/go-metrics/start.go
old mode 100755
new mode 100644
index 44113f1..32a28c4
--- a/vendor/github.com/armon/go-metrics/start.go
+++ b/vendor/github.com/armon/go-metrics/start.go
@@ -2,34 +2,50 @@
 
 import (
 	"os"
+	"sync"
+	"sync/atomic"
 	"time"
+
+	"github.com/hashicorp/go-immutable-radix"
 )
 
 // Config is used to configure metrics settings
 type Config struct {
-	ServiceName          string        // Prefixed with keys to seperate services
+	ServiceName          string        // Prefixed with keys to separate services
 	HostName             string        // Hostname to use. If not provided and EnableHostname, it will be os.Hostname
 	EnableHostname       bool          // Enable prefixing gauge values with hostname
+	EnableHostnameLabel  bool          // Enable adding hostname to labels
+	EnableServiceLabel   bool          // Enable adding service to labels
 	EnableRuntimeMetrics bool          // Enables profiling of runtime metrics (GC, Goroutines, Memory)
 	EnableTypePrefix     bool          // Prefixes key with a type ("counter", "gauge", "timer")
 	TimerGranularity     time.Duration // Granularity of timers.
 	ProfileInterval      time.Duration // Interval to profile runtime metrics
+
+	AllowedPrefixes []string // A list of metric prefixes to allow, with '.' as the separator
+	BlockedPrefixes []string // A list of metric prefixes to block, with '.' as the separator
+	AllowedLabels   []string // A list of metric labels to allow, with '.' as the separator
+	BlockedLabels   []string // A list of metric labels to block, with '.' as the separator
+	FilterDefault   bool     // Whether to allow metrics by default
 }
 
 // Metrics represents an instance of a metrics sink that can
 // be used to emit
 type Metrics struct {
 	Config
-	lastNumGC uint32
-	sink      MetricSink
+	lastNumGC     uint32
+	sink          MetricSink
+	filter        *iradix.Tree
+	allowedLabels map[string]bool
+	blockedLabels map[string]bool
+	filterLock    sync.RWMutex // Lock filters and allowedLabels/blockedLabels access
 }
 
 // Shared global metrics instance
-var globalMetrics *Metrics
+var globalMetrics atomic.Value // *Metrics
 
 func init() {
 	// Initialize to a blackhole sink to avoid errors
-	globalMetrics = &Metrics{sink: &BlackholeSink{}}
+	globalMetrics.Store(&Metrics{sink: &BlackholeSink{}})
 }
 
 // DefaultConfig provides a sane default configuration
@@ -42,6 +58,7 @@
 		EnableTypePrefix:     false,            // Disable type prefix
 		TimerGranularity:     time.Millisecond, // Timers are in milliseconds
 		ProfileInterval:      time.Second,      // Poll runtime every second
+		FilterDefault:        true,             // Don't filter metrics by default
 	}
 
 	// Try to get the hostname
@@ -55,6 +72,7 @@
 	met := &Metrics{}
 	met.Config = *conf
 	met.sink = sink
+	met.UpdateFilterAndLabels(conf.AllowedPrefixes, conf.BlockedPrefixes, conf.AllowedLabels, conf.BlockedLabels)
 
 	// Start the runtime collector
 	if conf.EnableRuntimeMetrics {
@@ -68,28 +86,56 @@
 func NewGlobal(conf *Config, sink MetricSink) (*Metrics, error) {
 	metrics, err := New(conf, sink)
 	if err == nil {
-		globalMetrics = metrics
+		globalMetrics.Store(metrics)
 	}
 	return metrics, err
 }
 
 // Proxy all the methods to the globalMetrics instance
 func SetGauge(key []string, val float32) {
-	globalMetrics.SetGauge(key, val)
+	globalMetrics.Load().(*Metrics).SetGauge(key, val)
+}
+
+func SetGaugeWithLabels(key []string, val float32, labels []Label) {
+	globalMetrics.Load().(*Metrics).SetGaugeWithLabels(key, val, labels)
 }
 
 func EmitKey(key []string, val float32) {
-	globalMetrics.EmitKey(key, val)
+	globalMetrics.Load().(*Metrics).EmitKey(key, val)
 }
 
 func IncrCounter(key []string, val float32) {
-	globalMetrics.IncrCounter(key, val)
+	globalMetrics.Load().(*Metrics).IncrCounter(key, val)
+}
+
+func IncrCounterWithLabels(key []string, val float32, labels []Label) {
+	globalMetrics.Load().(*Metrics).IncrCounterWithLabels(key, val, labels)
 }
 
 func AddSample(key []string, val float32) {
-	globalMetrics.AddSample(key, val)
+	globalMetrics.Load().(*Metrics).AddSample(key, val)
+}
+
+func AddSampleWithLabels(key []string, val float32, labels []Label) {
+	globalMetrics.Load().(*Metrics).AddSampleWithLabels(key, val, labels)
 }
 
 func MeasureSince(key []string, start time.Time) {
-	globalMetrics.MeasureSince(key, start)
+	globalMetrics.Load().(*Metrics).MeasureSince(key, start)
+}
+
+func MeasureSinceWithLabels(key []string, start time.Time, labels []Label) {
+	globalMetrics.Load().(*Metrics).MeasureSinceWithLabels(key, start, labels)
+}
+
+func UpdateFilter(allow, block []string) {
+	globalMetrics.Load().(*Metrics).UpdateFilter(allow, block)
+}
+
+// UpdateFilterAndLabels set allow/block prefixes of metrics while allowedLabels
+// and blockedLabels - when not nil - allow filtering of labels in order to
+// block/allow globally labels (especially useful when having large number of
+// values for a given label). See README.md for more information about usage.
+func UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels []string) {
+	globalMetrics.Load().(*Metrics).UpdateFilterAndLabels(allow, block, allowedLabels, blockedLabels)
 }