Example #1
0
// Interpolate takes a counter value sampled at variable intervals and aligns each value with a <duration> ms boundary.
// The initial value is not output unless it appears exactly on a ms boundary.
// Runs of two or more missing values will be filled by NaN
func Interpolate(duration uint64, input *oproto.ValueStream) *oproto.ValueStream {
	output := &oproto.ValueStream{}
	var previousValue *oproto.Value
	var timestamp uint64
	for _, v := range input.Value {
		if previousValue == nil {
			if v.Timestamp%duration == 0 {
				// Value is exactly on a timestamp
				output.Value = append(output.Value, v)
				previousValue = v
				timestamp = v.Timestamp + duration
			} else {
				previousValue = v
				previousValue.Timestamp = v.Timestamp / duration * duration
				timestamp = previousValue.Timestamp + duration
			}
			continue
		}
		if v.Timestamp >= timestamp {
			// Fill in any missing values before this one
			rate := float64((v.DoubleValue - previousValue.DoubleValue))
			for ; timestamp <= v.Timestamp; timestamp += duration {
				pct := float64(timestamp-previousValue.Timestamp) / float64(v.Timestamp-previousValue.Timestamp)
				newValue := previousValue.DoubleValue + (rate * pct)
				output.Value = append(output.Value, &oproto.Value{
					Timestamp:   timestamp,
					DoubleValue: newValue,
				})
			}
			if previousValue.Timestamp < v.Timestamp {
				if v.Timestamp%duration == 0 {
					// Value is exactly on a timestamp
					output.Value = append(output.Value, v)
					previousValue = v
					timestamp += duration
				} else {
					previousValue = v
				}
			}
		}
	}
	return output
}
Example #2
0
func Encode(input *oproto.ValueStream) *oproto.ValueStream {
	output := &oproto.ValueStream{Variable: input.Variable}
	var last *oproto.Value
	for _, value := range input.Value {
		if last == nil {
			last = value
			continue
		}

		if last.StringValue != "" && value.StringValue != "" {
			if last.StringValue == value.StringValue {
				if value.EndTimestamp > value.Timestamp {
					last.EndTimestamp = value.EndTimestamp
				} else {
					last.EndTimestamp = value.Timestamp
				}
				continue
			}
		} else {
			if last.DoubleValue == value.DoubleValue {
				if value.EndTimestamp > value.Timestamp {
					last.EndTimestamp = value.EndTimestamp
				} else {
					last.EndTimestamp = value.Timestamp
				}
				continue
			}
		}

		if last.EndTimestamp == 0 && last.Timestamp != 0 {
			last.EndTimestamp = last.Timestamp
		}
		output.Value = append(output.Value, last)
		last = value
	}

	if last != nil {
		if last.EndTimestamp == 0 && last.Timestamp != 0 {
			last.EndTimestamp = last.Timestamp
		}
		output.Value = append(output.Value, last)
	}
	return output
}
Example #3
0
func findFirstMatchingPolicy(value *oproto.Value, policies []*oproto.RetentionPolicyItem) *oproto.RetentionPolicyItem {
	now := openinstrument.NowMs()
	valueStartAge := now - value.Timestamp
	if value.EndTimestamp == 0 && value.Timestamp != 0 {
		value.EndTimestamp = value.Timestamp
	}
	valueEndAge := now - value.EndTimestamp
	for _, item := range policies {
		if len(item.Variable) == 0 {
			// No variables supplied, this matches everything
			return item
		}
		for _, i := range item.Variable {
			// Look for policies that match the variable age
			v := variable.NewFromProto(i)
			if v.TimestampInsideRange(valueStartAge) || v.TimestampInsideRange(valueEndAge) {
				return item
			}
		}
	}
	return nil
}