@@ -82,13 +82,17 @@ class Metrics
8282 std::atomic<int64_t > _value{0 };
8383 };
8484
85+ enum class MetricType : int { COUNTER = 0 , GAUGE };
86+
8587 using IdType = int32_t ; // Could be a tuple, but one way or another, they have to be combined to an int32_t.
8688 using SpanType = swoc::MemSpan<AtomicType>;
8789
88- static constexpr uint16_t MAX_BLOBS = 8192 ;
89- static constexpr uint16_t MAX_SIZE = 1024 ; // For a total of 8M metrics
90- static constexpr IdType NOT_FOUND = std::numeric_limits<IdType>::min(); // <16-bit,16-bit> = <blob-index,offset>
91- static const auto MEMORY_ORDER = std::memory_order_relaxed;
90+ static constexpr uint16_t MAX_BLOBS = 8192 ;
91+ static constexpr uint16_t MAX_SIZE = 1024 ; // For a total of 8M metrics
92+ static constexpr IdType NOT_FOUND = std::numeric_limits<IdType>::min(); // <16-bit,16-bit> = <blob-index,offset>
93+ static const auto MEMORY_ORDER = std::memory_order_relaxed;
94+ static constexpr int METRIC_TYPE_BITS = 29 ;
95+ static constexpr int METRIC_TYPE_MASK = 0x1FFF ;
9296
9397private:
9498 using NameAndId = std::tuple<std::string, IdType>;
@@ -122,9 +126,9 @@ class Metrics
122126 return _storage->lookup (name, out_id);
123127 }
124128 AtomicType *
125- lookup (IdType id, std::string_view *out_name = nullptr ) const
129+ lookup (IdType id, std::string_view *out_name = nullptr , Metrics::MetricType *type = nullptr ) const
126130 {
127- return _storage->lookup (id, out_name);
131+ return _storage->lookup (id, out_name, type );
128132 }
129133 bool
130134 rename (IdType id, const std::string_view name)
@@ -166,6 +170,12 @@ class Metrics
166170 return _storage->name (id);
167171 }
168172
173+ MetricType
174+ type (IdType id) const
175+ {
176+ return _storage->type (id);
177+ }
178+
169179 bool
170180 valid (IdType id) const
171181 {
@@ -177,7 +187,7 @@ class Metrics
177187 {
178188 public:
179189 using iterator_category = std::input_iterator_tag;
180- using value_type = std::tuple<std::string_view, int64_t >;
190+ using value_type = std::tuple<std::string_view, MetricType, int64_t >;
181191 using difference_type = ptrdiff_t ;
182192 using pointer = value_type *;
183193 using reference = value_type &;
@@ -206,9 +216,10 @@ class Metrics
206216 operator *() const
207217 {
208218 std::string_view name;
209- auto metric = _metrics.lookup (_it, &name);
219+ MetricType type;
220+ auto metric = _metrics.lookup (_it, &name, &type);
210221
211- return std::make_tuple (name, metric->_value .load ());
222+ return std::make_tuple (name, type, metric->_value .load ());
212223 }
213224
214225 bool
@@ -241,7 +252,7 @@ class Metrics
241252 {
242253 auto [blob, offset] = _storage->current ();
243254
244- return iterator (*this , _makeId (blob, offset));
255+ return iterator (*this , _makeId (blob, offset, MetricType::COUNTER ));
245256 }
246257
247258 iterator
@@ -259,34 +270,35 @@ class Metrics
259270private:
260271 // These are private, to assure that we don't use them by accident creating naked metrics
261272 IdType
262- _create (const std::string_view name)
273+ _create (const std::string_view name, MetricType type )
263274 {
264- return _storage->create (name);
275+ return _storage->create (name, type );
265276 }
266277
267278 SpanType
268- _createSpan (size_t size, IdType *id = nullptr )
279+ _createSpan (size_t size, MetricType type, IdType *id = nullptr )
269280 {
270- return _storage->createSpan (size, id);
281+ return _storage->createSpan (size, type, id);
271282 }
272283
273284 // These are little helpers around managing the ID's
274285 static constexpr std::tuple<uint16_t , uint16_t >
275286 _splitID (IdType value)
276287 {
277- return std::make_tuple (static_cast <uint16_t >(value >> 16 ), static_cast <uint16_t >(value & 0xFFFF ));
288+ return std::make_tuple (static_cast <uint16_t >(value >> 16 ) & METRIC_TYPE_MASK , static_cast <uint16_t >(value & 0xFFFF ));
278289 }
279290
280- static constexpr IdType
281- _makeId ( uint16_t blob, uint16_t offset )
291+ static constexpr MetricType
292+ _extractType (IdType value )
282293 {
283- return (blob << 16 | offset) ;
294+ return MetricType{value >> METRIC_TYPE_BITS} ;
284295 }
285296
286297 static constexpr IdType
287- _makeId (std::tuple< uint16_t , uint16_t > id )
298+ _makeId (uint16_t blob , uint16_t offset, const MetricType type )
288299 {
289- return _makeId (std::get<0 >(id), std::get<1 >(id));
300+ int t = static_cast <int >(type);
301+ return (t << METRIC_TYPE_BITS | blob << 16 | offset);
290302 }
291303
292304 class Storage
@@ -305,18 +317,20 @@ class Metrics
305317 {
306318 _blobs[0 ] = std::make_unique<NamesAndAtomics>();
307319 release_assert (_blobs[0 ]);
308- release_assert (0 == create (" proxy.process.api.metrics.bad_id" )); // Reserve slot 0 for errors, this should always be 0
320+ // Reserve slot 0 for errors, this should always be 0
321+ release_assert (0 == create (" proxy.process.api.metrics.bad_id" , MetricType::COUNTER));
309322 }
310323
311324 ~Storage () {}
312325
313- IdType create (const std::string_view name);
326+ IdType create (const std::string_view name, const MetricType type = MetricType::COUNTER );
314327 void addBlob ();
315328 IdType lookup (const std::string_view name) const ;
316- AtomicType *lookup (const std::string_view name, IdType *out_id) const ;
317- AtomicType *lookup (Metrics::IdType id, std::string_view *out_name = nullptr ) const ;
329+ AtomicType *lookup (const std::string_view name, IdType *out_id, MetricType *out_type = nullptr ) const ;
330+ AtomicType *lookup (Metrics::IdType id, std::string_view *out_name = nullptr , MetricType *out_type = nullptr ) const ;
318331 std::string_view name (IdType id) const ;
319- SpanType createSpan (size_t size, IdType *id = nullptr );
332+ MetricType type (IdType id) const ;
333+ SpanType createSpan (size_t size, const MetricType type = MetricType::COUNTER, IdType *id = nullptr );
320334 bool rename (IdType id, const std::string_view name);
321335
322336 std::pair<int16_t , int16_t >
@@ -380,15 +394,15 @@ class Metrics
380394 {
381395 auto &instance = Metrics::instance ();
382396
383- return instance._create (name);
397+ return instance._create (name, MetricType::GAUGE );
384398 }
385399
386400 static AtomicType *
387401 createPtr (const std::string_view name)
388402 {
389403 auto &instance = Metrics::instance ();
390404
391- return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (name)));
405+ return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (name, MetricType::GAUGE )));
392406 }
393407
394408 static AtomicType *
@@ -397,15 +411,15 @@ class Metrics
397411 auto &instance = Metrics::instance ();
398412 std::string tmpname = std::string (prefix) + std::string (name);
399413
400- return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (tmpname)));
414+ return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (tmpname, MetricType::GAUGE )));
401415 }
402416
403417 static Metrics::Gauge::SpanType
404418 createSpan (size_t size, IdType *id = nullptr )
405419 {
406420 auto &instance = Metrics::instance ();
407421
408- return instance._createSpan (size, id);
422+ return instance._createSpan (size, MetricType::GAUGE, id);
409423 }
410424
411425 static void
@@ -477,15 +491,15 @@ class Metrics
477491 {
478492 auto &instance = Metrics::instance ();
479493
480- return instance._create (name);
494+ return instance._create (name, MetricType::COUNTER );
481495 }
482496
483497 static AtomicType *
484498 createPtr (const std::string_view name)
485499 {
486500 auto &instance = Metrics::instance ();
487501
488- return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (name)));
502+ return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (name, MetricType::COUNTER )));
489503 }
490504
491505 static AtomicType *
@@ -494,15 +508,15 @@ class Metrics
494508 auto &instance = Metrics::instance ();
495509 std::string tmpname = std::string (prefix) + std::string (name);
496510
497- return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (tmpname)));
511+ return reinterpret_cast <AtomicType *>(instance.lookup (instance._create (tmpname, MetricType::COUNTER )));
498512 }
499513
500514 static Metrics::Counter::SpanType
501515 createSpan (size_t size, IdType *id = nullptr )
502516 {
503517 auto &instance = Metrics::instance ();
504518
505- return instance._createSpan (size, id);
519+ return instance._createSpan (size, MetricType::COUNTER, id);
506520 }
507521
508522 static void
@@ -531,6 +545,7 @@ class Metrics
531545 struct DerivedMetricSpec {
532546 using MetricSpec = std::variant<Metrics::AtomicType *, Metrics::IdType, std::string_view>;
533547 std::string_view derived_name;
548+ Metrics::MetricType derived_type;
534549 std::initializer_list<MetricSpec> derived_from;
535550 };
536551
0 commit comments