mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
// Copyright 2024 The etcd Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package chart
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"go.etcd.io/etcd/tools/rw-heatmaps/v3/pkg/dataset"
|
|
)
|
|
|
|
// heatMapGrid holds X, Y, Z values for a heatmap.
|
|
type heatMapGrid struct {
|
|
x, y []float64
|
|
z [][]float64 // The Z values should be arranged in a 2D slice.
|
|
}
|
|
|
|
// newHeatMapGrid returns a new heatMapGrid.
|
|
func newHeatMapGrid(plotType string, records []dataset.DataRecord) *heatMapGrid {
|
|
x, y := populateGridAxes(records)
|
|
|
|
// Create a 2D slice to hold the Z values.
|
|
z := make([][]float64, len(y))
|
|
for i := range z {
|
|
z[i] = make([]float64, len(x))
|
|
for j := range z[i] {
|
|
recordIndex := i*len(x) + j
|
|
// If the recordIndex is out of range (incomplete data), break the loop.
|
|
if recordIndex >= len(records) {
|
|
break
|
|
}
|
|
record := records[recordIndex]
|
|
if plotType == "read" {
|
|
z[i][j] = record.AvgRead
|
|
} else {
|
|
z[i][j] = record.AvgWrite
|
|
}
|
|
}
|
|
}
|
|
|
|
return &heatMapGrid{x, y, z}
|
|
}
|
|
|
|
// newDeltaHeatMapGrid returns a new heatMapGrid for the delta heatmap.
|
|
func newDeltaHeatMapGrid(plotType string, records [][]dataset.DataRecord) *heatMapGrid {
|
|
delta := make([]dataset.DataRecord, len(records[0]))
|
|
for i := range records[0] {
|
|
delta[i] = dataset.DataRecord{
|
|
ConnSize: records[0][i].ConnSize,
|
|
ValueSize: records[0][i].ValueSize,
|
|
AvgRead: ((records[1][i].AvgRead - records[0][i].AvgRead) / records[0][i].AvgRead) * 100,
|
|
AvgWrite: ((records[1][i].AvgWrite - records[0][i].AvgWrite) / records[0][i].AvgWrite) * 100,
|
|
}
|
|
}
|
|
|
|
return newHeatMapGrid(plotType, delta)
|
|
}
|
|
|
|
// Dims returns the number of elements in the grid.
|
|
// It implements the plotter.GridXYZ interface.
|
|
func (h *heatMapGrid) Dims() (int, int) {
|
|
return len(h.x), len(h.y)
|
|
}
|
|
|
|
// Z returns the value of a grid cell at (c, r).
|
|
// It implements the plotter.GridXYZ interface.
|
|
func (h *heatMapGrid) Z(c, r int) float64 {
|
|
return h.z[r][c]
|
|
}
|
|
|
|
// X returns the coordinate for the column at index c.
|
|
// It implements the plotter.GridXYZ interface.
|
|
func (h *heatMapGrid) X(c int) float64 {
|
|
if c >= len(h.x) {
|
|
panic("index out of range")
|
|
}
|
|
return h.x[c]
|
|
}
|
|
|
|
// Y returns the coordinate for the row at index r.
|
|
// It implements the plotter.GridXYZ interface.
|
|
func (h *heatMapGrid) Y(r int) float64 {
|
|
if r >= len(h.y) {
|
|
panic("index out of range")
|
|
}
|
|
return h.y[r]
|
|
}
|
|
|
|
// populateGridAxes populates the X and Y axes for the heatmap grid.
|
|
func populateGridAxes(records []dataset.DataRecord) ([]float64, []float64) {
|
|
var xslice, yslice []float64
|
|
|
|
for _, record := range records {
|
|
xslice = append(xslice, float64(record.ConnSize))
|
|
yslice = append(yslice, float64(record.ValueSize))
|
|
}
|
|
|
|
// Sort and deduplicate the slices
|
|
xUnique := uniqueSortedFloats(xslice)
|
|
yUnique := uniqueSortedFloats(yslice)
|
|
|
|
return xUnique, yUnique
|
|
}
|
|
|
|
// uniqueSortedFloats returns a sorted slice of unique float64 values.
|
|
func uniqueSortedFloats(input []float64) []float64 {
|
|
unique := make([]float64, 0)
|
|
seen := make(map[float64]bool)
|
|
|
|
for _, value := range input {
|
|
if !seen[value] {
|
|
seen[value] = true
|
|
unique = append(unique, value)
|
|
}
|
|
}
|
|
|
|
sort.Float64s(unique)
|
|
return unique
|
|
}
|