|
|
@@ -5,18 +5,18 @@ import (
|
|
|
"time"
|
|
|
|
|
|
"github.com/kubecost/cost-model/pkg/kubecost"
|
|
|
- //"k8s.io/klog"
|
|
|
)
|
|
|
|
|
|
// IntervalPoint describes a start or end of a window of time
|
|
|
-// Currently, this used in PVC-pod relations and is used to
|
|
|
-// detect/calculate coefficients for PVCs shared between pods.
|
|
|
+// Currently, this used in PVC-pod relations to detect/calculate
|
|
|
+// coefficients for PV cost when a PVC is shared between pods.
|
|
|
type IntervalPoint struct {
|
|
|
Time time.Time
|
|
|
PointType string
|
|
|
Key podKey
|
|
|
}
|
|
|
|
|
|
+// NewIntervalPoint creates and returns a new IntervalPoint instance with given parameters.
|
|
|
func NewIntervalPoint(time time.Time, pointType string, key podKey) IntervalPoint {
|
|
|
return IntervalPoint{
|
|
|
Time: time,
|
|
|
@@ -25,6 +25,9 @@ func NewIntervalPoint(time time.Time, pointType string, key podKey) IntervalPoin
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// getIntervalPointFromWindows takes a map of podKeys to windows
|
|
|
+// and returns a sorted list of IntervalPoints representing the
|
|
|
+// starts and ends of all those windows.
|
|
|
func getIntervalPointsFromWindows(windows map[podKey]kubecost.Window) []IntervalPoint {
|
|
|
|
|
|
var intervals []IntervalPoint
|
|
|
@@ -44,6 +47,10 @@ func getIntervalPointsFromWindows(windows map[podKey]kubecost.Window) []Interval
|
|
|
|
|
|
}
|
|
|
|
|
|
+// sortIntervalPoints sorts a list of IntervalPoints from earliest
|
|
|
+// to latest IntervalPoint.Time. In the case that two IntervalPoints
|
|
|
+// have the same time, the point with Type "start" is treated as coming
|
|
|
+// before the "end".
|
|
|
func sortIntervalPoints(intervals []IntervalPoint) {
|
|
|
sort.Slice(intervals, func(i, j int) bool {
|
|
|
if intervals[i].Time.Equal(intervals[j].Time) {
|
|
|
@@ -53,24 +60,37 @@ func sortIntervalPoints(intervals []IntervalPoint) {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+// getPVCCostCoefficients gets a coefficient which represents the scale
|
|
|
+// factor that each PVC in a pvcIntervalMap and corresponding slice of
|
|
|
+// IntervalPoints intervals uses to calculate a cost for that PVC's PV.
|
|
|
func getPVCCostCoefficients(intervals []IntervalPoint, pvcIntervalMap map[podKey]kubecost.Window, pvcCostCoefficientMap map[podKey][][]float64) {
|
|
|
|
|
|
+ // pvcCostCoefficientMap is mutated in this function. The format is
|
|
|
+ // such that the individual coefficient components are preserved for
|
|
|
+ // testing purposes.
|
|
|
+
|
|
|
var activePods float64
|
|
|
|
|
|
activeKeys := make(map[podKey]struct{})
|
|
|
|
|
|
+ // For each interval i.e. for any time a pod-PVC relation ends or starts...
|
|
|
for i := 1; i < len(intervals); i++ {
|
|
|
|
|
|
point := intervals[i]
|
|
|
prevPoint := intervals[i-1]
|
|
|
|
|
|
+ // intervals will always have at least two IntervalPoints (one start/end)
|
|
|
if i == 1 {
|
|
|
activePods += 1
|
|
|
activeKeys[prevPoint.Key] = struct{}{}
|
|
|
}
|
|
|
|
|
|
+ // If the current point happens at a later time than the previous point
|
|
|
if !point.Time.Equal(prevPoint.Time) {
|
|
|
for key := range activeKeys {
|
|
|
+ // Add a two-long slice of float64 representing:
|
|
|
+ // 1. The division of cost based on how many pods were running between those points
|
|
|
+ // 2. The ratio of the time between those points to the total time that pod was running
|
|
|
pvcCostCoefficientMap[key] = append(
|
|
|
pvcCostCoefficientMap[key],
|
|
|
[]float64{1.0 / activePods, point.Time.Sub(prevPoint.Time).Minutes() / pvcIntervalMap[key].Duration().Minutes()},
|
|
|
@@ -78,11 +98,13 @@ func getPVCCostCoefficients(intervals []IntervalPoint, pvcIntervalMap map[podKey
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // If the point was a start, increment and track
|
|
|
if point.PointType == "start" {
|
|
|
activePods += 1
|
|
|
activeKeys[point.Key] = struct{}{}
|
|
|
}
|
|
|
|
|
|
+ // If the point was an end, decrement and stop tracking
|
|
|
if point.PointType == "end" {
|
|
|
activePods -= 1
|
|
|
delete(activeKeys, point.Key)
|
|
|
@@ -91,6 +113,9 @@ func getPVCCostCoefficients(intervals []IntervalPoint, pvcIntervalMap map[podKey
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// getCoefficient takes the components of a PVC-pod PV cost coefficient
|
|
|
+// determined by getPVCCostCoefficient and gets the resulting single
|
|
|
+// floating point coefficient.
|
|
|
func getCoefficient(coefficientComponents [][]float64) float64 {
|
|
|
|
|
|
coefficient := 0.0
|