You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
2.4 KiB

  1. // Copyright 2017, OpenCensus Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. package view
  16. import (
  17. "sort"
  18. "go.opencensus.io/exemplar"
  19. "go.opencensus.io/internal/tagencoding"
  20. "go.opencensus.io/tag"
  21. )
  22. type collector struct {
  23. // signatures holds the aggregations values for each unique tag signature
  24. // (values for all keys) to its aggregator.
  25. signatures map[string]AggregationData
  26. // Aggregation is the description of the aggregation to perform for this
  27. // view.
  28. a *Aggregation
  29. }
  30. func (c *collector) addSample(s string, e *exemplar.Exemplar) {
  31. aggregator, ok := c.signatures[s]
  32. if !ok {
  33. aggregator = c.a.newData()
  34. c.signatures[s] = aggregator
  35. }
  36. aggregator.addSample(e)
  37. }
  38. // collectRows returns a snapshot of the collected Row values.
  39. func (c *collector) collectedRows(keys []tag.Key) []*Row {
  40. rows := make([]*Row, 0, len(c.signatures))
  41. for sig, aggregator := range c.signatures {
  42. tags := decodeTags([]byte(sig), keys)
  43. row := &Row{Tags: tags, Data: aggregator.clone()}
  44. rows = append(rows, row)
  45. }
  46. return rows
  47. }
  48. func (c *collector) clearRows() {
  49. c.signatures = make(map[string]AggregationData)
  50. }
  51. // encodeWithKeys encodes the map by using values
  52. // only associated with the keys provided.
  53. func encodeWithKeys(m *tag.Map, keys []tag.Key) []byte {
  54. vb := &tagencoding.Values{
  55. Buffer: make([]byte, len(keys)),
  56. }
  57. for _, k := range keys {
  58. v, _ := m.Value(k)
  59. vb.WriteValue([]byte(v))
  60. }
  61. return vb.Bytes()
  62. }
  63. // decodeTags decodes tags from the buffer and
  64. // orders them by the keys.
  65. func decodeTags(buf []byte, keys []tag.Key) []tag.Tag {
  66. vb := &tagencoding.Values{Buffer: buf}
  67. var tags []tag.Tag
  68. for _, k := range keys {
  69. v := vb.ReadValue()
  70. if v != nil {
  71. tags = append(tags, tag.Tag{Key: k, Value: string(v)})
  72. }
  73. }
  74. vb.ReadIndex = 0
  75. sort.Slice(tags, func(i, j int) bool { return tags[i].Key.Name() < tags[j].Key.Name() })
  76. return tags
  77. }