LCOV - code coverage report
Current view: top level - source/common/stats - metric_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 36 70 51.4 %
Date: 2024-01-05 06:35:25 Functions: 6 10 60.0 %

          Line data    Source code
       1             : #include "source/common/stats/metric_impl.h"
       2             : 
       3             : #include "envoy/stats/tag.h"
       4             : 
       5             : #include "source/common/stats/symbol_table.h"
       6             : 
       7             : namespace Envoy {
       8             : namespace Stats {
       9             : 
      10      392190 : MetricHelper::~MetricHelper() {
      11             :   // The storage must be cleaned by a subclass of MetricHelper in its
      12             :   // destructor, because the symbol-table is owned by the subclass.
      13             :   // Simply call MetricHelper::clear() in the subclass dtor.
      14      392190 :   ASSERT(!stat_names_.populated());
      15      392190 : }
      16             : 
      17             : MetricHelper::MetricHelper(StatName name, StatName tag_extracted_name,
      18      392190 :                            const StatNameTagVector& stat_name_tags, SymbolTable& symbol_table) {
      19             :   // Encode all the names and tags into transient storage so we can count the
      20             :   // required bytes. 2 is added to account for the name and tag_extracted_name,
      21             :   // and we multiply the number of tags by 2 to account for the name and value
      22             :   // of each tag.
      23      392190 :   const uint32_t num_names = 2 + 2 * stat_name_tags.size();
      24      392190 :   absl::FixedArray<StatName> names(num_names);
      25      392190 :   names[0] = name;
      26      392190 :   names[1] = tag_extracted_name;
      27      392190 :   int index = 1;
      28      399796 :   for (auto& stat_name_tag : stat_name_tags) {
      29       57170 :     names[++index] = stat_name_tag.first;
      30       57170 :     names[++index] = stat_name_tag.second;
      31       57170 :   }
      32      392190 :   symbol_table.populateList(names.begin(), num_names, stat_names_);
      33      392190 : }
      34             : 
      35     2412574 : StatName MetricHelper::statName() const {
      36     2412574 :   StatName stat_name;
      37     2412574 :   stat_names_.iterate([&stat_name](StatName s) -> bool {
      38     2412561 :     stat_name = s;
      39     2412561 :     return false; // Returning 'false' stops the iteration.
      40     2412561 :   });
      41     2412574 :   return stat_name;
      42     2412574 : }
      43             : 
      44       38576 : StatName MetricHelper::tagExtractedStatName() const {
      45             :   // The name is the first element in stat_names_. The second is the
      46             :   // tag-extracted-name. We don't have random access in that format,
      47             :   // so we iterate through them, skipping the first element (name),
      48             :   // and terminating the iteration after capturing the tag-extracted
      49             :   // name by returning false from the lambda.
      50       38576 :   StatName tag_extracted_stat_name;
      51       38576 :   bool skip = true;
      52       77152 :   stat_names_.iterate([&tag_extracted_stat_name, &skip](StatName s) -> bool {
      53       77152 :     if (skip) {
      54       38576 :       skip = false;
      55       38576 :       return true;
      56       38576 :     }
      57       38576 :     tag_extracted_stat_name = s;
      58       38576 :     return false; // Returning 'false' stops the iteration.
      59       77152 :   });
      60       38576 :   return tag_extracted_stat_name;
      61       38576 : }
      62             : 
      63           0 : void MetricHelper::iterateTagStatNames(const Metric::TagStatNameIterFn& fn) const {
      64           0 :   enum { Name, TagExtractedName, TagName, TagValue } state = Name;
      65           0 :   StatName tag_name;
      66             : 
      67             :   // StatNameList maintains a linear ordered collection of StatNames, and we
      68             :   // are mapping that into a tag-extracted name (the first element), followed
      69             :   // by alternating TagName and TagValue. So we use a little state machine
      70             :   // as we iterate through the stat_names_.
      71           0 :   stat_names_.iterate([&state, &tag_name, &fn](StatName stat_name) -> bool {
      72           0 :     switch (state) {
      73           0 :     case Name:
      74           0 :       state = TagExtractedName;
      75           0 :       break;
      76           0 :     case TagExtractedName:
      77           0 :       state = TagName;
      78           0 :       break;
      79           0 :     case TagName:
      80           0 :       tag_name = stat_name;
      81           0 :       state = TagValue;
      82           0 :       break;
      83           0 :     case TagValue:
      84           0 :       state = TagName;
      85           0 :       if (!fn(tag_name, stat_name)) {
      86           0 :         return false; // early exit.
      87           0 :       }
      88           0 :       break;
      89           0 :     }
      90           0 :     return true;
      91           0 :   });
      92           0 :   ASSERT(state != TagValue);
      93           0 : }
      94             : 
      95           0 : TagVector MetricHelper::tags(const SymbolTable& symbol_table) const {
      96           0 :   TagVector tags;
      97           0 :   iterateTagStatNames([&tags, &symbol_table](StatName name, StatName value) -> bool {
      98           0 :     tags.emplace_back(Tag{symbol_table.toString(name), symbol_table.toString(value)});
      99           0 :     return true;
     100           0 :   });
     101           0 :   return tags;
     102           0 : }
     103             : 
     104             : } // namespace Stats
     105             : } // namespace Envoy

Generated by: LCOV version 1.15