Add some docs
parent
3a857296f4
commit
edd22ce3b8
|
@ -6,20 +6,18 @@ import (
|
|||
"github.com/influxdb/influxdb/protocol"
|
||||
)
|
||||
|
||||
type JoinEngineState struct {
|
||||
lastFields []string
|
||||
lastPoint *protocol.Point
|
||||
}
|
||||
|
||||
// TODO: Explain how JoinEngine work
|
||||
type JoinEngine struct {
|
||||
query *parser.SelectQuery
|
||||
next Processor
|
||||
name string // the output table name
|
||||
tableIdx map[string]int
|
||||
tableState []JoinEngineState
|
||||
tablesState []joinEngineState
|
||||
pts int
|
||||
}
|
||||
|
||||
// Create and return a new JoinEngine given the shards that will be
|
||||
// processed and the query
|
||||
func NewJoinEngine(shards []uint32, query *parser.SelectQuery, next Processor) Processor {
|
||||
tableNames := query.GetFromClause().Names
|
||||
name := query.GetFromClause().GetString()
|
||||
|
@ -29,7 +27,7 @@ func NewJoinEngine(shards []uint32, query *parser.SelectQuery, next Processor) P
|
|||
joinEngine := &JoinEngine{
|
||||
next: next,
|
||||
name: name,
|
||||
tableState: make([]JoinEngineState, len(tableNames)),
|
||||
tablesState: make([]joinEngineState, len(tableNames)),
|
||||
tableIdx: make(map[string]int, len(tableNames)),
|
||||
query: query,
|
||||
pts: 0,
|
||||
|
@ -37,7 +35,7 @@ func NewJoinEngine(shards []uint32, query *parser.SelectQuery, next Processor) P
|
|||
|
||||
for i, tn := range tableNames {
|
||||
alias := tn.GetAlias()
|
||||
joinEngine.tableState[i] = JoinEngineState{}
|
||||
joinEngine.tablesState[i] = joinEngineState{}
|
||||
joinEngine.tableIdx[alias] = i
|
||||
}
|
||||
|
||||
|
@ -56,11 +54,16 @@ func (je *JoinEngine) Close() error {
|
|||
func (je *JoinEngine) Yield(s *protocol.Series) (bool, error) {
|
||||
log4go.Fine("JoinEngine.Yield(): %s", s)
|
||||
idx := je.tableIdx[s.GetName()]
|
||||
state := &je.tableState[idx]
|
||||
state := &je.tablesState[idx]
|
||||
// If the state for this table didn't contain a point already,
|
||||
// increment the number of tables ready to emit a point by
|
||||
// incrementing `pts`
|
||||
if state.lastPoint == nil {
|
||||
je.pts++
|
||||
}
|
||||
state.lastPoint = s.Points[len(s.Points)-1]
|
||||
// update the fields for this table. the fields shouldn't change
|
||||
// after the first point, so we only need to set them once
|
||||
if state.lastFields == nil {
|
||||
for _, f := range s.Fields {
|
||||
state.lastFields = append(state.lastFields, s.GetName()+"."+f)
|
||||
|
@ -68,11 +71,16 @@ func (je *JoinEngine) Yield(s *protocol.Series) (bool, error) {
|
|||
}
|
||||
|
||||
log4go.Fine("JoinEngine: pts = %d", je.pts)
|
||||
if je.pts != len(je.tableState) {
|
||||
// if the number of tables ready to emit a point isn't equal to the
|
||||
// total number of tables being joined, then return
|
||||
if je.pts != len(je.tablesState) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
ts := je.tableState[0].lastPoint.Timestamp
|
||||
// we arbitrarily use the timestamp of the first table's point as
|
||||
// the timestamp of the resulting point. may be we should use the
|
||||
// smalles (or largest) timestamp.
|
||||
ts := je.tablesState[0].lastPoint.Timestamp
|
||||
newSeries := &protocol.Series{
|
||||
Name: &je.name,
|
||||
Fields: je.fields(),
|
||||
|
@ -84,7 +92,9 @@ func (je *JoinEngine) Yield(s *protocol.Series) (bool, error) {
|
|||
},
|
||||
}
|
||||
|
||||
// reset the number of points available for
|
||||
// filter the point. the user may have a where clause with the join,
|
||||
// e.g. `select * from join(foo1, foo2) where foo1.val > 10`. we
|
||||
// can't evaluate the where clause until after join happens
|
||||
filteredSeries, err := Filter(je.query, newSeries)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -96,25 +106,36 @@ func (je *JoinEngine) Yield(s *protocol.Series) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
func (self *JoinEngine) Next() Processor {
|
||||
return self.next
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
type joinEngineState struct {
|
||||
lastFields []string
|
||||
lastPoint *protocol.Point
|
||||
}
|
||||
|
||||
// Returns the field names from all tables appended together
|
||||
func (je *JoinEngine) fields() []string {
|
||||
fs := []string{}
|
||||
for _, s := range je.tableState {
|
||||
for _, s := range je.tablesState {
|
||||
fs = append(fs, s.lastFields...)
|
||||
}
|
||||
return fs
|
||||
}
|
||||
|
||||
// Returns the field values from all tables appended together
|
||||
func (je *JoinEngine) values() []*protocol.FieldValue {
|
||||
vs := make([]*protocol.FieldValue, 0)
|
||||
for i := range je.tableState {
|
||||
s := &je.tableState[i]
|
||||
for i := range je.tablesState {
|
||||
// Take the address of the slice element, since we set lastPoint
|
||||
// to nil
|
||||
s := &je.tablesState[i]
|
||||
vs = append(vs, s.lastPoint.Values...)
|
||||
s.lastPoint = nil
|
||||
}
|
||||
je.pts = 0
|
||||
return vs
|
||||
}
|
||||
|
||||
func (self *JoinEngine) Next() Processor {
|
||||
return self.next
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue