Update godoc for package models

pull/7781/head
Mark Rushakoff 2016-12-30 11:56:58 -08:00
parent 88b8bd2465
commit 7b5b3189dd
5 changed files with 143 additions and 45 deletions

View File

@ -6,20 +6,22 @@ import (
) )
// ConsistencyLevel represent a required replication criteria before a write can // ConsistencyLevel represent a required replication criteria before a write can
// be returned as successful // be returned as successful.
//
// The consistency level is handled in open-source InfluxDB but only applicable to clusters.
type ConsistencyLevel int type ConsistencyLevel int
const ( const (
// ConsistencyLevelAny allows for hinted hand off, potentially no write happened yet // ConsistencyLevelAny allows for hinted handoff, potentially no write happened yet.
ConsistencyLevelAny ConsistencyLevel = iota ConsistencyLevelAny ConsistencyLevel = iota
// ConsistencyLevelOne requires at least one data node acknowledged a write // ConsistencyLevelOne requires at least one data node acknowledged a write.
ConsistencyLevelOne ConsistencyLevelOne
// ConsistencyLevelQuorum requires a quorum of data nodes to acknowledge a write // ConsistencyLevelQuorum requires a quorum of data nodes to acknowledge a write.
ConsistencyLevelQuorum ConsistencyLevelQuorum
// ConsistencyLevelAll requires all data nodes to acknowledge a write // ConsistencyLevelAll requires all data nodes to acknowledge a write.
ConsistencyLevelAll ConsistencyLevelAll
) )
@ -29,7 +31,7 @@ var (
ErrInvalidConsistencyLevel = errors.New("invalid consistency level") ErrInvalidConsistencyLevel = errors.New("invalid consistency level")
) )
// ParseConsistencyLevel converts a consistency level string to the corresponding ConsistencyLevel const // ParseConsistencyLevel converts a consistency level string to the corresponding ConsistencyLevel const.
func ParseConsistencyLevel(level string) (ConsistencyLevel, error) { func ParseConsistencyLevel(level string) (ConsistencyLevel, error) {
switch strings.ToLower(level) { switch strings.ToLower(level) {
case "any": case "any":

View File

@ -7,12 +7,15 @@ const (
) )
// InlineFNV64a is an alloc-free port of the standard library's fnv64a. // InlineFNV64a is an alloc-free port of the standard library's fnv64a.
// See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function.
type InlineFNV64a uint64 type InlineFNV64a uint64
// NewInlineFNV64a returns a new instance of InlineFNV64a.
func NewInlineFNV64a() InlineFNV64a { func NewInlineFNV64a() InlineFNV64a {
return offset64 return offset64
} }
// Write adds data to the running hash.
func (s *InlineFNV64a) Write(data []byte) (int, error) { func (s *InlineFNV64a) Write(data []byte) (int, error) {
hash := uint64(*s) hash := uint64(*s)
for _, c := range data { for _, c := range data {
@ -22,6 +25,8 @@ func (s *InlineFNV64a) Write(data []byte) (int, error) {
*s = InlineFNV64a(hash) *s = InlineFNV64a(hash)
return len(data), nil return len(data), nil
} }
// Sum64 returns the uint64 of the current resulting hash.
func (s *InlineFNV64a) Sum64() uint64 { func (s *InlineFNV64a) Sum64() uint64 {
return uint64(*s) return uint64(*s)
} }

View File

@ -1,3 +1,4 @@
// Package models implements basic objects used throughout the TICK stack.
package models // import "github.com/influxdata/influxdb/models" package models // import "github.com/influxdata/influxdb/models"
import ( import (
@ -26,53 +27,75 @@ var (
'=': []byte(`\=`), '=': []byte(`\=`),
} }
ErrPointMustHaveAField = errors.New("point without fields is unsupported") // ErrPointMustHaveAField is returned when operating on a point that does not have any fields.
ErrInvalidNumber = errors.New("invalid number") ErrPointMustHaveAField = errors.New("point without fields is unsupported")
ErrInvalidPoint = errors.New("point is invalid")
ErrMaxKeyLengthExceeded = errors.New("max key length exceeded") // ErrInvalidNumber is returned when a number is expected but not provided.
ErrInvalidNumber = errors.New("invalid number")
// ErrInvalidPoint is returned when a point cannot be parsed correctly.
ErrInvalidPoint = errors.New("point is invalid")
) )
const ( const (
// MaxKeyLength is the largest allowed size of the combined measurement and tag keys.
MaxKeyLength = 65535 MaxKeyLength = 65535
) )
// Point defines the values that will be written to the database // Point defines the values that will be written to the database.
type Point interface { type Point interface {
// Name return the measurement name for the point.
Name() string Name() string
// SetName updates the measurement name for the point.
SetName(string) SetName(string)
// Tags returns the tag set for the point.
Tags() Tags Tags() Tags
// AddTag adds or replaces a tag value for a point.
AddTag(key, value string) AddTag(key, value string)
// SetTags replaces the tags for the point.
SetTags(tags Tags) SetTags(tags Tags)
// Fields returns the fields for the point.
Fields() Fields Fields() Fields
// Time return the timestamp for the point.
Time() time.Time Time() time.Time
// SetTime updates the timestamp for the point.
SetTime(t time.Time) SetTime(t time.Time)
// UnixNano returns the timestamp of the point as nanoseconds since Unix epoch.
UnixNano() int64 UnixNano() int64
// HashID returns a non-cryptographic checksum of the point's key.
HashID() uint64 HashID() uint64
// Key returns the key (measurement joined with tags) of the point.
Key() []byte Key() []byte
Data() []byte Data() []byte
SetData(buf []byte) SetData(buf []byte)
// String returns a string representation of the point, if there is a // String returns a string representation of the point. If there is a
// timestamp associated with the point then it will be specified with the default // timestamp associated with the point then it will be specified with the default
// precision of nanoseconds // precision of nanoseconds.
String() string String() string
// Bytes returns a []byte representation of the point similar to string. // MarshalBinary returns a binary representation of the point.
MarshalBinary() ([]byte, error) MarshalBinary() ([]byte, error)
// PrecisionString returns a string representation of the point, if there // PrecisionString returns a string representation of the point. If there
// is a timestamp associated with the point then it will be specified in the // is a timestamp associated with the point then it will be specified in the
// given unit // given unit.
PrecisionString(precision string) string PrecisionString(precision string) string
// RoundedString returns a string representation of the point, if there // RoundedString returns a string representation of the point. If there
// is a timestamp associated with the point, then it will be rounded to the // is a timestamp associated with the point, then it will be rounded to the
// given duration // given duration.
RoundedString(d time.Duration) string RoundedString(d time.Duration) string
// Split will attempt to return multiple points with the same timestamp whose // Split will attempt to return multiple points with the same timestamp whose
@ -80,50 +103,82 @@ type Point interface {
// a point without a timestamp may exceed the requested size. // a point without a timestamp may exceed the requested size.
Split(size int) []Point Split(size int) []Point
// Round will round the timestamp of the point to the given duration // Round will round the timestamp of the point to the given duration.
Round(d time.Duration) Round(d time.Duration)
// StringSize returns the length of the string that would be returned by String() // StringSize returns the length of the string that would be returned by String().
StringSize() int StringSize() int
// AppendString appends the result of String() to the provided buffer and returns // AppendString appends the result of String() to the provided buffer and returns
// the result, potentially reducing string allocations // the result, potentially reducing string allocations.
AppendString(buf []byte) []byte AppendString(buf []byte) []byte
// FieldIterator retuns a FieldIterator that can be used to traverse the // FieldIterator retuns a FieldIterator that can be used to traverse the
// fields of a point without constructing the in-memory map // fields of a point without constructing the in-memory map.
FieldIterator() FieldIterator FieldIterator() FieldIterator
} }
// FieldType represents the type of a field.
type FieldType int type FieldType int
const ( const (
// Integer indicates the field's type is integer.
Integer FieldType = iota Integer FieldType = iota
// Float indicates the field's type is float.
Float Float
// Boolean indicates the field's type is boolean.
Boolean Boolean
// String indicates the field's type is string.
String String
// Empty is used to indicate that there is no field.
Empty Empty
) )
// FieldIterator provides a low-allocation interface to iterate through a point's fields.
type FieldIterator interface { type FieldIterator interface {
// Next indicates whether there any fields remaining.
Next() bool Next() bool
// FieldKey returns the key of the current field.
FieldKey() []byte FieldKey() []byte
// Type returns the FieldType of the current field.
Type() FieldType Type() FieldType
// StringValue returns the string value of the current field.
StringValue() string StringValue() string
// IntegerValue returns the integer value of the current field.
IntegerValue() int64 IntegerValue() int64
// BooleanValue returns the boolean value of the current field.
BooleanValue() bool BooleanValue() bool
// FloatValue returns the float value of the current field.
FloatValue() float64 FloatValue() float64
// Delete deletes the current field.
Delete() Delete()
// Reset resets the iterator to its initial state.
Reset() Reset()
} }
// Points represents a sortable list of points by timestamp. // Points represents a sortable list of points by timestamp.
type Points []Point type Points []Point
func (a Points) Len() int { return len(a) } // Len implements sort.Interface.
func (a Points) Len() int { return len(a) }
// Less implements sort.Interface.
func (a Points) Less(i, j int) bool { return a[i].Time().Before(a[j].Time()) } func (a Points) Less(i, j int) bool { return a[i].Time().Before(a[j].Time()) }
func (a Points) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Swap implements sort.Interface.
func (a Points) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// point is the default implementation of Point. // point is the default implementation of Point.
type point struct { type point struct {
@ -178,8 +233,7 @@ func ParsePoints(buf []byte) ([]Point, error) {
return ParsePointsWithPrecision(buf, time.Now().UTC(), "n") return ParsePointsWithPrecision(buf, time.Now().UTC(), "n")
} }
// ParsePointsString is identical to ParsePoints but accepts a string // ParsePointsString is identical to ParsePoints but accepts a string.
// buffer.
func ParsePointsString(buf string) ([]Point, error) { func ParsePointsString(buf string) ([]Point, error) {
return ParsePoints([]byte(buf)) return ParsePoints([]byte(buf))
} }
@ -312,7 +366,7 @@ func parsePoint(buf []byte, defaultTime time.Time, precision string) (Point, err
return pt, nil return pt, nil
} }
// GetPrecisionMultiplier will return a multiplier for the precision specified // GetPrecisionMultiplier will return a multiplier for the precision specified.
func GetPrecisionMultiplier(precision string) int64 { func GetPrecisionMultiplier(precision string) int64 {
d := time.Nanosecond d := time.Nanosecond
switch precision { switch precision {
@ -591,7 +645,7 @@ func less(buf []byte, indices []int, i, j int) bool {
} }
// scanFields scans buf, starting at i for the fields section of a point. It returns // scanFields scans buf, starting at i for the fields section of a point. It returns
// the ending position and the byte slice of the fields within buf // the ending position and the byte slice of the fields within buf.
func scanFields(buf []byte, i int) (int, []byte, error) { func scanFields(buf []byte, i int) (int, []byte, error) {
start := skipWhitespace(buf, i) start := skipWhitespace(buf, i)
i = start i = start
@ -904,7 +958,7 @@ func scanBoolean(buf []byte, i int) (int, []byte, error) {
} }
// skipWhitespace returns the end position within buf, starting at i after // skipWhitespace returns the end position within buf, starting at i after
// scanning over spaces in tags // scanning over spaces in tags.
func skipWhitespace(buf []byte, i int) int { func skipWhitespace(buf []byte, i int) int {
for i < len(buf) { for i < len(buf) {
if buf[i] != ' ' && buf[i] != '\t' && buf[i] != 0 { if buf[i] != ' ' && buf[i] != '\t' && buf[i] != 0 {
@ -1106,13 +1160,13 @@ func unescapeTag(in []byte) []byte {
var escapeStringFieldReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`) var escapeStringFieldReplacer = strings.NewReplacer(`"`, `\"`, `\`, `\\`)
// EscapeStringField returns a copy of in with any double quotes or // EscapeStringField returns a copy of in with any double quotes or
// backslashes with escaped values // backslashes with escaped values.
func EscapeStringField(in string) string { func EscapeStringField(in string) string {
return escapeStringFieldReplacer.Replace(in) return escapeStringFieldReplacer.Replace(in)
} }
// unescapeStringField returns a copy of in with any escaped double-quotes // unescapeStringField returns a copy of in with any escaped double-quotes
// or backslashes unescaped // or backslashes unescaped.
func unescapeStringField(in string) string { func unescapeStringField(in string) string {
if strings.IndexByte(in, '\\') == -1 { if strings.IndexByte(in, '\\') == -1 {
return in return in
@ -1159,7 +1213,7 @@ func NewPoint(name string, tags Tags, fields Fields, t time.Time) (Point, error)
} }
// pointKey checks some basic requirements for valid points, and returns the // pointKey checks some basic requirements for valid points, and returns the
// key, along with an possible error // key, along with an possible error.
func pointKey(measurement string, tags Tags, fields Fields, t time.Time) ([]byte, error) { func pointKey(measurement string, tags Tags, fields Fields, t time.Time) ([]byte, error) {
if len(fields) == 0 { if len(fields) == 0 {
return nil, ErrPointMustHaveAField return nil, ErrPointMustHaveAField
@ -1227,6 +1281,7 @@ func (p *point) SetData(b []byte) {
p.data = b p.data = b
} }
// Key returns the key (measurement joined with tags) of the point.
func (p *point) Key() []byte { func (p *point) Key() []byte {
return p.key return p.key
} }
@ -1236,7 +1291,7 @@ func (p *point) name() []byte {
return name return name
} }
// Name return the measurement name for the point // Name return the measurement name for the point.
func (p *point) Name() string { func (p *point) Name() string {
if p.cachedName != "" { if p.cachedName != "" {
return p.cachedName return p.cachedName
@ -1245,28 +1300,28 @@ func (p *point) Name() string {
return p.cachedName return p.cachedName
} }
// SetName updates the measurement name for the point // SetName updates the measurement name for the point.
func (p *point) SetName(name string) { func (p *point) SetName(name string) {
p.cachedName = "" p.cachedName = ""
p.key = MakeKey([]byte(name), p.Tags()) p.key = MakeKey([]byte(name), p.Tags())
} }
// Time return the timestamp for the point // Time return the timestamp for the point.
func (p *point) Time() time.Time { func (p *point) Time() time.Time {
return p.time return p.time
} }
// SetTime updates the timestamp for the point // SetTime updates the timestamp for the point.
func (p *point) SetTime(t time.Time) { func (p *point) SetTime(t time.Time) {
p.time = t p.time = t
} }
// Round implements Point.Round // Round will round the timestamp of the point to the given duration.
func (p *point) Round(d time.Duration) { func (p *point) Round(d time.Duration) {
p.time = p.time.Round(d) p.time = p.time.Round(d)
} }
// Tags returns the tag set for the point // Tags returns the tag set for the point.
func (p *point) Tags() Tags { func (p *point) Tags() Tags {
if p.cachedTags != nil { if p.cachedTags != nil {
return p.cachedTags return p.cachedTags
@ -1322,13 +1377,13 @@ func MakeKey(name []byte, tags Tags) []byte {
return append(escapeMeasurement(unescapeMeasurement(name)), tags.HashKey()...) return append(escapeMeasurement(unescapeMeasurement(name)), tags.HashKey()...)
} }
// SetTags replaces the tags for the point // SetTags replaces the tags for the point.
func (p *point) SetTags(tags Tags) { func (p *point) SetTags(tags Tags) {
p.key = MakeKey([]byte(p.Name()), tags) p.key = MakeKey([]byte(p.Name()), tags)
p.cachedTags = tags p.cachedTags = tags
} }
// AddTag adds or replaces a tag value for a point // AddTag adds or replaces a tag value for a point.
func (p *point) AddTag(key, value string) { func (p *point) AddTag(key, value string) {
tags := p.Tags() tags := p.Tags()
tags = append(tags, Tag{Key: []byte(key), Value: []byte(value)}) tags = append(tags, Tag{Key: []byte(key), Value: []byte(value)})
@ -1337,7 +1392,7 @@ func (p *point) AddTag(key, value string) {
p.key = MakeKey([]byte(p.Name()), tags) p.key = MakeKey([]byte(p.Name()), tags)
} }
// Fields returns the fields for the point // Fields returns the fields for the point.
func (p *point) Fields() Fields { func (p *point) Fields() Fields {
if p.cachedFields != nil { if p.cachedFields != nil {
return p.cachedFields return p.cachedFields
@ -1346,7 +1401,7 @@ func (p *point) Fields() Fields {
return p.cachedFields return p.cachedFields
} }
// SetPrecision will round a time to the specified precision // SetPrecision will round a time to the specified precision.
func (p *point) SetPrecision(precision string) { func (p *point) SetPrecision(precision string) {
switch precision { switch precision {
case "n": case "n":
@ -1363,6 +1418,7 @@ func (p *point) SetPrecision(precision string) {
} }
} }
// String returns the string representation of the point.
func (p *point) String() string { func (p *point) String() string {
if p.Time().IsZero() { if p.Time().IsZero() {
return string(p.Key()) + " " + string(p.fields) return string(p.Key()) + " " + string(p.fields)
@ -1370,7 +1426,7 @@ func (p *point) String() string {
return string(p.Key()) + " " + string(p.fields) + " " + strconv.FormatInt(p.UnixNano(), 10) return string(p.Key()) + " " + string(p.fields) + " " + strconv.FormatInt(p.UnixNano(), 10)
} }
// AppendString implements Point.AppendString // AppendString appends the string representation of the point to buf.
func (p *point) AppendString(buf []byte) []byte { func (p *point) AppendString(buf []byte) []byte {
buf = append(buf, p.key...) buf = append(buf, p.key...)
buf = append(buf, ' ') buf = append(buf, ' ')
@ -1384,6 +1440,7 @@ func (p *point) AppendString(buf []byte) []byte {
return buf return buf
} }
// StringSize returns the length of the string that would be returned by String().
func (p *point) StringSize() int { func (p *point) StringSize() int {
size := len(p.key) + len(p.fields) + 1 size := len(p.key) + len(p.fields) + 1
@ -1405,6 +1462,7 @@ func (p *point) StringSize() int {
return size return size
} }
// MarshalBinary returns a binary representation of the point.
func (p *point) MarshalBinary() ([]byte, error) { func (p *point) MarshalBinary() ([]byte, error) {
if len(p.fields) == 0 { if len(p.fields) == 0 {
return nil, ErrPointMustHaveAField return nil, ErrPointMustHaveAField
@ -1432,6 +1490,7 @@ func (p *point) MarshalBinary() ([]byte, error) {
return b, nil return b, nil
} }
// UnmarshalBinary decodes a binary representation of the point into a point struct.
func (p *point) UnmarshalBinary(b []byte) error { func (p *point) UnmarshalBinary(b []byte) error {
var i int var i int
keyLen := int(binary.BigEndian.Uint32(b[:4])) keyLen := int(binary.BigEndian.Uint32(b[:4]))
@ -1451,6 +1510,9 @@ func (p *point) UnmarshalBinary(b []byte) error {
return nil return nil
} }
// PrecisionString returns a string representation of the point. If there
// is a timestamp associated with the point then it will be specified in the
// given unit.
func (p *point) PrecisionString(precision string) string { func (p *point) PrecisionString(precision string) string {
if p.Time().IsZero() { if p.Time().IsZero() {
return fmt.Sprintf("%s %s", p.Key(), string(p.fields)) return fmt.Sprintf("%s %s", p.Key(), string(p.fields))
@ -1459,6 +1521,9 @@ func (p *point) PrecisionString(precision string) string {
p.UnixNano()/GetPrecisionMultiplier(precision)) p.UnixNano()/GetPrecisionMultiplier(precision))
} }
// RoundedString returns a string representation of the point. If there
// is a timestamp associated with the point, then it will be rounded to the
// given duration.
func (p *point) RoundedString(d time.Duration) string { func (p *point) RoundedString(d time.Duration) string {
if p.Time().IsZero() { if p.Time().IsZero() {
return fmt.Sprintf("%s %s", p.Key(), string(p.fields)) return fmt.Sprintf("%s %s", p.Key(), string(p.fields))
@ -1488,6 +1553,7 @@ func (p *point) unmarshalBinary() Fields {
return fields return fields
} }
// HashID returns a non-cryptographic checksum of the point's key.
func (p *point) HashID() uint64 { func (p *point) HashID() uint64 {
h := NewInlineFNV64a() h := NewInlineFNV64a()
h.Write(p.key) h.Write(p.key)
@ -1495,10 +1561,14 @@ func (p *point) HashID() uint64 {
return sum return sum
} }
// UnixNano returns the timestamp of the point as nanoseconds since Unix epoch.
func (p *point) UnixNano() int64 { func (p *point) UnixNano() int64 {
return p.Time().UnixNano() return p.Time().UnixNano()
} }
// Split will attempt to return multiple points with the same timestamp whose
// string representations are no longer than size. Points with a single field or
// a point without a timestamp may exceed the requested size.
func (p *point) Split(size int) []Point { func (p *point) Split(size int) []Point {
if p.time.IsZero() || len(p.String()) <= size { if p.time.IsZero() || len(p.String()) <= size {
return []Point{p} return []Point{p}
@ -1557,9 +1627,14 @@ func NewTags(m map[string]string) Tags {
return a return a
} }
func (a Tags) Len() int { return len(a) } // Len implements sort.Interface.
func (a Tags) Len() int { return len(a) }
// Less implements sort.Interface.
func (a Tags) Less(i, j int) bool { return bytes.Compare(a[i].Key, a[j].Key) == -1 } func (a Tags) Less(i, j int) bool { return bytes.Compare(a[i].Key, a[j].Key) == -1 }
func (a Tags) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Swap implements sort.Interface.
func (a Tags) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Get returns the value for a key. // Get returns the value for a key.
func (a Tags) Get(key []byte) []byte { func (a Tags) Get(key []byte) []byte {
@ -1696,6 +1771,8 @@ func parseNumber(val []byte) (interface{}, error) {
return parseFloatBytes(val, 64) return parseFloatBytes(val, 64)
} }
// FieldIterator retuns a FieldIterator that can be used to traverse the
// fields of a point without constructing the in-memory map.
func (p *point) FieldIterator() FieldIterator { func (p *point) FieldIterator() FieldIterator {
p.Reset() p.Reset()
return p return p
@ -1708,6 +1785,7 @@ type fieldIterator struct {
fieldType FieldType fieldType FieldType
} }
// Next indicates whether there any fields remaining.
func (p *point) Next() bool { func (p *point) Next() bool {
p.it.start = p.it.end p.it.start = p.it.end
if p.it.start >= len(p.fields) { if p.it.start >= len(p.fields) {
@ -1750,18 +1828,22 @@ func (p *point) Next() bool {
return true return true
} }
// FieldKey returns the key of the current field.
func (p *point) FieldKey() []byte { func (p *point) FieldKey() []byte {
return p.it.key return p.it.key
} }
// Type returns the FieldType of the current field.
func (p *point) Type() FieldType { func (p *point) Type() FieldType {
return p.it.fieldType return p.it.fieldType
} }
// StringValue returns the string value of the current field.
func (p *point) StringValue() string { func (p *point) StringValue() string {
return unescapeStringField(string(p.it.valueBuf[1 : len(p.it.valueBuf)-1])) return unescapeStringField(string(p.it.valueBuf[1 : len(p.it.valueBuf)-1]))
} }
// IntegerValue returns the integer value of the current field.
func (p *point) IntegerValue() int64 { func (p *point) IntegerValue() int64 {
n, err := parseIntBytes(p.it.valueBuf, 10, 64) n, err := parseIntBytes(p.it.valueBuf, 10, 64)
if err != nil { if err != nil {
@ -1770,6 +1852,7 @@ func (p *point) IntegerValue() int64 {
return n return n
} }
// BooleanValue returns the boolean value of the current field.
func (p *point) BooleanValue() bool { func (p *point) BooleanValue() bool {
b, err := parseBoolBytes(p.it.valueBuf) b, err := parseBoolBytes(p.it.valueBuf)
if err != nil { if err != nil {
@ -1778,6 +1861,7 @@ func (p *point) BooleanValue() bool {
return b return b
} }
// FloatValue returns the float value of the current field.
func (p *point) FloatValue() float64 { func (p *point) FloatValue() float64 {
f, err := parseFloatBytes(p.it.valueBuf, 64) f, err := parseFloatBytes(p.it.valueBuf, 64)
if err != nil { if err != nil {
@ -1787,6 +1871,7 @@ func (p *point) FloatValue() float64 {
return f return f
} }
// Delete deletes the current field.
func (p *point) Delete() { func (p *point) Delete() {
switch { switch {
case p.it.end == p.it.start: case p.it.end == p.it.start:
@ -1804,6 +1889,7 @@ func (p *point) Delete() {
p.it.fieldType = Empty p.it.fieldType = Empty
} }
// Reset resets the iterator to its initial state.
func (p *point) Reset() { func (p *point) Reset() {
p.it.fieldType = Empty p.it.fieldType = Empty
p.it.key = nil p.it.key = nil

View File

@ -42,8 +42,10 @@ func (r *Row) tagsKeys() []string {
// Rows represents a collection of rows. Rows implements sort.Interface. // Rows represents a collection of rows. Rows implements sort.Interface.
type Rows []*Row type Rows []*Row
// Len implements sort.Interface.
func (p Rows) Len() int { return len(p) } func (p Rows) Len() int { return len(p) }
// Less implements sort.Interface.
func (p Rows) Less(i, j int) bool { func (p Rows) Less(i, j int) bool {
// Sort by name first. // Sort by name first.
if p[i].Name != p[j].Name { if p[i].Name != p[j].Name {
@ -56,4 +58,5 @@ func (p Rows) Less(i, j int) bool {
return p[i].tagsHash() < p[j].tagsHash() return p[i].tagsHash() < p[j].tagsHash()
} }
// Swap implements sort.Interface.
func (p Rows) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p Rows) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

View File

@ -1,11 +1,13 @@
package models package models
// Statistic is the representation of a statistic used by the monitoring service.
type Statistic struct { type Statistic struct {
Name string `json:"name"` Name string `json:"name"`
Tags map[string]string `json:"tags"` Tags map[string]string `json:"tags"`
Values map[string]interface{} `json:"values"` Values map[string]interface{} `json:"values"`
} }
// NewStatistic returns an initialized Statistic.
func NewStatistic(name string) Statistic { func NewStatistic(name string) Statistic {
return Statistic{ return Statistic{
Name: name, Name: name,