Add a StatsBuffer circular buffer for ContainerStats.
This commit is contained in:
parent
c356d3b7c1
commit
023520da9b
56
storage/memory/stats_buffer.go
Normal file
56
storage/memory/stats_buffer.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package memory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/cadvisor/info"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A circular buffer for ContainerStats.
|
||||||
|
type StatsBuffer struct {
|
||||||
|
buffer []info.ContainerStats
|
||||||
|
size int
|
||||||
|
index int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a new thread-compatible StatsBuffer.
|
||||||
|
func NewStatsBuffer(size int) *StatsBuffer {
|
||||||
|
return &StatsBuffer{
|
||||||
|
buffer: make([]info.ContainerStats, size),
|
||||||
|
size: 0,
|
||||||
|
index: size - 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds an element to the start of the buffer (removing one from the end if necessary).
|
||||||
|
func (self *StatsBuffer) Add(item *info.ContainerStats) {
|
||||||
|
if self.size < len(self.buffer) {
|
||||||
|
self.size++
|
||||||
|
}
|
||||||
|
self.index = (self.index + 1) % len(self.buffer)
|
||||||
|
self.buffer[self.index] = *item
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the first N elements in the buffer. If N > size of buffer, size of buffer elements are returned.
|
||||||
|
func (self *StatsBuffer) FirstN(n int) []info.ContainerStats {
|
||||||
|
// Cap n at the number of elements we have.
|
||||||
|
if n > self.size {
|
||||||
|
n = self.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// index points to the latest element, get n before that one (keeping in mind we may have gone through 0).
|
||||||
|
start := self.index - (n - 1)
|
||||||
|
if start < 0 {
|
||||||
|
start += len(self.buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the elements.
|
||||||
|
res := make([]info.ContainerStats, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
index := (start + i) % len(self.buffer)
|
||||||
|
res[i] = self.buffer[index]
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StatsBuffer) Size() int {
|
||||||
|
return self.size
|
||||||
|
}
|
63
storage/memory/stats_buffer_test.go
Normal file
63
storage/memory/stats_buffer_test.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package memory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/cadvisor/info"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createStats(id int32) *info.ContainerStats {
|
||||||
|
return &info.ContainerStats{
|
||||||
|
Cpu: info.CpuStats{
|
||||||
|
Load: id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func expectSize(t *testing.T, sb *StatsBuffer, expectedSize int) {
|
||||||
|
if sb.Size() != expectedSize {
|
||||||
|
t.Errorf("Expected size %v, got %v", expectedSize, sb.Size())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func expectElements(t *testing.T, sb *StatsBuffer, expected []int32) {
|
||||||
|
res := sb.FirstN(sb.Size())
|
||||||
|
if len(res) != len(expected) {
|
||||||
|
t.Errorf("Expected elements %v, got %v", expected, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i, el := range res {
|
||||||
|
if el.Cpu.Load != expected[i] {
|
||||||
|
t.Errorf("Expected elements %v, got %v", expected, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddAndFirstN(t *testing.T) {
|
||||||
|
sb := NewStatsBuffer(5)
|
||||||
|
|
||||||
|
// Add 1.
|
||||||
|
sb.Add(createStats(1))
|
||||||
|
expectSize(t, sb, 1)
|
||||||
|
expectElements(t, sb, []int32{1})
|
||||||
|
|
||||||
|
// Fill the buffer.
|
||||||
|
for i := 1; i <= 5; i++ {
|
||||||
|
expectSize(t, sb, i)
|
||||||
|
sb.Add(createStats(int32(i)))
|
||||||
|
}
|
||||||
|
expectSize(t, sb, 5)
|
||||||
|
expectElements(t, sb, []int32{1, 2, 3, 4, 5})
|
||||||
|
|
||||||
|
// Add more than is available in the buffer
|
||||||
|
sb.Add(createStats(6))
|
||||||
|
expectSize(t, sb, 5)
|
||||||
|
expectElements(t, sb, []int32{2, 3, 4, 5, 6})
|
||||||
|
|
||||||
|
// Replace all elements.
|
||||||
|
for i := 7; i <= 10; i++ {
|
||||||
|
sb.Add(createStats(int32(i)))
|
||||||
|
}
|
||||||
|
expectSize(t, sb, 5)
|
||||||
|
expectElements(t, sb, []int32{6, 7, 8, 9, 10})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user