Example #1
0
func readMapItems(c *TagsCursor, field string, seek, tmin, tmax int64) []MapItem {
	var items []MapItem
	var seeked bool
	for {
		var timestamp int64
		var value interface{}
		if !seeked {
			timestamp, value = c.SeekTo(seek)
			seeked = true
		} else {
			timestamp, value = c.Next()
		}

		// We're done if the point is outside the query's time range [tmin:tmax).
		if timestamp != tmin && (timestamp < tmin || timestamp >= tmax) {
			return items
		}

		// Convert values to fields map.
		fields, ok := value.(map[string]interface{})
		if !ok {
			fields = map[string]interface{}{"": value}
		}

		// Value didn't match, look for the next one.
		if value == nil {
			continue
		}

		// Filter value.
		if c.filter != nil {
			// Convert value to a map for filter evaluation.
			m, ok := value.(map[string]interface{})
			if !ok {
				m = map[string]interface{}{field: value}
			}

			// If filter fails then skip to the next value.
			if !influxql.EvalBool(c.filter, m) {
				continue
			}
		}

		// Filter out single field, if specified.
		if m, ok := value.(map[string]interface{}); ok {
			value = m[field]
		}
		if value == nil {
			continue
		}

		items = append(items, MapItem{
			Timestamp: timestamp,
			Value:     value,
			Fields:    fields,
			Tags:      c.tags,
		})
	}
}
Example #2
0
// Next returns the next matching series-key, timestamp byte slice and meta tags for the tagset. Filtering
// is enforced on the values. If there is no matching value, then a nil result is returned.
func (tsc *TagSetCursor) Next(tmin, tmax int64) (int64, interface{}) {
	for {
		// If we're out of points, we're done.
		if tsc.heap.Len() == 0 {
			return -1, nil
		}

		// Grab the next point with the lowest timestamp.
		p := heap.Pop(tsc.heap).(*pointHeapItem)

		// We're done if the point is outside the query's time range [tmin:tmax).
		if p.timestamp != tmin && (p.timestamp < tmin || p.timestamp >= tmax) {
			return -1, nil
		}

		// Save timestamp & value.
		timestamp, value := p.timestamp, p.value

		// Keep track of all fields for series cursor so we can
		// respond with them if asked
		tsc.currentFields = value

		// Keep track of the current tags for the series cursor so we can
		// respond with them if asked
		tsc.currentTags = p.cursor.tags

		// Advance the cursor.
		if nextKey, nextVal := p.cursor.Next(); nextKey != -1 {
			*p = pointHeapItem{
				timestamp: nextKey,
				value:     nextVal,
				cursor:    p.cursor,
			}
			heap.Push(tsc.heap, p)
		}

		// Value didn't match, look for the next one.
		if value == nil {
			continue
		}

		// Filter value.
		if p.cursor.filter != nil {
			// Convert value to a map for filter evaluation.
			m, ok := value.(map[string]interface{})
			if !ok {
				m = map[string]interface{}{tsc.SelectFields[0]: value}
			}

			// If filter fails then skip to the next value.
			if !influxql.EvalBool(p.cursor.filter, m) {
				continue
			}
		}

		// Filter out single field, if specified.
		if len(tsc.SelectFields) == 1 {
			if m, ok := value.(map[string]interface{}); ok {
				value = m[tsc.SelectFields[0]]
			}
			if value == nil {
				continue
			}
		}

		return timestamp, value
	}
}
Example #3
0
func readMapInputs(cursors []*TagsCursor, fieldNames []string, seek, tmin, tmax int64) []MapInput {
	inputs := make([]MapInput, len(fieldNames))
	for i := range inputs {
		inputs[i].TMin = -1
	}

	for _, c := range cursors {
		for {
			var timestamp int64
			var value interface{}

			if !c.Seeked() {
				timestamp, value = c.SeekTo(seek)
			} else {
				timestamp, value = c.Next()
			}

			// We're done if the point is outside the query's time range [tmin:tmax).
			if timestamp != tmin && (timestamp < tmin || timestamp >= tmax) {
				c.Unread(timestamp, value)
				break
			}

			// Convert values to fields map.
			fields, ok := value.(map[string]interface{})
			if !ok {
				fields = map[string]interface{}{"": value}
			}

			// Value didn't match, look for the next one.
			if value == nil {
				continue
			}

			for i, field := range fieldNames {
				fieldValue := value

				// Filter value.
				if c.filter != nil {
					// Convert value to a map for filter evaluation.
					m, ok := fieldValue.(map[string]interface{})
					if !ok {
						m = map[string]interface{}{field: fieldValue}
					}

					// If filter fails then skip to the next value.
					if !influxql.EvalBool(c.filter, m) {
						continue
					}
				}

				// Filter out single field, if specified.
				if m, ok := fieldValue.(map[string]interface{}); ok {
					fieldValue = m[field]
				}
				if fieldValue == nil {
					continue
				}

				inputs[i].Items = append(inputs[i].Items, MapItem{
					Timestamp: timestamp,
					Value:     fieldValue,
					Fields:    fields,
					Tags:      c.tags,
				})
			}
		}
	}

	for _, input := range inputs {
		sort.Sort(MapItems(input.Items))
	}

	return inputs
}