Skip to content

Commit faccac5

Browse files
[fix]: custom hash and equality for attribute processor
1 parent 4193b21 commit faccac5

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,49 @@ namespace sdk
1818
{
1919
namespace metrics
2020
{
21+
2122
using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap;
2223

24+
/**
25+
* Hash and equality for nostd::string_view, enabling safe use in unordered_map
26+
* without requiring null termination. Supports heterogeneous lookup with
27+
* std::string and std::string_view as well.
28+
*/
29+
struct StringViewHash
30+
{
31+
using is_transparent = void;
32+
std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept
33+
{
34+
return std::hash<std::string_view>{}(
35+
std::string_view{sv.data(), sv.size()});
36+
}
37+
};
38+
39+
struct StringViewEqual
40+
{
41+
using is_transparent = void;
42+
bool operator()(opentelemetry::nostd::string_view lhs,
43+
opentelemetry::nostd::string_view rhs) const noexcept
44+
{
45+
return lhs.size() == rhs.size() &&
46+
std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
47+
}
48+
49+
bool operator()(const std::string &lhs,
50+
opentelemetry::nostd::string_view rhs) const noexcept
51+
{
52+
return lhs.size() == rhs.size() &&
53+
std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
54+
}
55+
56+
bool operator()(opentelemetry::nostd::string_view lhs,
57+
const std::string &rhs) const noexcept
58+
{
59+
return rhs.size() == lhs.size() &&
60+
std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0;
61+
}
62+
};
63+
2364
/**
2465
* The AttributesProcessor is responsible for customizing which
2566
* attribute(s) are to be reported as metrics dimension(s).
@@ -65,12 +106,12 @@ class DefaultAttributesProcessor : public AttributesProcessor
65106
class FilteringAttributesProcessor : public AttributesProcessor
66107
{
67108
public:
68-
FilteringAttributesProcessor(std::unordered_map<std::string, bool> &&allowed_attribute_keys = {})
109+
FilteringAttributesProcessor(std::unordered_map<std::string, bool, StringViewHash, StringViewEqual> &&allowed_attribute_keys = {})
69110
: allowed_attribute_keys_(std::move(allowed_attribute_keys))
70111
{}
71112

72113
FilteringAttributesProcessor(
73-
const std::unordered_map<std::string, bool> &allowed_attribute_keys = {})
114+
const std::unordered_map<std::string, bool, StringViewHash, StringViewEqual> &allowed_attribute_keys = {})
74115
: allowed_attribute_keys_(allowed_attribute_keys)
75116
{}
76117

@@ -80,7 +121,7 @@ class FilteringAttributesProcessor : public AttributesProcessor
80121
MetricAttributes result;
81122
attributes.ForEachKeyValue(
82123
[&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
83-
if (allowed_attribute_keys_.find(std::string(key)) != allowed_attribute_keys_.end())
124+
if (allowed_attribute_keys_.find(key) != allowed_attribute_keys_.end())
84125
{
85126
result.SetAttribute(key, value);
86127
return true;
@@ -94,11 +135,11 @@ class FilteringAttributesProcessor : public AttributesProcessor
94135

95136
bool isPresent(nostd::string_view key) const noexcept override
96137
{
97-
return (allowed_attribute_keys_.find(std::string(key)) != allowed_attribute_keys_.end());
138+
return (allowed_attribute_keys_.find(key) != allowed_attribute_keys_.end());
98139
}
99140

100141
private:
101-
std::unordered_map<std::string, bool> allowed_attribute_keys_;
142+
std::unordered_map<std::string, bool, StringViewHash, StringViewEqual> allowed_attribute_keys_;
102143
};
103144

104145
/**
@@ -109,12 +150,12 @@ class FilteringAttributesProcessor : public AttributesProcessor
109150
class FilteringExcludeAttributesProcessor : public AttributesProcessor
110151
{
111152
public:
112-
FilteringExcludeAttributesProcessor(std::unordered_map<std::string, bool> &&exclude_list = {})
153+
FilteringExcludeAttributesProcessor(std::unordered_map<std::string, bool, StringViewHash, StringViewEqual> &&exclude_list = {})
113154
: exclude_list_(std::move(exclude_list))
114155
{}
115156

116157
FilteringExcludeAttributesProcessor(
117-
const std::unordered_map<std::string, bool> &exclude_list = {})
158+
const std::unordered_map<std::string, bool, StringViewHash, StringViewEqual> &exclude_list = {})
118159
: exclude_list_(exclude_list)
119160
{}
120161

@@ -124,7 +165,7 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor
124165
MetricAttributes result;
125166
attributes.ForEachKeyValue(
126167
[&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
127-
if (exclude_list_.find(std::string(key)) == exclude_list_.end())
168+
if (exclude_list_.find(key) == exclude_list_.end())
128169
{
129170
result.SetAttribute(key, value);
130171
return true;
@@ -138,11 +179,11 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor
138179

139180
bool isPresent(nostd::string_view key) const noexcept override
140181
{
141-
return (exclude_list_.find(std::string(key)) == exclude_list_.end());
182+
return (exclude_list_.find(key) == exclude_list_.end());
142183
}
143184

144185
private:
145-
std::unordered_map<std::string, bool> exclude_list_;
186+
std::unordered_map<std::string, bool, StringViewHash, StringViewEqual> exclude_list_;
146187
};
147188

148189
} // namespace metrics

0 commit comments

Comments
 (0)