From faccac5df556b5916dae649c560d57519180e99e Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Mon, 15 Sep 2025 22:53:18 +0530 Subject: [PATCH 01/18] [fix]: custom hash and equality for attribute processor --- .../sdk/metrics/view/attributes_processor.h | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 7b320d8d6a..f9d82c8521 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -18,8 +18,49 @@ namespace sdk { namespace metrics { + using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; +/** + * Hash and equality for nostd::string_view, enabling safe use in unordered_map + * without requiring null termination. Supports heterogeneous lookup with + * std::string and std::string_view as well. + */ +struct StringViewHash +{ + using is_transparent = void; + std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept + { + return std::hash{}( + std::string_view{sv.data(), sv.size()}); + } +}; + +struct StringViewEqual +{ + using is_transparent = void; + bool operator()(opentelemetry::nostd::string_view lhs, + opentelemetry::nostd::string_view rhs) const noexcept + { + return lhs.size() == rhs.size() && + std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; + } + + bool operator()(const std::string &lhs, + opentelemetry::nostd::string_view rhs) const noexcept + { + return lhs.size() == rhs.size() && + std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; + } + + bool operator()(opentelemetry::nostd::string_view lhs, + const std::string &rhs) const noexcept + { + return rhs.size() == lhs.size() && + std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0; + } +}; + /** * The AttributesProcessor is responsible for customizing which * attribute(s) are to be reported as metrics dimension(s). @@ -65,12 +106,12 @@ class DefaultAttributesProcessor : public AttributesProcessor class FilteringAttributesProcessor : public AttributesProcessor { public: - FilteringAttributesProcessor(std::unordered_map &&allowed_attribute_keys = {}) + FilteringAttributesProcessor(std::unordered_map &&allowed_attribute_keys = {}) : allowed_attribute_keys_(std::move(allowed_attribute_keys)) {} FilteringAttributesProcessor( - const std::unordered_map &allowed_attribute_keys = {}) + const std::unordered_map &allowed_attribute_keys = {}) : allowed_attribute_keys_(allowed_attribute_keys) {} @@ -80,7 +121,7 @@ class FilteringAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (allowed_attribute_keys_.find(std::string(key)) != allowed_attribute_keys_.end()) + if (allowed_attribute_keys_.find(key) != allowed_attribute_keys_.end()) { result.SetAttribute(key, value); return true; @@ -94,11 +135,11 @@ class FilteringAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (allowed_attribute_keys_.find(std::string(key)) != allowed_attribute_keys_.end()); + return (allowed_attribute_keys_.find(key) != allowed_attribute_keys_.end()); } private: - std::unordered_map allowed_attribute_keys_; + std::unordered_map allowed_attribute_keys_; }; /** @@ -109,12 +150,12 @@ class FilteringAttributesProcessor : public AttributesProcessor class FilteringExcludeAttributesProcessor : public AttributesProcessor { public: - FilteringExcludeAttributesProcessor(std::unordered_map &&exclude_list = {}) + FilteringExcludeAttributesProcessor(std::unordered_map &&exclude_list = {}) : exclude_list_(std::move(exclude_list)) {} FilteringExcludeAttributesProcessor( - const std::unordered_map &exclude_list = {}) + const std::unordered_map &exclude_list = {}) : exclude_list_(exclude_list) {} @@ -124,7 +165,7 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (exclude_list_.find(std::string(key)) == exclude_list_.end()) + if (exclude_list_.find(key) == exclude_list_.end()) { result.SetAttribute(key, value); return true; @@ -138,11 +179,11 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (exclude_list_.find(std::string(key)) == exclude_list_.end()); + return (exclude_list_.find(key) == exclude_list_.end()); } private: - std::unordered_map exclude_list_; + std::unordered_map exclude_list_; }; } // namespace metrics From 844f1a2d3face62f96fede4af765da50941ffd38 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 16 Sep 2025 08:44:08 +0530 Subject: [PATCH 02/18] StringViewHash Fix --- .../sdk/metrics/view/attributes_processor.h | 78 ++++++++++++------- sdk/test/metrics/attributes_processor_test.cc | 26 ++++--- sdk/test/metrics/sum_aggregation_test.cc | 16 +++- 3 files changed, 80 insertions(+), 40 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index f9d82c8521..e5e880b112 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -23,44 +23,65 @@ using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMa /** * Hash and equality for nostd::string_view, enabling safe use in unordered_map - * without requiring null termination. Supports heterogeneous lookup with - * std::string and std::string_view as well. + * without requiring null termination. */ struct StringViewHash { using is_transparent = void; + + std::size_t operator()(const std::string &s) const noexcept + { + return std::hash{}(s); + } + std::size_t operator()(std::string_view sv) const noexcept + { + return std::hash{}(sv); + } std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { - return std::hash{}( - std::string_view{sv.data(), sv.size()}); + return std::hash{}(std::string_view{sv.data(), sv.size()}); } }; struct StringViewEqual { using is_transparent = void; - bool operator()(opentelemetry::nostd::string_view lhs, - opentelemetry::nostd::string_view rhs) const noexcept + + bool operator()(const std::string &lhs, const std::string &rhs) const noexcept { - return lhs.size() == rhs.size() && - std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; + return lhs == rhs; } - - bool operator()(const std::string &lhs, - opentelemetry::nostd::string_view rhs) const noexcept + bool operator()(const std::string &lhs, std::string_view rhs) const noexcept { - return lhs.size() == rhs.size() && - std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; + return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } - - bool operator()(opentelemetry::nostd::string_view lhs, - const std::string &rhs) const noexcept + bool operator()(std::string_view lhs, const std::string &rhs) const noexcept { - return rhs.size() == lhs.size() && - std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0; + return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; + } + bool operator()(opentelemetry::nostd::string_view lhs, const std::string &rhs) const noexcept + { + return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } }; +/** + * Cross-platform heterogeneous lookup wrapper. + * Falls back to std::string construction on libc++ (macOS), + * but uses direct lookup on libstdc++ (Linux). + */ +template +auto find_hetero(Map &map, Key &&key) +{ +#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_HAS_UNORDERED_MAP_TRANSPARENT_LOOKUP) + // libc++ (macOS) does not yet support heterogeneous lookup in unordered_map + return map.find(std::string(key)); +#else + // libstdc++ (Linux, GCC/Clang) supports it + return map.find(std::forward(key)); +#endif +} + /** * The AttributesProcessor is responsible for customizing which * attribute(s) are to be reported as metrics dimension(s). @@ -106,12 +127,15 @@ class DefaultAttributesProcessor : public AttributesProcessor class FilteringAttributesProcessor : public AttributesProcessor { public: - FilteringAttributesProcessor(std::unordered_map &&allowed_attribute_keys = {}) + FilteringAttributesProcessor( + std::unordered_map + &&allowed_attribute_keys = {}) : allowed_attribute_keys_(std::move(allowed_attribute_keys)) {} FilteringAttributesProcessor( - const std::unordered_map &allowed_attribute_keys = {}) + const std::unordered_map + &allowed_attribute_keys = {}) : allowed_attribute_keys_(allowed_attribute_keys) {} @@ -121,7 +145,7 @@ class FilteringAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (allowed_attribute_keys_.find(key) != allowed_attribute_keys_.end()) + if (find_hetero(allowed_attribute_keys_, key) != allowed_attribute_keys_.end()) { result.SetAttribute(key, value); return true; @@ -135,7 +159,7 @@ class FilteringAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (allowed_attribute_keys_.find(key) != allowed_attribute_keys_.end()); + return (find_hetero(allowed_attribute_keys_, key) != allowed_attribute_keys_.end()); } private: @@ -150,12 +174,14 @@ class FilteringAttributesProcessor : public AttributesProcessor class FilteringExcludeAttributesProcessor : public AttributesProcessor { public: - FilteringExcludeAttributesProcessor(std::unordered_map &&exclude_list = {}) + FilteringExcludeAttributesProcessor( + std::unordered_map &&exclude_list = {}) : exclude_list_(std::move(exclude_list)) {} FilteringExcludeAttributesProcessor( - const std::unordered_map &exclude_list = {}) + const std::unordered_map &exclude_list = + {}) : exclude_list_(exclude_list) {} @@ -165,7 +191,7 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (exclude_list_.find(key) == exclude_list_.end()) + if (find_hetero(exclude_list_, key) == exclude_list_.end()) { result.SetAttribute(key, value); return true; @@ -179,7 +205,7 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (exclude_list_.find(key) == exclude_list_.end()); + return (find_hetero(exclude_list_, key) == exclude_list_.end()); } private: diff --git a/sdk/test/metrics/attributes_processor_test.cc b/sdk/test/metrics/attributes_processor_test.cc index 8de97cc6df..ea36e7eebf 100644 --- a/sdk/test/metrics/attributes_processor_test.cc +++ b/sdk/test/metrics/attributes_processor_test.cc @@ -17,9 +17,10 @@ using namespace opentelemetry::sdk::common; TEST(AttributesProcessor, FilteringAttributesProcessor) { - const int kNumFilterAttributes = 3; - std::unordered_map filter = { - {"attr2", true}, {"attr4", true}, {"attr6", true}}; + const int kNumFilterAttributes = 3; + std::unordered_map + filter = {{"attr2", true}, {"attr4", true}, {"attr6", true}}; const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; @@ -38,9 +39,11 @@ TEST(AttributesProcessor, FilteringAttributesProcessor) TEST(AttributesProcessor, FilteringAllAttributesProcessor) { - const int kNumFilterAttributes = 0; - std::unordered_map filter = {}; - const int kNumAttributes = 6; + const int kNumFilterAttributes = 0; + std::unordered_map + filter = {}; + const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; std::map attributes = {{keys[0], values[0]}, {keys[1], values[1]}, @@ -54,8 +57,9 @@ TEST(AttributesProcessor, FilteringAllAttributesProcessor) TEST(AttributesProcessor, FilteringExcludeAttributesProcessor) { - std::unordered_map filter = { - {"attr2", true}, {"attr4", true}, {"attr6", true}}; + std::unordered_map + filter = {{"attr2", true}, {"attr4", true}, {"attr6", true}}; const int kNumAttributes = 7; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6", "attr7"}; @@ -76,8 +80,10 @@ TEST(AttributesProcessor, FilteringExcludeAttributesProcessor) TEST(AttributesProcessor, FilteringExcludeAllAttributesProcessor) { - std::unordered_map filter = {}; - const int kNumAttributes = 6; + std::unordered_map + filter = {}; + const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; std::map attributes = {{keys[0], values[0]}, {keys[1], values[1]}, diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index 7722db1afa..38339b9ba5 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -100,7 +100,9 @@ TEST(HistogramToSumFilterAttributes, Double) std::string instrument_name = "histogram1"; std::string instrument_desc = "histogram metrics"; - std::unordered_map allowedattr; + std::unordered_map + allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; @@ -154,7 +156,9 @@ TEST(HistogramToSumFilterAttributesWithCardinalityLimit, Double) std::string instrument_desc = "histogram metrics"; size_t cardinality_limit = 10000; - std::unordered_map allowedattr; + std::unordered_map + allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; @@ -281,7 +285,9 @@ TEST(CounterToSumFilterAttributes, Double) std::string instrument_name = "counter1"; std::string instrument_desc = "counter metrics"; - std::unordered_map allowedattr; + std::unordered_map + allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; @@ -335,7 +341,9 @@ TEST(CounterToSumFilterAttributesWithCardinalityLimit, Double) std::string instrument_desc = "counter metrics"; size_t cardinality_limit = 10000; - std::unordered_map allowedattr; + std::unordered_map + allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; From 7a05e7f5c934231e50de2e1e5e5abf1aba3fb51f Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 16 Sep 2025 08:47:30 +0530 Subject: [PATCH 03/18] macos copy fix --- .../opentelemetry/sdk/metrics/view/attributes_processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index e5e880b112..336c14888d 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -73,7 +73,7 @@ struct StringViewEqual template auto find_hetero(Map &map, Key &&key) { -#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_HAS_UNORDERED_MAP_TRANSPARENT_LOOKUP) +#if defined(_LIBCPP_VERSION) // libc++ (macOS) does not yet support heterogeneous lookup in unordered_map return map.find(std::string(key)); #else From f199a59586be0a65c05b5b9502f5d8f84731a727 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 16 Sep 2025 09:14:44 +0530 Subject: [PATCH 04/18] string_view fix --- .../sdk/metrics/view/attributes_processor.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 336c14888d..e73f6f23cf 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -33,13 +33,13 @@ struct StringViewHash { return std::hash{}(s); } - std::size_t operator()(std::string_view sv) const noexcept + std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { - return std::hash{}(sv); + return std::hash{}(sv); } std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { - return std::hash{}(std::string_view{sv.data(), sv.size()}); + return std::hash{}(opentelemetry::nostd::string_view{sv.data(), sv.size()}); } }; @@ -51,11 +51,11 @@ struct StringViewEqual { return lhs == rhs; } - bool operator()(const std::string &lhs, std::string_view rhs) const noexcept + bool operator()(const std::string &lhs, opentelemetry::nostd::string_view rhs) const noexcept { return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } - bool operator()(std::string_view lhs, const std::string &rhs) const noexcept + bool operator()(opentelemetry::nostd::string_view lhs, const std::string &rhs) const noexcept { return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } From a38b2d7db4131a0d9fad049fd885f4762443a79f Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 16 Sep 2025 09:29:14 +0530 Subject: [PATCH 05/18] more fixes --- .../sdk/metrics/view/attributes_processor.h | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index e73f6f23cf..2804a9614f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -33,13 +33,11 @@ struct StringViewHash { return std::hash{}(s); } + std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { - return std::hash{}(sv); - } - std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept - { - return std::hash{}(opentelemetry::nostd::string_view{sv.data(), sv.size()}); + // hash the data without assuming null-termination + return std::hash{}(std::string{sv.data(), sv.size()}); } }; @@ -51,15 +49,19 @@ struct StringViewEqual { return lhs == rhs; } + bool operator()(const std::string &lhs, opentelemetry::nostd::string_view rhs) const noexcept { return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } + bool operator()(opentelemetry::nostd::string_view lhs, const std::string &rhs) const noexcept { return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } - bool operator()(opentelemetry::nostd::string_view lhs, const std::string &rhs) const noexcept + + bool operator()(opentelemetry::nostd::string_view lhs, + opentelemetry::nostd::string_view rhs) const noexcept { return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; } @@ -70,15 +72,16 @@ struct StringViewEqual * Falls back to std::string construction on libc++ (macOS), * but uses direct lookup on libstdc++ (Linux). */ -template -auto find_hetero(Map &map, Key &&key) +inline auto find_hetero( + const std::unordered_map &map, + opentelemetry::nostd::string_view key) { #if defined(_LIBCPP_VERSION) - // libc++ (macOS) does not yet support heterogeneous lookup in unordered_map + // libc++ (macOS) does not yet support heterogeneous lookup return map.find(std::string(key)); #else - // libstdc++ (Linux, GCC/Clang) supports it - return map.find(std::forward(key)); + // libstdc++ supports heterogeneous lookup directly + return map.find(key); #endif } From 121bfcf3881df789558d19c46a82505ccdf47264 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 16 Sep 2025 09:44:40 +0530 Subject: [PATCH 06/18] some more fix --- .../sdk/metrics/view/attributes_processor.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 2804a9614f..e50d9c1c79 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -85,6 +86,16 @@ inline auto find_hetero( #endif } +inline auto find_hetero(std::unordered_map &map, + opentelemetry::nostd::string_view key) +{ +#if defined(_LIBCPP_VERSION) + return map.find(std::string(key)); +#else + return map.find(key); +#endif +} + /** * The AttributesProcessor is responsible for customizing which * attribute(s) are to be reported as metrics dimension(s). From 53012d24069a25f02d2415f02630c53d5746fc82 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Wed, 17 Sep 2025 00:56:19 +0530 Subject: [PATCH 07/18] cppver fix --- .../sdk/metrics/view/attributes_processor.h | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index e50d9c1c79..cab99e7b10 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -28,7 +28,10 @@ using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMa */ struct StringViewHash { +#if __cplusplus >= 202002L + // enable heterogenous lookup in C++20+ using is_transparent = void; +#endif std::size_t operator()(const std::string &s) const noexcept { @@ -37,14 +40,21 @@ struct StringViewHash std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { - // hash the data without assuming null-termination +#if __cplusplus >= 202002L + return std::hash{}( + opentelemetry::nostd::string_view{sv.data(), sv.size()}); +#else + // pre-C++20 fallback: materialize to std::string return std::hash{}(std::string{sv.data(), sv.size()}); +#endif } }; struct StringViewEqual { +#if __cplusplus >= 202002L using is_transparent = void; +#endif bool operator()(const std::string &lhs, const std::string &rhs) const noexcept { @@ -70,18 +80,16 @@ struct StringViewEqual /** * Cross-platform heterogeneous lookup wrapper. - * Falls back to std::string construction on libc++ (macOS), + * Falls back to std::string construction on libc++ (macOS) and pre-c++20, * but uses direct lookup on libstdc++ (Linux). */ inline auto find_hetero( const std::unordered_map &map, opentelemetry::nostd::string_view key) { -#if defined(_LIBCPP_VERSION) - // libc++ (macOS) does not yet support heterogeneous lookup +#if defined(_LIBCPP_VERSION) || __cplusplus < 202002L return map.find(std::string(key)); #else - // libstdc++ supports heterogeneous lookup directly return map.find(key); #endif } @@ -89,7 +97,7 @@ inline auto find_hetero( inline auto find_hetero(std::unordered_map &map, opentelemetry::nostd::string_view key) { -#if defined(_LIBCPP_VERSION) +#if defined(_LIBCPP_VERSION) || __cplusplus < 202002L return map.find(std::string(key)); #else return map.find(key); From 0a81688db100ea1ce1f9c333e5adb493072f8f4c Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Sat, 20 Sep 2025 01:23:00 +0530 Subject: [PATCH 08/18] hash fix --- .../sdk/metrics/view/attributes_processor.h | 124 ++++++++++++------ 1 file changed, 83 insertions(+), 41 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index cab99e7b10..090c3bfe1d 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -22,59 +22,109 @@ namespace metrics using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; +/** + * Generic FNV hash implementation + */ + +template +struct fnv_magic_prime_number +{ + static constexpr const Ty value = 0x01000193U; +}; + +template +struct fnv_magic_prime_number +{ + static constexpr const Ty value = 0x100000001b3ULL; +}; + +template +struct fnv_magic_offset_basis +{ + static constexpr const Ty value = 0x811C9DC5U; + + static constexpr Ty fix(Ty hval) { return hval; } +}; + +template +struct fnv_magic_offset_basis +{ + static constexpr const Ty value = 0xCBF29CE484222325ULL; + + static constexpr Ty fix(Ty hval) { return hval ^ (hval >> 32); } +}; + +template +Ty fnv_n_buf(const void *buf, size_t len, Ty hval = fnv_magic_offset_basis::value) +{ + const unsigned char *bp = reinterpret_cast(buf); + const unsigned char *be = bp + len; + Ty mn = fnv_magic_prime_number::value; + + while (bp < be) + { + hval *= mn; + hval ^= static_cast(*bp++); + } + + return fnv_magic_offset_basis::fix(hval); +} + +template +Ty fnv_n_buf_a(const void *buf, size_t len, Ty hval = fnv_magic_offset_basis::value) +{ + const unsigned char *bp = reinterpret_cast(buf); + const unsigned char *be = bp + len; + Ty mn = fnv_magic_prime_number::value; + + while (bp < be) + { + hval ^= static_cast(*bp++); + hval *= mn; + } + + return fnv_magic_offset_basis::fix(hval); +} + /** * Hash and equality for nostd::string_view, enabling safe use in unordered_map * without requiring null termination. */ + struct StringViewHash { -#if __cplusplus >= 202002L - // enable heterogenous lookup in C++20+ +#if defined(OPENTELEMETRY_STL_VERSION) +# if OPENTELEMETRY_STL_VERSION >= 2020 using is_transparent = void; +# endif #endif std::size_t operator()(const std::string &s) const noexcept { - return std::hash{}(s); + return fnv_n_buf_a(s.data(), s.size()); } std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { -#if __cplusplus >= 202002L - return std::hash{}( - opentelemetry::nostd::string_view{sv.data(), sv.size()}); -#else - // pre-C++20 fallback: materialize to std::string - return std::hash{}(std::string{sv.data(), sv.size()}); -#endif + return fnv_n_buf_a(sv.data(), sv.size()); } }; struct StringViewEqual { -#if __cplusplus >= 202002L +#if defined(OPENTELEMETRY_STL_VERSION) +# if OPENTELEMETRY_STL_VERSION >= 2020 using is_transparent = void; +# endif #endif - bool operator()(const std::string &lhs, const std::string &rhs) const noexcept - { - return lhs == rhs; - } - - bool operator()(const std::string &lhs, opentelemetry::nostd::string_view rhs) const noexcept - { - return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; - } - - bool operator()(opentelemetry::nostd::string_view lhs, const std::string &rhs) const noexcept + template + bool operator()(const Lhs &lhs, const Rhs &rhs) const noexcept { - return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; - } + opentelemetry::nostd::string_view lsv(lhs.data(), lhs.size()); + opentelemetry::nostd::string_view rsv(rhs.data(), rhs.size()); - bool operator()(opentelemetry::nostd::string_view lhs, - opentelemetry::nostd::string_view rhs) const noexcept - { - return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; + return lsv.size() == rsv.size() && std::memcmp(lsv.data(), rsv.data(), lsv.size()) == 0; } }; @@ -83,23 +133,15 @@ struct StringViewEqual * Falls back to std::string construction on libc++ (macOS) and pre-c++20, * but uses direct lookup on libstdc++ (Linux). */ -inline auto find_hetero( - const std::unordered_map &map, - opentelemetry::nostd::string_view key) -{ -#if defined(_LIBCPP_VERSION) || __cplusplus < 202002L - return map.find(std::string(key)); -#else - return map.find(key); -#endif -} -inline auto find_hetero(std::unordered_map &map, - opentelemetry::nostd::string_view key) +template +inline auto find_hetero(MapType &&map, opentelemetry::nostd::string_view key) { -#if defined(_LIBCPP_VERSION) || __cplusplus < 202002L +#if defined(_LIBCPP_VERSION) || \ + (defined(OPENTELEMETRY_STL_VERSION) && OPENTELEMETRY_STL_VERSION < 2020) return map.find(std::string(key)); #else + // libstdc++ + C++20: heterogeneous lookup works return map.find(key); #endif } From 98543fc9bc1ac9eaf48cb872f46fd1dc2d53799b Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Sat, 20 Sep 2025 01:56:09 +0530 Subject: [PATCH 09/18] fix --- .../opentelemetry/sdk/metrics/view/attributes_processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 090c3bfe1d..4cbfe65625 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -138,7 +138,7 @@ template inline auto find_hetero(MapType &&map, opentelemetry::nostd::string_view key) { #if defined(_LIBCPP_VERSION) || \ - (defined(OPENTELEMETRY_STL_VERSION) && OPENTELEMETRY_STL_VERSION < 2020) + (!defined(OPENTELEMETRY_STL_VERSION) || OPENTELEMETRY_STL_VERSION < 2020) return map.find(std::string(key)); #else // libstdc++ + C++20: heterogeneous lookup works From 63b233860e85843cf1af275adc257749cb5f2488 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Sun, 21 Sep 2025 00:46:44 +0530 Subject: [PATCH 10/18] code style fix --- .../sdk/metrics/view/attributes_processor.h | 65 +++++++++---------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 4cbfe65625..cc92f4e4c6 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -26,64 +26,55 @@ using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMa * Generic FNV hash implementation */ -template -struct fnv_magic_prime_number -{ - static constexpr const Ty value = 0x01000193U; -}; +template +struct FnvPrime; template -struct fnv_magic_prime_number +struct FnvPrime { - static constexpr const Ty value = 0x100000001b3ULL; + static constexpr Ty value = static_cast(0x01000193U); }; -template -struct fnv_magic_offset_basis +template +struct FnvPrime { - static constexpr const Ty value = 0x811C9DC5U; - - static constexpr Ty fix(Ty hval) { return hval; } + static constexpr Ty value = static_cast(0x100000001b3ULL); }; +// FNV offset basis values +template +struct FnvOffset; + template -struct fnv_magic_offset_basis +struct FnvOffset { - static constexpr const Ty value = 0xCBF29CE484222325ULL; + static constexpr Ty value = static_cast(0x811C9DC5U); - static constexpr Ty fix(Ty hval) { return hval ^ (hval >> 32); } + static constexpr Ty Fix(Ty hval) noexcept { return hval; } }; template -Ty fnv_n_buf(const void *buf, size_t len, Ty hval = fnv_magic_offset_basis::value) +struct FnvOffset { - const unsigned char *bp = reinterpret_cast(buf); - const unsigned char *be = bp + len; - Ty mn = fnv_magic_prime_number::value; + static constexpr Ty value = static_cast(0xCBF29CE484222325ULL); - while (bp < be) - { - hval *= mn; - hval ^= static_cast(*bp++); - } - - return fnv_magic_offset_basis::fix(hval); -} + static constexpr Ty Fix(Ty hval) noexcept { return hval ^ (hval >> 32); } +}; +// FNV-1a template -Ty fnv_n_buf_a(const void *buf, size_t len, Ty hval = fnv_magic_offset_basis::value) +inline Ty Fnv1a(const void *buf, size_t len, Ty hval = FnvOffset::value) noexcept { const unsigned char *bp = reinterpret_cast(buf); const unsigned char *be = bp + len; - Ty mn = fnv_magic_prime_number::value; + Ty prime = FnvPrime::value; while (bp < be) { hval ^= static_cast(*bp++); - hval *= mn; + hval *= prime; } - - return fnv_magic_offset_basis::fix(hval); + return FnvOffset::Fix(hval); } /** @@ -101,12 +92,12 @@ struct StringViewHash std::size_t operator()(const std::string &s) const noexcept { - return fnv_n_buf_a(s.data(), s.size()); + return Fnv1a(s.data(), s.size()); } std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept { - return fnv_n_buf_a(sv.data(), sv.size()); + return Fnv1a(sv.data(), sv.size()); } }; @@ -121,8 +112,10 @@ struct StringViewEqual template bool operator()(const Lhs &lhs, const Rhs &rhs) const noexcept { - opentelemetry::nostd::string_view lsv(lhs.data(), lhs.size()); - opentelemetry::nostd::string_view rsv(rhs.data(), rhs.size()); + opentelemetry::nostd::string_view lsv(opentelemetry::nostd::data(lhs), + opentelemetry::nostd::size(lhs)); + opentelemetry::nostd::string_view rsv(opentelemetry::nostd::data(rhs), + opentelemetry::nostd::size(rhs)); return lsv.size() == rsv.size() && std::memcmp(lsv.data(), rsv.data(), lsv.size()) == 0; } From e5ad0c927eca8ebc938eb14894757cf0d527abcc Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Mon, 22 Sep 2025 10:27:15 +0530 Subject: [PATCH 11/18] small fix --- .../opentelemetry/sdk/metrics/view/attributes_processor.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index cc92f4e4c6..31588d54fd 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -112,10 +112,8 @@ struct StringViewEqual template bool operator()(const Lhs &lhs, const Rhs &rhs) const noexcept { - opentelemetry::nostd::string_view lsv(opentelemetry::nostd::data(lhs), - opentelemetry::nostd::size(lhs)); - opentelemetry::nostd::string_view rsv(opentelemetry::nostd::data(rhs), - opentelemetry::nostd::size(rhs)); + opentelemetry::nostd::string_view lsv(lhs); + opentelemetry::nostd::string_view rsv(rhs); return lsv.size() == rsv.size() && std::memcmp(lsv.data(), rsv.data(), lsv.size()) == 0; } From a0a5540095b400b1c777abbf89472565117e71fa Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 23 Sep 2025 10:47:12 +0530 Subject: [PATCH 12/18] header fix --- .../sdk/common/custom_hash_equality.h | 157 +++++++++++++++++ .../sdk/metrics/view/attributes_processor.h | 163 ++++-------------- .../metrics/attributes_processor_benchmark.cc | 1 + sdk/test/metrics/attributes_processor_test.cc | 1 - sdk/test/metrics/sum_aggregation_test.cc | 17 +- 5 files changed, 201 insertions(+), 138 deletions(-) create mode 100644 sdk/include/opentelemetry/sdk/common/custom_hash_equality.h diff --git a/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h b/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h new file mode 100644 index 0000000000..4671b36cba --- /dev/null +++ b/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h @@ -0,0 +1,157 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include + +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +/** + * + * FNV Hashing Utilities + * + * Implements FNV-1a hashing algorithm for 32-bit and 64-bit types. + * + * - FNV (Fowler–Noll–Vo) is a simple, fast, and widely used non-cryptographic hash. + * - FNV-1a is the recommended variant because it mixes input bits better. + * - We parameterize by type size (4 = 32-bit, 8 = 64-bit). + */ + +// Forward declaration for FNV prime constants +template +struct FnvPrime; + +// Specialization for 32-bit +template +struct FnvPrime +{ + static constexpr Ty value = static_cast(0x01000193U); +}; + +// Specialization for 64-bit +template +struct FnvPrime +{ + static constexpr Ty value = static_cast(0x100000001b3ULL); +}; + +// Forward declaration for FNV offset basis constants +template +struct FnvOffset; + +// Specialization for 32-bit +template +struct FnvOffset +{ + // 32-bit offset basis + static constexpr Ty value = static_cast(0x811C9DC5U); + + static constexpr Ty Fix(Ty hval) noexcept { return hval; } +}; + +// Specialization for 64-bit +template +struct FnvOffset +{ + // 64-bit offset basis + static constexpr Ty value = static_cast(0xCBF29CE484222325ULL); + + // Fix function: mix upper and lower bits for better distribution + static constexpr Ty Fix(Ty hval) noexcept { return hval ^ (hval >> 32); } +}; + +/** + * FNV-1a hash function + * + * @tparam Ty Hash integer type (std::size_t, uint32_t, uint64_t, etc.) + * @param buf Pointer to the input buffer + * @param len Length of the buffer + * @param hval Starting hash value (defaults to offset basis) + * @return Computed hash + */ +template +inline Ty Fnv1a(const void *buf, size_t len, Ty hval = FnvOffset::value) noexcept +{ + const unsigned char *bp = reinterpret_cast(buf); + const unsigned char *be = bp + len; + Ty prime = FnvPrime::value; + + while (bp < be) + { + hval ^= static_cast(*bp++); + hval *= prime; + } + return FnvOffset::Fix(hval); +} + +/** + * Hash and equality for nostd::string_view, enabling safe use in unordered_map + * without requiring null termination. + */ + +struct StringViewHash +{ +#if defined(OPENTELEMETRY_STL_VERSION) +# if OPENTELEMETRY_STL_VERSION >= 2020 + using is_transparent = void; +# endif +#endif + + std::size_t operator()(const std::string &s) const noexcept + { + return Fnv1a(s.data(), s.size()); + } + + std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept + { + return Fnv1a(sv.data(), sv.size()); + } +}; + +struct StringViewEqual +{ +#if defined(OPENTELEMETRY_STL_VERSION) +# if OPENTELEMETRY_STL_VERSION >= 2020 + using is_transparent = void; +# endif +#endif + + template + bool operator()(const Lhs &lhs, const Rhs &rhs) const noexcept + { + opentelemetry::nostd::string_view lsv(lhs); + opentelemetry::nostd::string_view rsv(rhs); + + return lsv.size() == rsv.size() && std::memcmp(lsv.data(), rsv.data(), lsv.size()) == 0; + } +}; + +/** + * Cross-platform heterogeneous lookup wrapper. + * Falls back to std::string construction on libc++ (macOS) and pre-c++20, + * but uses direct lookup on libstdc++ (Linux). + */ + +template +inline auto find_hetero(MapType &&map, opentelemetry::nostd::string_view key) +{ +#if defined(_LIBCPP_VERSION) || \ + (!defined(OPENTELEMETRY_STL_VERSION) || OPENTELEMETRY_STL_VERSION < 2020) + return map.find(std::string(key)); +#else + // libstdc++ + C++20: heterogeneous lookup works + return map.find(key); +#endif +} +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 31588d54fd..143a2be44b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -11,6 +11,7 @@ #include "opentelemetry/common/attribute_value.h" #include "opentelemetry/common/key_value_iterable.h" #include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/sdk/common/custom_hash_equality.h" #include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/version.h" @@ -22,121 +23,6 @@ namespace metrics using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; -/** - * Generic FNV hash implementation - */ - -template -struct FnvPrime; - -template -struct FnvPrime -{ - static constexpr Ty value = static_cast(0x01000193U); -}; - -template -struct FnvPrime -{ - static constexpr Ty value = static_cast(0x100000001b3ULL); -}; - -// FNV offset basis values -template -struct FnvOffset; - -template -struct FnvOffset -{ - static constexpr Ty value = static_cast(0x811C9DC5U); - - static constexpr Ty Fix(Ty hval) noexcept { return hval; } -}; - -template -struct FnvOffset -{ - static constexpr Ty value = static_cast(0xCBF29CE484222325ULL); - - static constexpr Ty Fix(Ty hval) noexcept { return hval ^ (hval >> 32); } -}; - -// FNV-1a -template -inline Ty Fnv1a(const void *buf, size_t len, Ty hval = FnvOffset::value) noexcept -{ - const unsigned char *bp = reinterpret_cast(buf); - const unsigned char *be = bp + len; - Ty prime = FnvPrime::value; - - while (bp < be) - { - hval ^= static_cast(*bp++); - hval *= prime; - } - return FnvOffset::Fix(hval); -} - -/** - * Hash and equality for nostd::string_view, enabling safe use in unordered_map - * without requiring null termination. - */ - -struct StringViewHash -{ -#if defined(OPENTELEMETRY_STL_VERSION) -# if OPENTELEMETRY_STL_VERSION >= 2020 - using is_transparent = void; -# endif -#endif - - std::size_t operator()(const std::string &s) const noexcept - { - return Fnv1a(s.data(), s.size()); - } - - std::size_t operator()(opentelemetry::nostd::string_view sv) const noexcept - { - return Fnv1a(sv.data(), sv.size()); - } -}; - -struct StringViewEqual -{ -#if defined(OPENTELEMETRY_STL_VERSION) -# if OPENTELEMETRY_STL_VERSION >= 2020 - using is_transparent = void; -# endif -#endif - - template - bool operator()(const Lhs &lhs, const Rhs &rhs) const noexcept - { - opentelemetry::nostd::string_view lsv(lhs); - opentelemetry::nostd::string_view rsv(rhs); - - return lsv.size() == rsv.size() && std::memcmp(lsv.data(), rsv.data(), lsv.size()) == 0; - } -}; - -/** - * Cross-platform heterogeneous lookup wrapper. - * Falls back to std::string construction on libc++ (macOS) and pre-c++20, - * but uses direct lookup on libstdc++ (Linux). - */ - -template -inline auto find_hetero(MapType &&map, opentelemetry::nostd::string_view key) -{ -#if defined(_LIBCPP_VERSION) || \ - (!defined(OPENTELEMETRY_STL_VERSION) || OPENTELEMETRY_STL_VERSION < 2020) - return map.find(std::string(key)); -#else - // libstdc++ + C++20: heterogeneous lookup works - return map.find(key); -#endif -} - /** * The AttributesProcessor is responsible for customizing which * attribute(s) are to be reported as metrics dimension(s). @@ -183,14 +69,18 @@ class FilteringAttributesProcessor : public AttributesProcessor { public: FilteringAttributesProcessor( - std::unordered_map - &&allowed_attribute_keys = {}) + std::unordered_map &&allowed_attribute_keys = {}) : allowed_attribute_keys_(std::move(allowed_attribute_keys)) {} - FilteringAttributesProcessor( - const std::unordered_map - &allowed_attribute_keys = {}) + FilteringAttributesProcessor(const std::unordered_map + &allowed_attribute_keys = {}) : allowed_attribute_keys_(allowed_attribute_keys) {} @@ -200,7 +90,8 @@ class FilteringAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (find_hetero(allowed_attribute_keys_, key) != allowed_attribute_keys_.end()) + if (opentelemetry::sdk::common::find_hetero(allowed_attribute_keys_, key) != + allowed_attribute_keys_.end()) { result.SetAttribute(key, value); return true; @@ -214,11 +105,16 @@ class FilteringAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (find_hetero(allowed_attribute_keys_, key) != allowed_attribute_keys_.end()); + return (opentelemetry::sdk::common::find_hetero(allowed_attribute_keys_, key) != + allowed_attribute_keys_.end()); } private: - std::unordered_map allowed_attribute_keys_; + std::unordered_map + allowed_attribute_keys_; }; /** @@ -230,13 +126,18 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor { public: FilteringExcludeAttributesProcessor( - std::unordered_map &&exclude_list = {}) + std::unordered_map &&exclude_list = {}) : exclude_list_(std::move(exclude_list)) {} FilteringExcludeAttributesProcessor( - const std::unordered_map &exclude_list = - {}) + const std::unordered_map &exclude_list = {}) : exclude_list_(exclude_list) {} @@ -246,7 +147,7 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (find_hetero(exclude_list_, key) == exclude_list_.end()) + if (opentelemetry::sdk::common::find_hetero(exclude_list_, key) == exclude_list_.end()) { result.SetAttribute(key, value); return true; @@ -260,11 +161,15 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (find_hetero(exclude_list_, key) == exclude_list_.end()); + return (opentelemetry::sdk::common::find_hetero(exclude_list_, key) == exclude_list_.end()); } private: - std::unordered_map exclude_list_; + std::unordered_map + exclude_list_; }; } // namespace metrics diff --git a/sdk/test/metrics/attributes_processor_benchmark.cc b/sdk/test/metrics/attributes_processor_benchmark.cc index 02923c5642..a8e6e7590a 100644 --- a/sdk/test/metrics/attributes_processor_benchmark.cc +++ b/sdk/test/metrics/attributes_processor_benchmark.cc @@ -8,6 +8,7 @@ #include #include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/sdk/common/custom_hash_equality.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" using namespace opentelemetry::sdk::metrics; diff --git a/sdk/test/metrics/attributes_processor_test.cc b/sdk/test/metrics/attributes_processor_test.cc index ea36e7eebf..97ee1e40ff 100644 --- a/sdk/test/metrics/attributes_processor_test.cc +++ b/sdk/test/metrics/attributes_processor_test.cc @@ -8,7 +8,6 @@ #include #include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" using namespace opentelemetry::sdk::metrics; diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index 38339b9ba5..3e0f928382 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -19,6 +19,7 @@ #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/variant.h" +#include "opentelemetry/sdk/common/custom_hash_equality.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation_config.h" #include "opentelemetry/sdk/metrics/data/metric_data.h" @@ -100,8 +101,8 @@ TEST(HistogramToSumFilterAttributes, Double) std::string instrument_name = "histogram1"; std::string instrument_desc = "histogram metrics"; - std::unordered_map + std::unordered_map allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ @@ -156,8 +157,8 @@ TEST(HistogramToSumFilterAttributesWithCardinalityLimit, Double) std::string instrument_desc = "histogram metrics"; size_t cardinality_limit = 10000; - std::unordered_map + std::unordered_map allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ @@ -285,8 +286,8 @@ TEST(CounterToSumFilterAttributes, Double) std::string instrument_name = "counter1"; std::string instrument_desc = "counter metrics"; - std::unordered_map + std::unordered_map allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ @@ -341,8 +342,8 @@ TEST(CounterToSumFilterAttributesWithCardinalityLimit, Double) std::string instrument_desc = "counter metrics"; size_t cardinality_limit = 10000; - std::unordered_map + std::unordered_map allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ From ae5eeb9cbca2601b173aff0dfe4a6bbcf7273a64 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 23 Sep 2025 10:54:06 +0530 Subject: [PATCH 13/18] fix in test --- sdk/test/metrics/attributes_processor_test.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk/test/metrics/attributes_processor_test.cc b/sdk/test/metrics/attributes_processor_test.cc index 97ee1e40ff..cc8a833cec 100644 --- a/sdk/test/metrics/attributes_processor_test.cc +++ b/sdk/test/metrics/attributes_processor_test.cc @@ -17,8 +17,8 @@ using namespace opentelemetry::sdk::common; TEST(AttributesProcessor, FilteringAttributesProcessor) { const int kNumFilterAttributes = 3; - std::unordered_map + std::unordered_map filter = {{"attr2", true}, {"attr4", true}, {"attr6", true}}; const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; @@ -39,8 +39,8 @@ TEST(AttributesProcessor, FilteringAttributesProcessor) TEST(AttributesProcessor, FilteringAllAttributesProcessor) { const int kNumFilterAttributes = 0; - std::unordered_map + std::unordered_map filter = {}; const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; @@ -56,8 +56,8 @@ TEST(AttributesProcessor, FilteringAllAttributesProcessor) TEST(AttributesProcessor, FilteringExcludeAttributesProcessor) { - std::unordered_map + std::unordered_map filter = {{"attr2", true}, {"attr4", true}, {"attr6", true}}; const int kNumAttributes = 7; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", @@ -79,8 +79,8 @@ TEST(AttributesProcessor, FilteringExcludeAttributesProcessor) TEST(AttributesProcessor, FilteringExcludeAllAttributesProcessor) { - std::unordered_map + std::unordered_map filter = {}; const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; From 4991c294918376ac5223b8af9de133299a615396 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Tue, 23 Sep 2025 11:18:29 +0530 Subject: [PATCH 14/18] iwyu fix --- sdk/test/metrics/attributes_processor_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/test/metrics/attributes_processor_test.cc b/sdk/test/metrics/attributes_processor_test.cc index cc8a833cec..a084b34234 100644 --- a/sdk/test/metrics/attributes_processor_test.cc +++ b/sdk/test/metrics/attributes_processor_test.cc @@ -8,6 +8,7 @@ #include #include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/sdk/common/custom_hash_equality.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" using namespace opentelemetry::sdk::metrics; From 3e8f5c79f7c9a8049a6f479e638a7bbed26cc532 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Wed, 24 Sep 2025 00:39:11 +0530 Subject: [PATCH 15/18] name and typedef fix --- .../sdk/common/custom_hash_equality.h | 2 +- .../sdk/metrics/view/attributes_processor.h | 67 +++++++------------ sdk/test/metrics/attributes_processor_test.cc | 26 +++---- sdk/test/metrics/sum_aggregation_test.cc | 12 +--- 4 files changed, 39 insertions(+), 68 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h b/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h index 4671b36cba..d1b5555b3a 100644 --- a/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h +++ b/sdk/include/opentelemetry/sdk/common/custom_hash_equality.h @@ -142,7 +142,7 @@ struct StringViewEqual */ template -inline auto find_hetero(MapType &&map, opentelemetry::nostd::string_view key) +inline auto find_heterogeneous(MapType &&map, opentelemetry::nostd::string_view key) { #if defined(_LIBCPP_VERSION) || \ (!defined(OPENTELEMETRY_STL_VERSION) || OPENTELEMETRY_STL_VERSION < 2020) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 143a2be44b..b00687a5c1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -23,6 +23,12 @@ namespace metrics using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; +typedef std::unordered_map + FilterAttributeMap; + /** * The AttributesProcessor is responsible for customizing which * attribute(s) are to be reported as metrics dimension(s). @@ -68,19 +74,11 @@ class DefaultAttributesProcessor : public AttributesProcessor class FilteringAttributesProcessor : public AttributesProcessor { public: - FilteringAttributesProcessor( - std::unordered_map &&allowed_attribute_keys = {}) + FilteringAttributesProcessor(FilterAttributeMap &&allowed_attribute_keys = {}) : allowed_attribute_keys_(std::move(allowed_attribute_keys)) {} - FilteringAttributesProcessor(const std::unordered_map - &allowed_attribute_keys = {}) + FilteringAttributesProcessor(const FilterAttributeMap &allowed_attribute_keys = {}) : allowed_attribute_keys_(allowed_attribute_keys) {} @@ -90,7 +88,7 @@ class FilteringAttributesProcessor : public AttributesProcessor MetricAttributes result; attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (opentelemetry::sdk::common::find_hetero(allowed_attribute_keys_, key) != + if (opentelemetry::sdk::common::find_heterogeneous(allowed_attribute_keys_, key) != allowed_attribute_keys_.end()) { result.SetAttribute(key, value); @@ -105,16 +103,12 @@ class FilteringAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (opentelemetry::sdk::common::find_hetero(allowed_attribute_keys_, key) != + return (opentelemetry::sdk::common::find_heterogeneous(allowed_attribute_keys_, key) != allowed_attribute_keys_.end()); } private: - std::unordered_map - allowed_attribute_keys_; + FilterAttributeMap allowed_attribute_keys_; }; /** @@ -125,19 +119,11 @@ class FilteringAttributesProcessor : public AttributesProcessor class FilteringExcludeAttributesProcessor : public AttributesProcessor { public: - FilteringExcludeAttributesProcessor( - std::unordered_map &&exclude_list = {}) + FilteringExcludeAttributesProcessor(FilterAttributeMap &&exclude_list = {}) : exclude_list_(std::move(exclude_list)) {} - FilteringExcludeAttributesProcessor( - const std::unordered_map &exclude_list = {}) + FilteringExcludeAttributesProcessor(const FilterAttributeMap &exclude_list = {}) : exclude_list_(exclude_list) {} @@ -145,15 +131,15 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor const opentelemetry::common::KeyValueIterable &attributes) const noexcept override { MetricAttributes result; - attributes.ForEachKeyValue( - [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (opentelemetry::sdk::common::find_hetero(exclude_list_, key) == exclude_list_.end()) - { - result.SetAttribute(key, value); - return true; - } - return true; - }); + attributes.ForEachKeyValue([&](nostd::string_view key, + opentelemetry::common::AttributeValue value) noexcept { + if (opentelemetry::sdk::common::find_heterogeneous(exclude_list_, key) == exclude_list_.end()) + { + result.SetAttribute(key, value); + return true; + } + return true; + }); result.UpdateHash(); return result; @@ -161,15 +147,12 @@ class FilteringExcludeAttributesProcessor : public AttributesProcessor bool isPresent(nostd::string_view key) const noexcept override { - return (opentelemetry::sdk::common::find_hetero(exclude_list_, key) == exclude_list_.end()); + return (opentelemetry::sdk::common::find_heterogeneous(exclude_list_, key) == + exclude_list_.end()); } private: - std::unordered_map - exclude_list_; + FilterAttributeMap exclude_list_; }; } // namespace metrics diff --git a/sdk/test/metrics/attributes_processor_test.cc b/sdk/test/metrics/attributes_processor_test.cc index a084b34234..3e13f0e101 100644 --- a/sdk/test/metrics/attributes_processor_test.cc +++ b/sdk/test/metrics/attributes_processor_test.cc @@ -17,10 +17,9 @@ using namespace opentelemetry::sdk::common; TEST(AttributesProcessor, FilteringAttributesProcessor) { - const int kNumFilterAttributes = 3; - std::unordered_map - filter = {{"attr2", true}, {"attr4", true}, {"attr6", true}}; + const int kNumFilterAttributes = 3; + opentelemetry::sdk::metrics::FilterAttributeMap filter = { + {"attr2", true}, {"attr4", true}, {"attr6", true}}; const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; @@ -39,11 +38,9 @@ TEST(AttributesProcessor, FilteringAttributesProcessor) TEST(AttributesProcessor, FilteringAllAttributesProcessor) { - const int kNumFilterAttributes = 0; - std::unordered_map - filter = {}; - const int kNumAttributes = 6; + const int kNumFilterAttributes = 0; + opentelemetry::sdk::metrics::FilterAttributeMap filter = {}; + const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; std::map attributes = {{keys[0], values[0]}, {keys[1], values[1]}, @@ -57,9 +54,8 @@ TEST(AttributesProcessor, FilteringAllAttributesProcessor) TEST(AttributesProcessor, FilteringExcludeAttributesProcessor) { - std::unordered_map - filter = {{"attr2", true}, {"attr4", true}, {"attr6", true}}; + opentelemetry::sdk::metrics::FilterAttributeMap filter = { + {"attr2", true}, {"attr4", true}, {"attr6", true}}; const int kNumAttributes = 7; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6", "attr7"}; @@ -80,10 +76,8 @@ TEST(AttributesProcessor, FilteringExcludeAttributesProcessor) TEST(AttributesProcessor, FilteringExcludeAllAttributesProcessor) { - std::unordered_map - filter = {}; - const int kNumAttributes = 6; + opentelemetry::sdk::metrics::FilterAttributeMap filter = {}; + const int kNumAttributes = 6; std::string keys[kNumAttributes] = {"attr1", "attr2", "attr3", "attr4", "attr5", "attr6"}; int values[kNumAttributes] = {10, 20, 30, 40, 50, 60}; std::map attributes = {{keys[0], values[0]}, {keys[1], values[1]}, diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index 3e0f928382..cd6affea88 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -101,9 +101,7 @@ TEST(HistogramToSumFilterAttributes, Double) std::string instrument_name = "histogram1"; std::string instrument_desc = "histogram metrics"; - std::unordered_map - allowedattr; + opentelemetry::sdk::metrics::FilterAttributeMap allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; @@ -157,9 +155,7 @@ TEST(HistogramToSumFilterAttributesWithCardinalityLimit, Double) std::string instrument_desc = "histogram metrics"; size_t cardinality_limit = 10000; - std::unordered_map - allowedattr; + opentelemetry::sdk::metrics::FilterAttributeMap allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; @@ -342,9 +338,7 @@ TEST(CounterToSumFilterAttributesWithCardinalityLimit, Double) std::string instrument_desc = "counter metrics"; size_t cardinality_limit = 10000; - std::unordered_map - allowedattr; + opentelemetry::sdk::metrics::FilterAttributeMap allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; From 5c5c3ccf085859f6b1f5fdd0fac73d4e8cd23052 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Wed, 24 Sep 2025 00:42:34 +0530 Subject: [PATCH 16/18] Attribute map name --- sdk/test/metrics/sum_aggregation_test.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index cd6affea88..d95131bdde 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -282,9 +282,7 @@ TEST(CounterToSumFilterAttributes, Double) std::string instrument_name = "counter1"; std::string instrument_desc = "counter metrics"; - std::unordered_map - allowedattr; + opentelemetry::sdk::metrics::FilterAttributeMap allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; From 49e8152283eb268afa84fdfa1a78e129199206ae Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Wed, 24 Sep 2025 00:45:51 +0530 Subject: [PATCH 17/18] format fix --- sdk/test/metrics/sum_aggregation_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index d95131bdde..7230531d99 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -282,7 +282,7 @@ TEST(CounterToSumFilterAttributes, Double) std::string instrument_name = "counter1"; std::string instrument_desc = "counter metrics"; - opentelemetry::sdk::metrics::FilterAttributeMap allowedattr; + opentelemetry::sdk::metrics::FilterAttributeMap allowedattr; allowedattr["attr1"] = true; std::unique_ptr attrproc{ new opentelemetry::sdk::metrics::FilteringAttributesProcessor(allowedattr)}; From 7320c356d8ee6b5434dc207335f56502982d3311 Mon Sep 17 00:00:00 2001 From: nikhilbhatia08 Date: Wed, 24 Sep 2025 01:07:33 +0530 Subject: [PATCH 18/18] iwyu fix --- sdk/test/metrics/attributes_processor_benchmark.cc | 2 -- sdk/test/metrics/sum_aggregation_test.cc | 1 - 2 files changed, 3 deletions(-) diff --git a/sdk/test/metrics/attributes_processor_benchmark.cc b/sdk/test/metrics/attributes_processor_benchmark.cc index a8e6e7590a..c64aa6a77c 100644 --- a/sdk/test/metrics/attributes_processor_benchmark.cc +++ b/sdk/test/metrics/attributes_processor_benchmark.cc @@ -4,11 +4,9 @@ #include #include #include -#include #include #include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/sdk/common/custom_hash_equality.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" using namespace opentelemetry::sdk::metrics; diff --git a/sdk/test/metrics/sum_aggregation_test.cc b/sdk/test/metrics/sum_aggregation_test.cc index 7230531d99..02421a9e26 100644 --- a/sdk/test/metrics/sum_aggregation_test.cc +++ b/sdk/test/metrics/sum_aggregation_test.cc @@ -19,7 +19,6 @@ #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/variant.h" -#include "opentelemetry/sdk/common/custom_hash_equality.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation_config.h" #include "opentelemetry/sdk/metrics/data/metric_data.h"