rows.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package models
  2. import (
  3. "hash/fnv"
  4. "sort"
  5. )
  6. // Row represents a single row returned from the execution of a statement.
  7. type Row struct {
  8. Name string `json:"name,omitempty"`
  9. Tags map[string]string `json:"tags,omitempty"`
  10. Columns []string `json:"columns,omitempty"`
  11. Values [][]interface{} `json:"values,omitempty"`
  12. Err error `json:"err,omitempty"`
  13. }
  14. // SameSeries returns true if r contains values for the same series as o.
  15. func (r *Row) SameSeries(o *Row) bool {
  16. return r.tagsHash() == o.tagsHash() && r.Name == o.Name
  17. }
  18. // tagsHash returns a hash of tag key/value pairs.
  19. func (r *Row) tagsHash() uint64 {
  20. h := fnv.New64a()
  21. keys := r.tagsKeys()
  22. for _, k := range keys {
  23. h.Write([]byte(k))
  24. h.Write([]byte(r.Tags[k]))
  25. }
  26. return h.Sum64()
  27. }
  28. // tagKeys returns a sorted list of tag keys.
  29. func (r *Row) tagsKeys() []string {
  30. a := make([]string, 0, len(r.Tags))
  31. for k := range r.Tags {
  32. a = append(a, k)
  33. }
  34. sort.Strings(a)
  35. return a
  36. }
  37. // Rows represents a collection of rows. Rows implements sort.Interface.
  38. type Rows []*Row
  39. func (p Rows) Len() int { return len(p) }
  40. func (p Rows) Less(i, j int) bool {
  41. // Sort by name first.
  42. if p[i].Name != p[j].Name {
  43. return p[i].Name < p[j].Name
  44. }
  45. // Sort by tag set hash. Tags don't have a meaningful sort order so we
  46. // just compute a hash and sort by that instead. This allows the tests
  47. // to receive rows in a predictable order every time.
  48. return p[i].tagsHash() < p[j].tagsHash()
  49. }
  50. func (p Rows) Swap(i, j int) { p[i], p[j] = p[j], p[i] }