// Next returns the next point from the iterator.
func (itr *stringIterator) Next() *influxql.StringPoint {
	for {
		seek := tsdb.EOF

		if itr.cur != nil {
			// Read from the main cursor if we have one.
			itr.point.Time, itr.point.Value = itr.cur.nextString()
			seek = itr.point.Time
		} else {
			// Otherwise find lowest aux timestamp.
			for i := range itr.aux {
				if k, _ := itr.aux[i].peek(); k != tsdb.EOF {
					if seek == tsdb.EOF || (itr.opt.Ascending && k < seek) || (!itr.opt.Ascending && k > seek) {
						seek = k
					}
				}
			}
			itr.point.Time = seek
		}

		// Exit if we have no more points or we are outside our time range.
		if itr.point.Time == tsdb.EOF {
			itr.copyStats()
			return nil
		} else if itr.opt.Ascending && itr.point.Time > itr.opt.EndTime {
			itr.copyStats()
			return nil
		} else if !itr.opt.Ascending && itr.point.Time < itr.opt.StartTime {
			itr.copyStats()
			return nil
		}

		// Read from each auxiliary cursor.
		for i := range itr.opt.Aux {
			itr.point.Aux[i] = itr.aux[i].nextAt(seek)
		}

		// Read from condition field cursors.
		for i := range itr.conds.curs {
			itr.m[itr.conds.names[i]] = itr.conds.curs[i].nextAt(seek)
		}

		// Evaluate condition, if one exists. Retry if it fails.
		if itr.opt.Condition != nil && !influxql.EvalBool(itr.opt.Condition, itr.m) {
			continue
		}

		// Track points returned.
		itr.statsBuf.PointN++

		// Copy buffer to stats periodically.
		if itr.statsBuf.PointN%statsBufferCopyIntervalN == 0 {
			itr.copyStats()
		}

		return &itr.point
	}
}
Exemple #2
0
// Next returns the next point from the iterator.
func (itr *integerIterator) Next() *influxql.IntegerPoint {
	for {
		seek := tsdb.EOF

		if itr.cur != nil {
			// Read from the main cursor if we have one.
			itr.point.Time, itr.point.Value = itr.cur.nextInteger()
			seek = itr.point.Time
		} else {
			// Otherwise find lowest aux timestamp.
			for i := range itr.aux {
				if k, _ := itr.aux[i].peek(); k != tsdb.EOF && (seek == tsdb.EOF || k < seek) {
					seek = k
				}
			}
			itr.point.Time = seek
		}

		// Exit if we have no more points or we are outside our time range.
		if itr.point.Time == tsdb.EOF {
			return nil
		} else if itr.opt.Ascending && itr.point.Time > itr.opt.EndTime {
			return nil
		} else if !itr.opt.Ascending && itr.point.Time < itr.opt.StartTime {
			return nil
		}

		// Read from each auxiliary cursor.
		for i := range itr.opt.Aux {
			itr.point.Aux[i] = itr.aux[i].nextAt(seek)
		}

		// Read from condition field cursors.
		for i := range itr.conds.curs {
			itr.m[itr.conds.names[i]] = itr.conds.curs[i].nextAt(seek)
		}

		// Evaluate condition, if one exists. Retry if it fails.
		if itr.opt.Condition != nil && !influxql.EvalBool(itr.opt.Condition, itr.m) {
			continue
		}

		return &itr.point
	}
}
Exemple #3
0
// Next returns the next point from the cursor.
func (itr *FloatCursorIterator) Next() *influxql.FloatPoint {
	for {
		// Read next key/value and emit nil if at the end.
		timestamp, value := itr.cursor.Next()
		if timestamp == EOF {
			return nil
		} else if itr.opt.Ascending && timestamp > itr.opt.EndTime {
			return nil
		} else if !itr.opt.Ascending && timestamp < itr.opt.StartTime {
			return nil
		}

		// Set timestamp on point.
		itr.point.Time = timestamp

		// Retrieve tags key/value map.
		tags := itr.tags.KeyValues()

		// If value is a map then extract all the fields.
		if m, ok := value.(map[string]interface{}); ok {
			// If filter fails then skip to the next value.
			if itr.opt.Condition != nil && !influxql.EvalBool(itr.opt.Condition, m) {
				continue
			}

			if itr.ref != nil {
				fv, ok := m[itr.ref.Val].(float64)
				if !ok {
					continue // read next point
				}
				itr.point.Value = fv
			} else {
				itr.point.Value = math.NaN()
			}

			// Read all auxilary fields.
			for i, ref := range itr.opt.Aux {
				if v, ok := m[ref.Val]; ok {
					itr.point.Aux[i] = v
				} else if s, ok := tags[ref.Val]; ok {
					itr.point.Aux[i] = s
				} else {
					itr.point.Aux[i] = nil
				}
			}

			return &itr.point
		}

		// Otherwise expect value to be of an appropriate type.
		if itr.ref != nil {
			// If filter fails then skip to the next value.
			if itr.opt.Condition != nil && !influxql.EvalBool(itr.opt.Condition, map[string]interface{}{itr.ref.Val: value}) {
				continue
			}

			fv, ok := value.(float64)
			if !ok {
				continue // read next point
			}
			itr.point.Value = fv
		} else {
			itr.point.Value = math.NaN()
		}

		// Read all auxilary fields.
		for i, ref := range itr.opt.Aux {
			if tagValue, ok := tags[ref.Val]; ok {
				itr.point.Aux[i] = tagValue
			} else {
				itr.point.Aux[i] = value
			}
		}

		return &itr.point
	}
}