]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/context/context.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / api / include / opentelemetry / context / context.h
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #pragma once
5
6 #include <cstring>
7 #include "opentelemetry/context/context_value.h"
8 #include "opentelemetry/nostd/shared_ptr.h"
9 #include "opentelemetry/nostd/string_view.h"
10
11 OPENTELEMETRY_BEGIN_NAMESPACE
12 namespace context
13 {
14
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.
19 class Context
20 {
21
22 public:
23 Context() = default;
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
26 template <class T>
27 Context(const T &keys_and_values) noexcept
28 {
29 head_ = nostd::shared_ptr<DataList>{new DataList(keys_and_values)};
30 }
31
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
35 {
36 head_ = nostd::shared_ptr<DataList>{new DataList(key, value)};
37 }
38
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.
42 template <class T>
43 Context SetValues(T &values) noexcept
44 {
45 Context context = Context(values);
46 nostd::shared_ptr<DataList> last = context.head_;
47 while (last->next_ != nullptr)
48 {
49 last = last->next_;
50 }
51 last->next_ = head_;
52 return context;
53 }
54
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
59 {
60 Context context = Context(key, value);
61 context.head_->next_ = head_;
62 return context;
63 }
64
65 // Returns the value associated with the passed in key.
66 context::ContextValue GetValue(const nostd::string_view key) const noexcept
67 {
68 for (DataList *data = head_.get(); data != nullptr; data = data->next_.get())
69 {
70 if (key.size() == data->key_length_)
71 {
72 if (std::memcmp(key.data(), data->key_, data->key_length_) == 0)
73 {
74 return data->value_;
75 }
76 }
77 }
78 return ContextValue{};
79 }
80
81 // Checks for key and returns true if found
82 bool HasKey(const nostd::string_view key) const noexcept
83 {
84 return !nostd::holds_alternative<nostd::monostate>(GetValue(key));
85 }
86
87 bool operator==(const Context &other) const noexcept { return (head_ == other.head_); }
88
89 private:
90 // A linked list to contain the keys and values of this context node
91 class DataList
92 {
93 public:
94 char *key_;
95
96 nostd::shared_ptr<DataList> next_;
97
98 size_t key_length_;
99
100 ContextValue value_;
101
102 DataList() { next_ = nullptr; }
103
104 // Builds a data list off of a key and value iterable and returns the head
105 template <class T>
106 DataList(const T &keys_and_vals) : key_{nullptr}, next_(nostd::shared_ptr<DataList>{nullptr})
107 {
108 bool first = true;
109 auto *node = this;
110 for (auto &iter : keys_and_vals)
111 {
112 if (first)
113 {
114 *node = DataList(iter.first, iter.second);
115 first = false;
116 }
117 else
118 {
119 node->next_ = nostd::shared_ptr<DataList>(new DataList(iter.first, iter.second));
120 node = node->next_.get();
121 }
122 }
123 }
124
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)
128 {
129 key_ = new char[key.size()];
130 key_length_ = key.size();
131 memcpy(key_, key.data(), key.size() * sizeof(char));
132 value_ = value;
133 next_ = nostd::shared_ptr<DataList>{nullptr};
134 }
135
136 DataList &operator=(DataList &&other) noexcept
137 {
138 key_length_ = other.key_length_;
139 value_ = std::move(other.value_);
140 next_ = std::move(other.next_);
141
142 key_ = other.key_;
143 other.key_ = nullptr;
144
145 return *this;
146 }
147
148 ~DataList()
149 {
150 if (key_ != nullptr)
151 {
152 delete[] key_;
153 }
154 }
155 };
156
157 // Head of the list which holds the keys and values of this context
158 nostd::shared_ptr<DataList> head_;
159 };
160 } // namespace context
161 OPENTELEMETRY_END_NAMESPACE