Ver Fonte

Update map pools to use a uint64 key instead of float64 to take full advantage of the runtime.mapclear replacement. Update KeyTuple to use substrings of the key versus a split based allocation.

Matt Bolt há 6 anos atrás
pai
commit
e525394e68
3 ficheiros alterados com 67 adições e 41 exclusões
  1. 44 20
      pkg/costmodel/costmodel.go
  2. 18 16
      pkg/util/pool.go
  3. 5 5
      pkg/util/vector.go

+ 44 - 20
pkg/costmodel/costmodel.go

@@ -1489,9 +1489,9 @@ func getPodDeploymentsWithMetrics(deploymentLabels map[string]map[string]string,
 			continue
 		}
 
-		namespace := kt.Namespace
-		name := kt.Key
-		clusterID := kt.ClusterID
+		namespace := kt.Namespace()
+		name := kt.Key()
+		clusterID := kt.ClusterID()
 
 		key := namespace + "," + clusterID
 		if _, ok := podDeploymentsMapping[key]; !ok {
@@ -1503,9 +1503,9 @@ func getPodDeploymentsWithMetrics(deploymentLabels map[string]map[string]string,
 			if err != nil {
 				continue
 			}
-			podNamespace := pkey.Namespace
-			podName := pkey.Key
-			podClusterID := pkey.ClusterID
+			podNamespace := pkey.Namespace()
+			podName := pkey.Key()
+			podClusterID := pkey.ClusterID()
 
 			labelSet := labels.Set(pLabels)
 			if s.Matches(labelSet) && podNamespace == namespace && podClusterID == clusterID {
@@ -1534,9 +1534,9 @@ func getPodServicesWithMetrics(serviceLabels map[string]map[string]string, podLa
 			continue
 		}
 
-		namespace := kt.Namespace
-		name := kt.Key
-		clusterID := kt.ClusterID
+		namespace := kt.Namespace()
+		name := kt.Key()
+		clusterID := kt.ClusterID()
 
 		key := namespace + "," + clusterID
 		if _, ok := podServicesMapping[key]; !ok {
@@ -1552,9 +1552,9 @@ func getPodServicesWithMetrics(serviceLabels map[string]map[string]string, podLa
 			if err != nil {
 				continue
 			}
-			podNamespace := pkey.Namespace
-			podName := pkey.Key
-			podClusterID := pkey.ClusterID
+			podNamespace := pkey.Namespace()
+			podName := pkey.Key()
+			podClusterID := pkey.ClusterID()
 
 			labelSet := labels.Set(pLabels)
 			if s.Matches(labelSet) && podNamespace == namespace && podClusterID == clusterID {
@@ -2817,20 +2817,44 @@ func newContainerMetricFromPrometheus(metrics map[string]interface{}, defaultClu
 }
 
 type KeyTuple struct {
-	Namespace string
-	Key       string
-	ClusterID string
+	key    string
+	kIndex int
+	cIndex int
+}
+
+func (kt *KeyTuple) Namespace() string {
+	return kt.key[0 : kt.kIndex-1]
+}
+
+func (kt *KeyTuple) Key() string {
+	return kt.key[kt.kIndex : kt.cIndex-1]
+}
+
+func (kt *KeyTuple) ClusterID() string {
+	return kt.key[kt.cIndex:]
 }
 
 func NewKeyTuple(key string) (*KeyTuple, error) {
-	r := strings.Split(key, ",")
-	if len(r) != 3 {
+	kIndex := strings.IndexRune(key, ',')
+	if kIndex < 0 {
 		return nil, fmt.Errorf("NewKeyTuple() Provided key not containing exactly 3 components.")
 	}
+	kIndex += 1
+
+	subIndex := strings.IndexRune(key[kIndex:], ',')
+	if subIndex < 0 {
+		return nil, fmt.Errorf("NewKeyTuple() Provided key not containing exactly 3 components.")
+	}
+	cIndex := kIndex + subIndex + 1
+
+	if strings.ContainsRune(key[cIndex:], ',') {
+		return nil, fmt.Errorf("NewKeyTuple() Provided key not containing exactly 3 components.")
+	}
+
 	return &KeyTuple{
-		Namespace: r[0],
-		Key:       r[1],
-		ClusterID: r[2],
+		key:    key,
+		kIndex: kIndex,
+		cIndex: cIndex,
 	}, nil
 }
 

+ 18 - 16
pkg/util/pool.go

@@ -7,8 +7,8 @@ import (
 // A pool of vector maps for mapping float64 timestamps
 // to float64 values
 type VectorMapPool interface {
-	Get() map[float64]float64
-	Put(map[float64]float64)
+	Get() map[uint64]float64
+	Put(map[uint64]float64)
 }
 
 // ------------
@@ -19,17 +19,17 @@ type VectorMapPool interface {
 // maps will block until one is available. You will be unable to
 // Put() a map if the buffer is full.
 type FixedMapPool struct {
-	maps chan map[float64]float64
+	maps chan map[uint64]float64
 	size int
 }
 
 // Returns a map from the pool. Blocks if no maps are available for re-use
-func (mp *FixedMapPool) Get() map[float64]float64 {
+func (mp *FixedMapPool) Get() map[uint64]float64 {
 	return <-mp.maps
 }
 
 // Adds a map back to the pool if there is room. Does not block on overflow.
-func (mp *FixedMapPool) Put(m map[float64]float64) {
+func (mp *FixedMapPool) Put(m map[uint64]float64) {
 	if len(mp.maps) >= mp.size {
 		return
 	}
@@ -44,13 +44,13 @@ func (mp *FixedMapPool) Put(m map[float64]float64) {
 // Creates a new fixed map pool which maintains a fixed pool size
 func NewFixedMapPool(size int) VectorMapPool {
 	mp := &FixedMapPool{
-		maps: make(chan map[float64]float64, size),
+		maps: make(chan map[uint64]float64, size),
 		size: size,
 	}
 
 	// Pre-Populate the buffer with maps
 	for i := 0; i < size; i++ {
-		mp.maps <- make(map[float64]float64)
+		mp.maps <- make(map[uint64]float64)
 	}
 
 	return mp
@@ -64,21 +64,21 @@ func NewFixedMapPool(size int) VectorMapPool {
 // not block if maps are over requested, but will only maintain
 // a buffer up the size limitation.
 type FlexibleMapPool struct {
-	maps chan map[float64]float64
+	maps chan map[uint64]float64
 }
 
 // Returns a map from the pool. Does not block on over-request.
-func (mp *FlexibleMapPool) Get() map[float64]float64 {
+func (mp *FlexibleMapPool) Get() map[uint64]float64 {
 	select {
 	case m := <-mp.maps:
 		return m
 	default:
-		return make(map[float64]float64)
+		return make(map[uint64]float64)
 	}
 }
 
 // Adds a map back to the pool if there is room. Does not block on overflow.
-func (mp *FlexibleMapPool) Put(m map[float64]float64) {
+func (mp *FlexibleMapPool) Put(m map[uint64]float64) {
 	for k := range m {
 		delete(m, k)
 	}
@@ -86,14 +86,16 @@ func (mp *FlexibleMapPool) Put(m map[float64]float64) {
 	// Either return the map to the buffered channel, or do nothing
 	select {
 	case mp.maps <- m:
+		return
 	default:
+		return
 	}
 }
 
 // Creates a new fixed map pool which maintains a fixed pool size
 func NewFlexibleMapPool(size int) VectorMapPool {
 	return &FlexibleMapPool{
-		maps: make(chan map[float64]float64, size),
+		maps: make(chan map[uint64]float64, size),
 	}
 }
 
@@ -105,12 +107,12 @@ type UnboundedMapPool struct {
 }
 
 // Returns a map from the pool. Does not block on over-request.
-func (mp *UnboundedMapPool) Get() map[float64]float64 {
-	return mp.maps.Get().(map[float64]float64)
+func (mp *UnboundedMapPool) Get() map[uint64]float64 {
+	return mp.maps.Get().(map[uint64]float64)
 }
 
 // Adds a map back to the pool if there is room. Does not block on overflow.
-func (mp *UnboundedMapPool) Put(m map[float64]float64) {
+func (mp *UnboundedMapPool) Put(m map[uint64]float64) {
 	for k := range m {
 		delete(m, k)
 	}
@@ -124,7 +126,7 @@ func NewUnboundedMapPool() VectorMapPool {
 	return &UnboundedMapPool{
 		maps: &sync.Pool{
 			New: func() interface{} {
-				return make(map[float64]float64)
+				return make(map[uint64]float64)
 			},
 		},
 	}

+ 5 - 5
pkg/util/vector.go

@@ -68,7 +68,7 @@ func ApplyVectorOp(xvs []*Vector, yvs []*Vector, op VectorJoinOp) []*Vector {
 		// round all non-zero timestamps to the nearest 10 second mark
 		xv.Timestamp = roundTimestamp(xv.Timestamp, 10.0)
 
-		xMap[xv.Timestamp] = xv.Value
+		xMap[uint64(xv.Timestamp)] = xv.Value
 		timestamps = append(timestamps, &Vector{
 			Timestamp: xv.Timestamp,
 		})
@@ -85,8 +85,8 @@ func ApplyVectorOp(xvs []*Vector, yvs []*Vector, op VectorJoinOp) []*Vector {
 		// round all non-zero timestamps to the nearest 10 second mark
 		yv.Timestamp = roundTimestamp(yv.Timestamp, 10.0)
 
-		yMap[yv.Timestamp] = yv.Value
-		if _, ok := xMap[yv.Timestamp]; !ok {
+		yMap[uint64(yv.Timestamp)] = yv.Value
+		if _, ok := xMap[uint64(yv.Timestamp)]; !ok {
 			// no need to double add, since we'll range over sorted timestamps and check.
 			timestamps = append(timestamps, &Vector{
 				Timestamp: yv.Timestamp,
@@ -98,8 +98,8 @@ func ApplyVectorOp(xvs []*Vector, yvs []*Vector, op VectorJoinOp) []*Vector {
 	// reuse the existing slice to reduce allocations
 	result := timestamps[:0]
 	for _, sv := range timestamps {
-		x, okX := xMap[sv.Timestamp]
-		y, okY := yMap[sv.Timestamp]
+		x, okX := xMap[uint64(sv.Timestamp)]
+		y, okY := yMap[uint64(sv.Timestamp)]
 
 		if op(sv, VectorValue(x, okX), VectorValue(y, okY)) {
 			result = append(result, sv)