github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.opentelemetry.io/otel/attribute/iterator.go (about)

     1  // Copyright The OpenTelemetry 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 attribute // import "go.opentelemetry.io/otel/attribute"
    16  
    17  // Iterator allows iterating over the set of attributes in order, sorted by
    18  // key.
    19  type Iterator struct {
    20  	storage *Set
    21  	idx     int
    22  }
    23  
    24  // MergeIterator supports iterating over two sets of attributes while
    25  // eliminating duplicate values from the combined set. The first iterator
    26  // value takes precedence.
    27  type MergeIterator struct {
    28  	one     oneIterator
    29  	two     oneIterator
    30  	current KeyValue
    31  }
    32  
    33  type oneIterator struct {
    34  	iter Iterator
    35  	done bool
    36  	attr KeyValue
    37  }
    38  
    39  // Next moves the iterator to the next position. Returns false if there are no
    40  // more attributes.
    41  func (i *Iterator) Next() bool {
    42  	i.idx++
    43  	return i.idx < i.Len()
    44  }
    45  
    46  // Label returns current KeyValue. Must be called only after Next returns
    47  // true.
    48  //
    49  // Deprecated: Use Attribute instead.
    50  func (i *Iterator) Label() KeyValue {
    51  	return i.Attribute()
    52  }
    53  
    54  // Attribute returns the current KeyValue of the Iterator. It must be called
    55  // only after Next returns true.
    56  func (i *Iterator) Attribute() KeyValue {
    57  	kv, _ := i.storage.Get(i.idx)
    58  	return kv
    59  }
    60  
    61  // IndexedLabel returns current index and attribute. Must be called only
    62  // after Next returns true.
    63  //
    64  // Deprecated: Use IndexedAttribute instead.
    65  func (i *Iterator) IndexedLabel() (int, KeyValue) {
    66  	return i.idx, i.Attribute()
    67  }
    68  
    69  // IndexedAttribute returns current index and attribute. Must be called only
    70  // after Next returns true.
    71  func (i *Iterator) IndexedAttribute() (int, KeyValue) {
    72  	return i.idx, i.Attribute()
    73  }
    74  
    75  // Len returns a number of attributes in the iterated set.
    76  func (i *Iterator) Len() int {
    77  	return i.storage.Len()
    78  }
    79  
    80  // ToSlice is a convenience function that creates a slice of attributes from
    81  // the passed iterator. The iterator is set up to start from the beginning
    82  // before creating the slice.
    83  func (i *Iterator) ToSlice() []KeyValue {
    84  	l := i.Len()
    85  	if l == 0 {
    86  		return nil
    87  	}
    88  	i.idx = -1
    89  	slice := make([]KeyValue, 0, l)
    90  	for i.Next() {
    91  		slice = append(slice, i.Attribute())
    92  	}
    93  	return slice
    94  }
    95  
    96  // NewMergeIterator returns a MergeIterator for merging two attribute sets.
    97  // Duplicates are resolved by taking the value from the first set.
    98  func NewMergeIterator(s1, s2 *Set) MergeIterator {
    99  	mi := MergeIterator{
   100  		one: makeOne(s1.Iter()),
   101  		two: makeOne(s2.Iter()),
   102  	}
   103  	return mi
   104  }
   105  
   106  func makeOne(iter Iterator) oneIterator {
   107  	oi := oneIterator{
   108  		iter: iter,
   109  	}
   110  	oi.advance()
   111  	return oi
   112  }
   113  
   114  func (oi *oneIterator) advance() {
   115  	if oi.done = !oi.iter.Next(); !oi.done {
   116  		oi.attr = oi.iter.Attribute()
   117  	}
   118  }
   119  
   120  // Next returns true if there is another attribute available.
   121  func (m *MergeIterator) Next() bool {
   122  	if m.one.done && m.two.done {
   123  		return false
   124  	}
   125  	if m.one.done {
   126  		m.current = m.two.attr
   127  		m.two.advance()
   128  		return true
   129  	}
   130  	if m.two.done {
   131  		m.current = m.one.attr
   132  		m.one.advance()
   133  		return true
   134  	}
   135  	if m.one.attr.Key == m.two.attr.Key {
   136  		m.current = m.one.attr // first iterator attribute value wins
   137  		m.one.advance()
   138  		m.two.advance()
   139  		return true
   140  	}
   141  	if m.one.attr.Key < m.two.attr.Key {
   142  		m.current = m.one.attr
   143  		m.one.advance()
   144  		return true
   145  	}
   146  	m.current = m.two.attr
   147  	m.two.advance()
   148  	return true
   149  }
   150  
   151  // Label returns the current value after Next() returns true.
   152  //
   153  // Deprecated: Use Attribute instead.
   154  func (m *MergeIterator) Label() KeyValue {
   155  	return m.current
   156  }
   157  
   158  // Attribute returns the current value after Next() returns true.
   159  func (m *MergeIterator) Attribute() KeyValue {
   160  	return m.current
   161  }