Fix handling of time ranges in timed store.

The current logic assumes that entries are added to the store in
monotonically increasing order for time. This is not true when
we add creation events for existing containers.
This commit is contained in:
Rohit Jnagal 2015-05-07 16:44:22 +00:00
parent 5bd6f601a4
commit 06c9dcd3bb
2 changed files with 34 additions and 20 deletions

View File

@ -170,8 +170,8 @@ func TestGetEventsForOneEvent(t *testing.T) {
func TestGetEventsForTimePeriod(t *testing.T) {
myEventHolder, myRequest, fakeEvent, fakeEvent2 := initializeScenario(t)
myRequest.StartTime = createOldTime(t).Add(-1 * time.Second * 10)
myRequest.EndTime = createOldTime(t).Add(time.Second * 10)
myRequest.StartTime = time.Now().Add(-1 * time.Second * 10)
myRequest.EndTime = time.Now().Add(time.Second * 10)
myRequest.EventType[info.EventOom] = true
myEventHolder.AddEvent(fakeEvent)
@ -181,7 +181,7 @@ func TestGetEventsForTimePeriod(t *testing.T) {
assert.Nil(t, err)
checkNumberOfEvents(t, 1, len(receivedEvents))
ensureProperEventReturned(t, fakeEvent, receivedEvents[0])
ensureProperEventReturned(t, fakeEvent2, receivedEvents[0])
}
func TestGetEventsForNoTypeRequested(t *testing.T) {

View File

@ -19,10 +19,24 @@ import (
"time"
)
type timedStoreDataSlice []timedStoreData
func (t timedStoreDataSlice) Less(i, j int) bool {
return t[i].timestamp.Before(t[j].timestamp)
}
func (t timedStoreDataSlice) Len() int {
return len(t)
}
func (t timedStoreDataSlice) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
// A time-based buffer for ContainerStats.
// Holds information for a specific time period and/or a max number of items.
type TimedStore struct {
buffer []timedStoreData
buffer timedStoreDataSlice
age time.Duration
maxItems int
}
@ -36,7 +50,7 @@ type timedStoreData struct {
// A maxItems value of -1 means no limit.
func NewTimedStore(age time.Duration, maxItems int) *TimedStore {
return &TimedStore{
buffer: make([]timedStoreData, 0),
buffer: make(timedStoreDataSlice, 0),
age: age,
maxItems: maxItems,
}
@ -44,7 +58,21 @@ func NewTimedStore(age time.Duration, maxItems int) *TimedStore {
// Adds an element to the start of the buffer (removing one from the end if necessary).
func (self *TimedStore) Add(timestamp time.Time, item interface{}) {
// Remove any elements before the eviction time.
// Remove any elements if over our max size.
if self.maxItems >= 0 && (len(self.buffer)+1) > self.maxItems {
startIndex := len(self.buffer) + 1 - self.maxItems
self.buffer = self.buffer[startIndex:]
}
// Add the new element first and sort. We can then remove an expired element, if required.
copied := item
self.buffer = append(self.buffer, timedStoreData{
timestamp: timestamp,
data: copied,
})
sort.Sort(self.buffer)
// Remove any elements before eviction time.
// TODO(rjnagal): This is assuming that the added entry has timestamp close to now.
evictTime := timestamp.Add(-self.age)
index := sort.Search(len(self.buffer), func(index int) bool {
return self.buffer[index].timestamp.After(evictTime)
@ -53,17 +81,6 @@ func (self *TimedStore) Add(timestamp time.Time, item interface{}) {
self.buffer = self.buffer[index:]
}
// Remove any elements if over our max size.
if self.maxItems >= 0 && (len(self.buffer)+1) > self.maxItems {
startIndex := len(self.buffer) + 1 - self.maxItems
self.buffer = self.buffer[startIndex:]
}
copied := item
self.buffer = append(self.buffer, timedStoreData{
timestamp: timestamp,
data: copied,
})
}
// Returns up to maxResult elements in the specified time period (inclusive).
@ -80,9 +97,6 @@ func (self *TimedStore) InTimeRange(start, end time.Time, maxResults int) []inte
maxResults = -1
}
// NOTE: Since we store the elments in descending timestamp order "start" will
// be a higher index than "end".
var startIndex int
if start.IsZero() {
// None specified, start at the beginning.