1
// Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
7 #include "opentelemetry/context/context_value.h"
8 #include "opentelemetry/nostd/shared_ptr.h"
9 #include "opentelemetry/nostd/string_view.h"
11 OPENTELEMETRY_BEGIN_NAMESPACE
15 // The context class provides a context identifier. Is built as a linked list
16 // of DataList nodes and each context holds a shared_ptr to a place within
17 // the list that determines which keys and values it has access to. All that
18 // come before and none that come after.
24 // Creates a context object from a map of keys and identifiers, this will
25 // hold a shared_ptr to the head of the DataList linked list
27 Context(const T
&keys_and_values
) noexcept
29 head_
= nostd::shared_ptr
<DataList
>{new DataList(keys_and_values
)};
32 // Creates a context object from a key and value, this will
33 // hold a shared_ptr to the head of the DataList linked list
34 Context(nostd::string_view key
, ContextValue value
) noexcept
36 head_
= nostd::shared_ptr
<DataList
>{new DataList(key
, value
)};
39 // Accepts a new iterable and then returns a new context that
40 // contains the new key and value data. It attaches the
41 // exisiting list to the end of the new list.
43 Context
SetValues(T
&values
) noexcept
45 Context context
= Context(values
);
46 nostd::shared_ptr
<DataList
> last
= context
.head_
;
47 while (last
->next_
!= nullptr)
55 // Accepts a new iterable and then returns a new context that
56 // contains the new key and value data. It attaches the
57 // exisiting list to the end of the new list.
58 Context
SetValue(nostd::string_view key
, ContextValue value
) noexcept
60 Context context
= Context(key
, value
);
61 context
.head_
->next_
= head_
;
65 // Returns the value associated with the passed in key.
66 context::ContextValue
GetValue(const nostd::string_view key
) const noexcept
68 for (DataList
*data
= head_
.get(); data
!= nullptr; data
= data
->next_
.get())
70 if (key
.size() == data
->key_length_
)
72 if (std::memcmp(key
.data(), data
->key_
, data
->key_length_
) == 0)
78 return ContextValue
{};
81 // Checks for key and returns true if found
82 bool HasKey(const nostd::string_view key
) const noexcept
84 return !nostd::holds_alternative
<nostd::monostate
>(GetValue(key
));
87 bool operator==(const Context
&other
) const noexcept
{ return (head_
== other
.head_
); }
90 // A linked list to contain the keys and values of this context node
96 nostd::shared_ptr
<DataList
> next_
;
102 DataList() { next_
= nullptr; }
104 // Builds a data list off of a key and value iterable and returns the head
106 DataList(const T
&keys_and_vals
) : key_
{nullptr}, next_(nostd::shared_ptr
<DataList
>{nullptr})
110 for (auto &iter
: keys_and_vals
)
114 *node
= DataList(iter
.first
, iter
.second
);
119 node
->next_
= nostd::shared_ptr
<DataList
>(new DataList(iter
.first
, iter
.second
));
120 node
= node
->next_
.get();
125 // Builds a data list with just a key and value, so it will just be the head
126 // and returns that head.
127 DataList(nostd::string_view key
, const ContextValue
&value
)
129 key_
= new char[key
.size()];
130 key_length_
= key
.size();
131 memcpy(key_
, key
.data(), key
.size() * sizeof(char));
133 next_
= nostd::shared_ptr
<DataList
>{nullptr};
136 DataList
&operator=(DataList
&&other
) noexcept
138 key_length_
= other
.key_length_
;
139 value_
= std::move(other
.value_
);
140 next_
= std::move(other
.next_
);
143 other
.key_
= nullptr;
157 // Head of the list which holds the keys and values of this context
158 nostd::shared_ptr
<DataList
> head_
;
160 } // namespace context
161 OPENTELEMETRY_END_NAMESPACE