diff --git a/storage/memory/memory.go b/storage/memory/memory.go index d2a6c276..758ebf08 100644 --- a/storage/memory/memory.go +++ b/storage/memory/memory.go @@ -15,7 +15,6 @@ package memory import ( - "container/list" "fmt" "sync" @@ -27,7 +26,7 @@ import ( // containerStorage is used to store per-container information type containerStorage struct { ref info.ContainerReference - recentStats *list.List + recentStats *StatsBuffer maxNumStats int lock sync.RWMutex } @@ -37,46 +36,32 @@ func (self *containerStorage) AddStats(stats *info.ContainerStats) error { defer self.lock.Unlock() // Add the stat to storage. - if self.recentStats.Len() >= self.maxNumStats { - self.recentStats.Remove(self.recentStats.Back()) - } - self.recentStats.PushFront(stats) + self.recentStats.Add(stats) return nil } func (self *containerStorage) RecentStats(numStats int) ([]*info.ContainerStats, error) { self.lock.RLock() defer self.lock.RUnlock() - if self.recentStats.Len() < numStats || numStats < 0 { - numStats = self.recentStats.Len() + if self.recentStats.Size() < numStats || numStats < 0 { + numStats = self.recentStats.Size() } // Stats in the recentStats list are stored in reverse chronological // order, i.e. most recent stats is in the front. - // numStats will always <= recentStats.Len() so that there will be + // numStats will always <= recentStats.Size() so that there will be // always at least numStats available stats to retrieve. We traverse - // the recentStats list from its head and fill the ret slice in - // reverse order so that the returned slice will be in chronological + // the recentStats list from its head so that the returned slice will be in chronological // order. The order of the returned slice is not specified by the // StorageDriver interface, so it is not necessary for other storage // drivers to return the slice in the same order. - ret := make([]*info.ContainerStats, numStats) - e := self.recentStats.Front() - for i := numStats - 1; i >= 0; i-- { - data, ok := e.Value.(*info.ContainerStats) - if !ok { - return nil, fmt.Errorf("The %vth element is not a ContainerStats", i) - } - ret[i] = data - e = e.Next() - } - return ret, nil + return self.recentStats.FirstN(numStats), nil } func newContainerStore(ref info.ContainerReference, maxNumStats int) *containerStorage { return &containerStorage{ ref: ref, - recentStats: list.New(), + recentStats: NewStatsBuffer(maxNumStats), maxNumStats: maxNumStats, } } diff --git a/storage/memory/stats_buffer.go b/storage/memory/stats_buffer.go index a10ea188..324da00b 100644 --- a/storage/memory/stats_buffer.go +++ b/storage/memory/stats_buffer.go @@ -30,7 +30,7 @@ func (self *StatsBuffer) Add(item *info.ContainerStats) { } // 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 { +func (self *StatsBuffer) FirstN(n int) []*info.ContainerStats { // Cap n at the number of elements we have. if n > self.size { n = self.size @@ -43,10 +43,10 @@ func (self *StatsBuffer) FirstN(n int) []info.ContainerStats { } // Copy the elements. - res := make([]info.ContainerStats, n) + res := make([]*info.ContainerStats, n) for i := 0; i < n; i++ { index := (start + i) % len(self.buffer) - res[i] = self.buffer[index] + res[i] = &self.buffer[index] } return res } diff --git a/storage/memory/stats_buffer_test.go b/storage/memory/stats_buffer_test.go index 780b15ba..fd1b8e9d 100644 --- a/storage/memory/stats_buffer_test.go +++ b/storage/memory/stats_buffer_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/google/cadvisor/info" + ) func createStats(id int32) *info.ContainerStats {