influxdb/engine/series_heap.go

106 lines
2.7 KiB
Go
Raw Normal View History

2014-08-29 22:17:07 +00:00
package engine
import (
2014-10-10 06:54:01 +00:00
"container/heap"
2014-08-29 22:17:07 +00:00
"github.com/influxdb/influxdb/protocol"
)
type Value struct {
streamId int
s *protocol.Series
}
2014-10-10 06:54:01 +00:00
type MinValueSlice struct {
values []Value
}
func (mvs *MinValueSlice) Len() int {
return len(mvs.values)
}
func (mvs *MinValueSlice) Less(i, j int) bool {
return mvs.values[i].s.Points[0].GetTimestamp() < mvs.values[j].s.Points[0].GetTimestamp()
}
func (mvs *MinValueSlice) Swap(i, j int) {
mvs.values[i], mvs.values[j] = mvs.values[j], mvs.values[i]
}
func (mvs *MinValueSlice) Push(x interface{}) {
mvs.values = append(mvs.values, x.(Value))
}
2014-08-29 22:17:07 +00:00
2014-10-10 06:54:01 +00:00
func (mvs *MinValueSlice) Pop() interface{} {
l := len(mvs.values)
var v interface{}
v, mvs.values = mvs.values[l-1], mvs.values[:l-1]
return v
2014-08-29 22:17:07 +00:00
}
2014-10-10 06:54:01 +00:00
type MaxValueSlice struct {
*MinValueSlice
2014-08-29 22:17:07 +00:00
}
2014-10-10 06:54:01 +00:00
func (mvs MaxValueSlice) Less(i, j int) bool {
return mvs.values[i].s.Points[0].GetTimestamp() >
mvs.values[j].s.Points[0].GetTimestamp()
2014-08-29 22:17:07 +00:00
}
2014-10-10 06:54:01 +00:00
// A heap that holds one point series' (series that have one
2014-08-29 22:17:07 +00:00
// point only) and their stream ids. See http://en.wikipedia.org/wiki/Heap_(data_structure)
// for more info on heaps. The heap is used by the Merger to emit
// points from multiple streams in monotic order.
type SeriesHeap struct {
Ascending bool
2014-10-10 06:54:01 +00:00
values *MinValueSlice
}
func NewSeriesHeap(asc bool) SeriesHeap {
return SeriesHeap{
Ascending: asc,
values: &MinValueSlice{},
}
2014-08-29 22:17:07 +00:00
}
// returns the number of values in the heap so far
2014-10-10 06:54:01 +00:00
func (sh SeriesHeap) Size() int {
return sh.values.Len()
2014-08-29 22:17:07 +00:00
}
// Add another one point series with the given stream id. TODO: This
// is slightly inefficient way to construct the initial value slice,
// if we had a value slice we can construct the heap in O(n) instead
// of O(n logn) which is required if we construct the heap using
// multiple calls to Add()
2014-10-10 06:54:01 +00:00
func (sh SeriesHeap) Add(streamId int, s *protocol.Series) {
var vs heap.Interface
2014-08-29 22:17:07 +00:00
if sh.Ascending {
2014-10-10 06:54:01 +00:00
vs = sh.values
2014-08-29 22:17:07 +00:00
} else {
2014-10-10 06:54:01 +00:00
vs = MaxValueSlice{sh.values}
2014-08-29 22:17:07 +00:00
}
2014-10-10 06:54:01 +00:00
heap.Push(vs, Value{
s: s,
streamId: streamId,
})
2014-08-29 22:17:07 +00:00
}
// Get and remove the next one point series that has smallest (or
// largest) timestmap, according to the Ascending field. TODO: This is
// slightly inefficient since we remove a value from the values slice
// and do a BubbleDown which is inefficient since the next value from
// the stream will be added immediately after and will cause a
// BubbleUp. In big O() notation this step doesn't change much, it
// only adds a contant to the upper bound.
2014-10-10 06:54:01 +00:00
func (sh SeriesHeap) Next() (int, *protocol.Series) {
var vs heap.Interface
2014-08-29 22:17:07 +00:00
if sh.Ascending {
2014-10-10 06:54:01 +00:00
vs = sh.values
2014-08-29 22:17:07 +00:00
} else {
2014-10-10 06:54:01 +00:00
vs = MaxValueSlice{sh.values}
2014-08-29 22:17:07 +00:00
}
2014-10-10 06:54:01 +00:00
v := heap.Remove(vs, 0).(Value)
2014-08-29 22:17:07 +00:00
return v.streamId, v.s
}