|
@@ -58,7 +58,6 @@ type Allocation struct {
|
|
|
CPUCoreHours float64 `json:"cpuCoreHours"`
|
|
CPUCoreHours float64 `json:"cpuCoreHours"`
|
|
|
CPUCoreRequestAverage float64 `json:"cpuCoreRequestAverage"`
|
|
CPUCoreRequestAverage float64 `json:"cpuCoreRequestAverage"`
|
|
|
CPUCoreUsageAverage float64 `json:"cpuCoreUsageAverage"`
|
|
CPUCoreUsageAverage float64 `json:"cpuCoreUsageAverage"`
|
|
|
- CPUCoreUsageMax float64 `json:"cpuCoreUsageMax"`
|
|
|
|
|
CPUCost float64 `json:"cpuCost"`
|
|
CPUCost float64 `json:"cpuCost"`
|
|
|
GPUHours float64 `json:"gpuHours"`
|
|
GPUHours float64 `json:"gpuHours"`
|
|
|
GPUCost float64 `json:"gpuCost"`
|
|
GPUCost float64 `json:"gpuCost"`
|
|
@@ -69,10 +68,41 @@ type Allocation struct {
|
|
|
RAMByteHours float64 `json:"ramByteHours"`
|
|
RAMByteHours float64 `json:"ramByteHours"`
|
|
|
RAMBytesRequestAverage float64 `json:"ramByteRequestAverage"`
|
|
RAMBytesRequestAverage float64 `json:"ramByteRequestAverage"`
|
|
|
RAMBytesUsageAverage float64 `json:"ramByteUsageAverage"`
|
|
RAMBytesUsageAverage float64 `json:"ramByteUsageAverage"`
|
|
|
- RAMBytesUsageMax float64 `json:"ramByteUsageMax"`
|
|
|
|
|
RAMCost float64 `json:"ramCost"`
|
|
RAMCost float64 `json:"ramCost"`
|
|
|
SharedCost float64 `json:"sharedCost"`
|
|
SharedCost float64 `json:"sharedCost"`
|
|
|
ExternalCost float64 `json:"externalCost"`
|
|
ExternalCost float64 `json:"externalCost"`
|
|
|
|
|
+
|
|
|
|
|
+ // RawAllocationOnly is a pointer so if it is not present it will be
|
|
|
|
|
+ // marshalled as null rather than as an object with Go default values.
|
|
|
|
|
+ RawAllocationOnly *RawAllocationOnlyData `json:"rawAllocationOnly"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// RawAllocationOnlyData is information that only belong in "raw" Allocations,
|
|
|
|
|
+// those which have not undergone aggregation, accumulation, or any other form
|
|
|
|
|
+// of combination to produce a new Allocation from other Allocations.
|
|
|
|
|
+//
|
|
|
|
|
+// Max usage data belongs here because computing the overall maximum from two
|
|
|
|
|
+// or more Allocations is a non-trivial operation that cannot be defined without
|
|
|
|
|
+// maintaining a large amount of state. Consider the following example:
|
|
|
|
|
+// _______________________________________________
|
|
|
|
|
+//
|
|
|
|
|
+// A1 Using 3 CPU ---- ----- ------
|
|
|
|
|
+// A2 Using 2 CPU ---- ----- ----
|
|
|
|
|
+// A3 Using 1 CPU --- --
|
|
|
|
|
+// _______________________________________________
|
|
|
|
|
+// Time ---->
|
|
|
|
|
+//
|
|
|
|
|
+// The logical maximum CPU usage is 5, but this cannot be calculated iteratively,
|
|
|
|
|
+// which is how we calculate aggregations and accumulations of Allocations currently.
|
|
|
|
|
+// This becomes a problem I could call "maximum sum of overlapping intervals" and is
|
|
|
|
|
+// essentially a variant of an interval scheduling algorithm.
|
|
|
|
|
+//
|
|
|
|
|
+// If we had types to differentiate between regular Allocations and AggregatedAllocations
|
|
|
|
|
+// then this type would be unnecessary and its fields would go into the regular Allocation
|
|
|
|
|
+// and not in the AggregatedAllocation.
|
|
|
|
|
+type RawAllocationOnlyData struct {
|
|
|
|
|
+ CPUCoreUsageMax float64 `json:"cpuCoreUsageMax"`
|
|
|
|
|
+ RAMBytesUsageMax float64 `json:"ramByteUsageMax"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// AllocationMatchFunc is a function that can be used to match Allocations by
|
|
// AllocationMatchFunc is a function that can be used to match Allocations by
|
|
@@ -113,7 +143,6 @@ func (a *Allocation) Clone() *Allocation {
|
|
|
CPUCoreHours: a.CPUCoreHours,
|
|
CPUCoreHours: a.CPUCoreHours,
|
|
|
CPUCoreRequestAverage: a.CPUCoreRequestAverage,
|
|
CPUCoreRequestAverage: a.CPUCoreRequestAverage,
|
|
|
CPUCoreUsageAverage: a.CPUCoreUsageAverage,
|
|
CPUCoreUsageAverage: a.CPUCoreUsageAverage,
|
|
|
- CPUCoreUsageMax: a.CPUCoreUsageMax,
|
|
|
|
|
CPUCost: a.CPUCost,
|
|
CPUCost: a.CPUCost,
|
|
|
GPUHours: a.GPUHours,
|
|
GPUHours: a.GPUHours,
|
|
|
GPUCost: a.GPUCost,
|
|
GPUCost: a.GPUCost,
|
|
@@ -124,10 +153,22 @@ func (a *Allocation) Clone() *Allocation {
|
|
|
RAMByteHours: a.RAMByteHours,
|
|
RAMByteHours: a.RAMByteHours,
|
|
|
RAMBytesRequestAverage: a.RAMBytesRequestAverage,
|
|
RAMBytesRequestAverage: a.RAMBytesRequestAverage,
|
|
|
RAMBytesUsageAverage: a.RAMBytesUsageAverage,
|
|
RAMBytesUsageAverage: a.RAMBytesUsageAverage,
|
|
|
- RAMBytesUsageMax: a.RAMBytesUsageMax,
|
|
|
|
|
RAMCost: a.RAMCost,
|
|
RAMCost: a.RAMCost,
|
|
|
SharedCost: a.SharedCost,
|
|
SharedCost: a.SharedCost,
|
|
|
ExternalCost: a.ExternalCost,
|
|
ExternalCost: a.ExternalCost,
|
|
|
|
|
+ RawAllocationOnly: a.RawAllocationOnly.Clone(),
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Clone returns a deep copy of the given RawAllocationOnlyData
|
|
|
|
|
+func (r *RawAllocationOnlyData) Clone() *RawAllocationOnlyData {
|
|
|
|
|
+ if r == nil {
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return &RawAllocationOnlyData{
|
|
|
|
|
+ CPUCoreUsageMax: r.CPUCoreUsageMax,
|
|
|
|
|
+ RAMBytesUsageMax: r.RAMBytesUsageMax,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -191,13 +232,23 @@ func (a *Allocation) Equal(that *Allocation) bool {
|
|
|
if !util.IsApproximately(a.ExternalCost, that.ExternalCost) {
|
|
if !util.IsApproximately(a.ExternalCost, that.ExternalCost) {
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
- if !util.IsApproximately(a.CPUCoreUsageMax, that.CPUCoreUsageMax) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if a.RawAllocationOnly == nil && that.RawAllocationOnly != nil {
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
- if !util.IsApproximately(a.RAMBytesUsageMax, that.RAMBytesUsageMax) {
|
|
|
|
|
|
|
+ if a.RawAllocationOnly != nil && that.RawAllocationOnly == nil {
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if a.RawAllocationOnly != nil && that.RawAllocationOnly != nil {
|
|
|
|
|
+ if !util.IsApproximately(a.RawAllocationOnly.CPUCoreUsageMax, that.RawAllocationOnly.CPUCoreUsageMax) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ if !util.IsApproximately(a.RawAllocationOnly.RAMBytesUsageMax, that.RawAllocationOnly.RAMBytesUsageMax) {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -284,7 +335,6 @@ func (a *Allocation) MarshalJSON() ([]byte, error) {
|
|
|
jsonEncodeFloat64(buffer, "cpuCores", a.CPUCores(), ",")
|
|
jsonEncodeFloat64(buffer, "cpuCores", a.CPUCores(), ",")
|
|
|
jsonEncodeFloat64(buffer, "cpuCoreRequestAverage", a.CPUCoreRequestAverage, ",")
|
|
jsonEncodeFloat64(buffer, "cpuCoreRequestAverage", a.CPUCoreRequestAverage, ",")
|
|
|
jsonEncodeFloat64(buffer, "cpuCoreUsageAverage", a.CPUCoreUsageAverage, ",")
|
|
jsonEncodeFloat64(buffer, "cpuCoreUsageAverage", a.CPUCoreUsageAverage, ",")
|
|
|
- jsonEncodeFloat64(buffer, "cpuCoreUsageMax", a.CPUCoreUsageMax, ",")
|
|
|
|
|
jsonEncodeFloat64(buffer, "cpuCoreHours", a.CPUCoreHours, ",")
|
|
jsonEncodeFloat64(buffer, "cpuCoreHours", a.CPUCoreHours, ",")
|
|
|
jsonEncodeFloat64(buffer, "cpuCost", a.CPUCost, ",")
|
|
jsonEncodeFloat64(buffer, "cpuCost", a.CPUCost, ",")
|
|
|
jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency(), ",")
|
|
jsonEncodeFloat64(buffer, "cpuEfficiency", a.CPUEfficiency(), ",")
|
|
@@ -299,13 +349,13 @@ func (a *Allocation) MarshalJSON() ([]byte, error) {
|
|
|
jsonEncodeFloat64(buffer, "ramByteRequestAverage", a.RAMBytesRequestAverage, ",")
|
|
jsonEncodeFloat64(buffer, "ramByteRequestAverage", a.RAMBytesRequestAverage, ",")
|
|
|
jsonEncodeFloat64(buffer, "ramByteUsageAverage", a.RAMBytesUsageAverage, ",")
|
|
jsonEncodeFloat64(buffer, "ramByteUsageAverage", a.RAMBytesUsageAverage, ",")
|
|
|
jsonEncodeFloat64(buffer, "ramByteHours", a.RAMByteHours, ",")
|
|
jsonEncodeFloat64(buffer, "ramByteHours", a.RAMByteHours, ",")
|
|
|
- jsonEncodeFloat64(buffer, "ramByteUsageMax", a.RAMBytesUsageMax, ",")
|
|
|
|
|
jsonEncodeFloat64(buffer, "ramCost", a.RAMCost, ",")
|
|
jsonEncodeFloat64(buffer, "ramCost", a.RAMCost, ",")
|
|
|
jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency(), ",")
|
|
jsonEncodeFloat64(buffer, "ramEfficiency", a.RAMEfficiency(), ",")
|
|
|
jsonEncodeFloat64(buffer, "sharedCost", a.SharedCost, ",")
|
|
jsonEncodeFloat64(buffer, "sharedCost", a.SharedCost, ",")
|
|
|
jsonEncodeFloat64(buffer, "externalCost", a.ExternalCost, ",")
|
|
jsonEncodeFloat64(buffer, "externalCost", a.ExternalCost, ",")
|
|
|
jsonEncodeFloat64(buffer, "totalCost", a.TotalCost(), ",")
|
|
jsonEncodeFloat64(buffer, "totalCost", a.TotalCost(), ",")
|
|
|
- jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency(), "")
|
|
|
|
|
|
|
+ jsonEncodeFloat64(buffer, "totalEfficiency", a.TotalEfficiency(), ",")
|
|
|
|
|
+ jsonEncode(buffer, "rawAllocationOnly", a.RawAllocationOnly, "")
|
|
|
buffer.WriteString("}")
|
|
buffer.WriteString("}")
|
|
|
return buffer.Bytes(), nil
|
|
return buffer.Bytes(), nil
|
|
|
}
|
|
}
|
|
@@ -447,6 +497,10 @@ func (a *Allocation) add(that *Allocation) {
|
|
|
a.LoadBalancerCost += that.LoadBalancerCost
|
|
a.LoadBalancerCost += that.LoadBalancerCost
|
|
|
a.SharedCost += that.SharedCost
|
|
a.SharedCost += that.SharedCost
|
|
|
a.ExternalCost += that.ExternalCost
|
|
a.ExternalCost += that.ExternalCost
|
|
|
|
|
+
|
|
|
|
|
+ // Any data that is in a "raw allocation only" is not valid in any
|
|
|
|
|
+ // sort of cumulative Allocation (like one that is added).
|
|
|
|
|
+ a.RawAllocationOnly = nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// AllocationSet stores a set of Allocations, each with a unique name, that share
|
|
// AllocationSet stores a set of Allocations, each with a unique name, that share
|