set.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package attribute // import "go.opentelemetry.io/otel/attribute"
  4. import (
  5. "cmp"
  6. "encoding/json"
  7. "reflect"
  8. "slices"
  9. "sort"
  10. )
  11. type (
  12. // Set is the representation for a distinct attribute set. It manages an
  13. // immutable set of attributes, with an internal cache for storing
  14. // attribute encodings.
  15. //
  16. // This type will remain comparable for backwards compatibility. The
  17. // equivalence of Sets across versions is not guaranteed to be stable.
  18. // Prior versions may find two Sets to be equal or not when compared
  19. // directly (i.e. ==), but subsequent versions may not. Users should use
  20. // the Equals method to ensure stable equivalence checking.
  21. //
  22. // Users should also use the Distinct returned from Equivalent as a map key
  23. // instead of a Set directly. In addition to that type providing guarantees
  24. // on stable equivalence, it may also provide performance improvements.
  25. Set struct {
  26. equivalent Distinct
  27. }
  28. // Distinct is a unique identifier of a Set.
  29. //
  30. // Distinct is designed to be ensures equivalence stability: comparisons
  31. // will return the save value across versions. For this reason, Distinct
  32. // should always be used as a map key instead of a Set.
  33. Distinct struct {
  34. iface interface{}
  35. }
  36. // Sortable implements sort.Interface, used for sorting KeyValue.
  37. //
  38. // Deprecated: This type is no longer used. It was added as a performance
  39. // optimization for Go < 1.21 that is no longer needed (Go < 1.21 is no
  40. // longer supported by the module).
  41. Sortable []KeyValue
  42. )
  43. var (
  44. // keyValueType is used in computeDistinctReflect.
  45. keyValueType = reflect.TypeOf(KeyValue{})
  46. // emptySet is returned for empty attribute sets.
  47. emptySet = &Set{
  48. equivalent: Distinct{
  49. iface: [0]KeyValue{},
  50. },
  51. }
  52. )
  53. // EmptySet returns a reference to a Set with no elements.
  54. //
  55. // This is a convenience provided for optimized calling utility.
  56. func EmptySet() *Set {
  57. return emptySet
  58. }
  59. // reflectValue abbreviates reflect.ValueOf(d).
  60. func (d Distinct) reflectValue() reflect.Value {
  61. return reflect.ValueOf(d.iface)
  62. }
  63. // Valid returns true if this value refers to a valid Set.
  64. func (d Distinct) Valid() bool {
  65. return d.iface != nil
  66. }
  67. // Len returns the number of attributes in this set.
  68. func (l *Set) Len() int {
  69. if l == nil || !l.equivalent.Valid() {
  70. return 0
  71. }
  72. return l.equivalent.reflectValue().Len()
  73. }
  74. // Get returns the KeyValue at ordered position idx in this set.
  75. func (l *Set) Get(idx int) (KeyValue, bool) {
  76. if l == nil || !l.equivalent.Valid() {
  77. return KeyValue{}, false
  78. }
  79. value := l.equivalent.reflectValue()
  80. if idx >= 0 && idx < value.Len() {
  81. // Note: The Go compiler successfully avoids an allocation for
  82. // the interface{} conversion here:
  83. return value.Index(idx).Interface().(KeyValue), true
  84. }
  85. return KeyValue{}, false
  86. }
  87. // Value returns the value of a specified key in this set.
  88. func (l *Set) Value(k Key) (Value, bool) {
  89. if l == nil || !l.equivalent.Valid() {
  90. return Value{}, false
  91. }
  92. rValue := l.equivalent.reflectValue()
  93. vlen := rValue.Len()
  94. idx := sort.Search(vlen, func(idx int) bool {
  95. return rValue.Index(idx).Interface().(KeyValue).Key >= k
  96. })
  97. if idx >= vlen {
  98. return Value{}, false
  99. }
  100. keyValue := rValue.Index(idx).Interface().(KeyValue)
  101. if k == keyValue.Key {
  102. return keyValue.Value, true
  103. }
  104. return Value{}, false
  105. }
  106. // HasValue tests whether a key is defined in this set.
  107. func (l *Set) HasValue(k Key) bool {
  108. if l == nil {
  109. return false
  110. }
  111. _, ok := l.Value(k)
  112. return ok
  113. }
  114. // Iter returns an iterator for visiting the attributes in this set.
  115. func (l *Set) Iter() Iterator {
  116. return Iterator{
  117. storage: l,
  118. idx: -1,
  119. }
  120. }
  121. // ToSlice returns the set of attributes belonging to this set, sorted, where
  122. // keys appear no more than once.
  123. func (l *Set) ToSlice() []KeyValue {
  124. iter := l.Iter()
  125. return iter.ToSlice()
  126. }
  127. // Equivalent returns a value that may be used as a map key. The Distinct type
  128. // guarantees that the result will equal the equivalent. Distinct value of any
  129. // attribute set with the same elements as this, where sets are made unique by
  130. // choosing the last value in the input for any given key.
  131. func (l *Set) Equivalent() Distinct {
  132. if l == nil || !l.equivalent.Valid() {
  133. return emptySet.equivalent
  134. }
  135. return l.equivalent
  136. }
  137. // Equals returns true if the argument set is equivalent to this set.
  138. func (l *Set) Equals(o *Set) bool {
  139. return l.Equivalent() == o.Equivalent()
  140. }
  141. // Encoded returns the encoded form of this set, according to encoder.
  142. func (l *Set) Encoded(encoder Encoder) string {
  143. if l == nil || encoder == nil {
  144. return ""
  145. }
  146. return encoder.Encode(l.Iter())
  147. }
  148. func empty() Set {
  149. return Set{
  150. equivalent: emptySet.equivalent,
  151. }
  152. }
  153. // NewSet returns a new Set. See the documentation for
  154. // NewSetWithSortableFiltered for more details.
  155. //
  156. // Except for empty sets, this method adds an additional allocation compared
  157. // with calls that include a Sortable.
  158. func NewSet(kvs ...KeyValue) Set {
  159. s, _ := NewSetWithFiltered(kvs, nil)
  160. return s
  161. }
  162. // NewSetWithSortable returns a new Set. See the documentation for
  163. // NewSetWithSortableFiltered for more details.
  164. //
  165. // This call includes a Sortable option as a memory optimization.
  166. //
  167. // Deprecated: Use [NewSet] instead.
  168. func NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set {
  169. s, _ := NewSetWithFiltered(kvs, nil)
  170. return s
  171. }
  172. // NewSetWithFiltered returns a new Set. See the documentation for
  173. // NewSetWithSortableFiltered for more details.
  174. //
  175. // This call includes a Filter to include/exclude attribute keys from the
  176. // return value. Excluded keys are returned as a slice of attribute values.
  177. func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
  178. // Check for empty set.
  179. if len(kvs) == 0 {
  180. return empty(), nil
  181. }
  182. // Stable sort so the following de-duplication can implement
  183. // last-value-wins semantics.
  184. slices.SortStableFunc(kvs, func(a, b KeyValue) int {
  185. return cmp.Compare(a.Key, b.Key)
  186. })
  187. position := len(kvs) - 1
  188. offset := position - 1
  189. // The requirements stated above require that the stable
  190. // result be placed in the end of the input slice, while
  191. // overwritten values are swapped to the beginning.
  192. //
  193. // De-duplicate with last-value-wins semantics. Preserve
  194. // duplicate values at the beginning of the input slice.
  195. for ; offset >= 0; offset-- {
  196. if kvs[offset].Key == kvs[position].Key {
  197. continue
  198. }
  199. position--
  200. kvs[offset], kvs[position] = kvs[position], kvs[offset]
  201. }
  202. kvs = kvs[position:]
  203. if filter != nil {
  204. if div := filteredToFront(kvs, filter); div != 0 {
  205. return Set{equivalent: computeDistinct(kvs[div:])}, kvs[:div]
  206. }
  207. }
  208. return Set{equivalent: computeDistinct(kvs)}, nil
  209. }
  210. // NewSetWithSortableFiltered returns a new Set.
  211. //
  212. // Duplicate keys are eliminated by taking the last value. This
  213. // re-orders the input slice so that unique last-values are contiguous
  214. // at the end of the slice.
  215. //
  216. // This ensures the following:
  217. //
  218. // - Last-value-wins semantics
  219. // - Caller sees the reordering, but doesn't lose values
  220. // - Repeated call preserve last-value wins.
  221. //
  222. // Note that methods are defined on Set, although this returns Set. Callers
  223. // can avoid memory allocations by:
  224. //
  225. // - allocating a Sortable for use as a temporary in this method
  226. // - allocating a Set for storing the return value of this constructor.
  227. //
  228. // The result maintains a cache of encoded attributes, by attribute.EncoderID.
  229. // This value should not be copied after its first use.
  230. //
  231. // The second []KeyValue return value is a list of attributes that were
  232. // excluded by the Filter (if non-nil).
  233. //
  234. // Deprecated: Use [NewSetWithFiltered] instead.
  235. func NewSetWithSortableFiltered(kvs []KeyValue, _ *Sortable, filter Filter) (Set, []KeyValue) {
  236. return NewSetWithFiltered(kvs, filter)
  237. }
  238. // filteredToFront filters slice in-place using keep function. All KeyValues that need to
  239. // be removed are moved to the front. All KeyValues that need to be kept are
  240. // moved (in-order) to the back. The index for the first KeyValue to be kept is
  241. // returned.
  242. func filteredToFront(slice []KeyValue, keep Filter) int {
  243. n := len(slice)
  244. j := n
  245. for i := n - 1; i >= 0; i-- {
  246. if keep(slice[i]) {
  247. j--
  248. slice[i], slice[j] = slice[j], slice[i]
  249. }
  250. }
  251. return j
  252. }
  253. // Filter returns a filtered copy of this Set. See the documentation for
  254. // NewSetWithSortableFiltered for more details.
  255. func (l *Set) Filter(re Filter) (Set, []KeyValue) {
  256. if re == nil {
  257. return *l, nil
  258. }
  259. // Iterate in reverse to the first attribute that will be filtered out.
  260. n := l.Len()
  261. first := n - 1
  262. for ; first >= 0; first-- {
  263. kv, _ := l.Get(first)
  264. if !re(kv) {
  265. break
  266. }
  267. }
  268. // No attributes will be dropped, return the immutable Set l and nil.
  269. if first < 0 {
  270. return *l, nil
  271. }
  272. // Copy now that we know we need to return a modified set.
  273. //
  274. // Do not do this in-place on the underlying storage of *Set l. Sets are
  275. // immutable and filtering should not change this.
  276. slice := l.ToSlice()
  277. // Don't re-iterate the slice if only slice[0] is filtered.
  278. if first == 0 {
  279. // It is safe to assume len(slice) >= 1 given we found at least one
  280. // attribute above that needs to be filtered out.
  281. return Set{equivalent: computeDistinct(slice[1:])}, slice[:1]
  282. }
  283. // Move the filtered slice[first] to the front (preserving order).
  284. kv := slice[first]
  285. copy(slice[1:first+1], slice[:first])
  286. slice[0] = kv
  287. // Do not re-evaluate re(slice[first+1:]).
  288. div := filteredToFront(slice[1:first+1], re) + 1
  289. return Set{equivalent: computeDistinct(slice[div:])}, slice[:div]
  290. }
  291. // computeDistinct returns a Distinct using either the fixed- or
  292. // reflect-oriented code path, depending on the size of the input. The input
  293. // slice is assumed to already be sorted and de-duplicated.
  294. func computeDistinct(kvs []KeyValue) Distinct {
  295. iface := computeDistinctFixed(kvs)
  296. if iface == nil {
  297. iface = computeDistinctReflect(kvs)
  298. }
  299. return Distinct{
  300. iface: iface,
  301. }
  302. }
  303. // computeDistinctFixed computes a Distinct for small slices. It returns nil
  304. // if the input is too large for this code path.
  305. func computeDistinctFixed(kvs []KeyValue) interface{} {
  306. switch len(kvs) {
  307. case 1:
  308. return [1]KeyValue(kvs)
  309. case 2:
  310. return [2]KeyValue(kvs)
  311. case 3:
  312. return [3]KeyValue(kvs)
  313. case 4:
  314. return [4]KeyValue(kvs)
  315. case 5:
  316. return [5]KeyValue(kvs)
  317. case 6:
  318. return [6]KeyValue(kvs)
  319. case 7:
  320. return [7]KeyValue(kvs)
  321. case 8:
  322. return [8]KeyValue(kvs)
  323. case 9:
  324. return [9]KeyValue(kvs)
  325. case 10:
  326. return [10]KeyValue(kvs)
  327. default:
  328. return nil
  329. }
  330. }
  331. // computeDistinctReflect computes a Distinct using reflection, works for any
  332. // size input.
  333. func computeDistinctReflect(kvs []KeyValue) interface{} {
  334. at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()
  335. for i, keyValue := range kvs {
  336. *(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue
  337. }
  338. return at.Interface()
  339. }
  340. // MarshalJSON returns the JSON encoding of the Set.
  341. func (l *Set) MarshalJSON() ([]byte, error) {
  342. return json.Marshal(l.equivalent.iface)
  343. }
  344. // MarshalLog is the marshaling function used by the logging system to represent this Set.
  345. func (l Set) MarshalLog() interface{} {
  346. kvs := make(map[string]string)
  347. for _, kv := range l.ToSlice() {
  348. kvs[string(kv.Key)] = kv.Value.Emit()
  349. }
  350. return kvs
  351. }
  352. // Len implements sort.Interface.
  353. func (l *Sortable) Len() int {
  354. return len(*l)
  355. }
  356. // Swap implements sort.Interface.
  357. func (l *Sortable) Swap(i, j int) {
  358. (*l)[i], (*l)[j] = (*l)[j], (*l)[i]
  359. }
  360. // Less implements sort.Interface.
  361. func (l *Sortable) Less(i, j int) bool {
  362. return (*l)[i].Key < (*l)[j].Key
  363. }