Copilot commented on code in PR #13616:
URL: https://github.com/apache/trafficserver/pull/13616#discussion_r3917563390


##########
src/tsutil/Metrics.cc:
##########
@@ -245,9 +252,57 @@ Metrics::Storage::rename(Metrics::IdType id, 
std::string_view name)
   return true;
 }
 
+bool
+Metrics::Storage::set_listed(Metrics::IdType id, bool listed)
+{
+  if (!allocated(id)) {
+    return false;
+  }
+
+  auto [blob_ix, offset]         = _splitID(id);
+  Metrics::NamesAndAtomics *blob = _blobs[blob_ix].get();
+
+  // Only this bit, so a flag added later is not clobbered by unlisting or 
relisting.
+  if (listed) {
+    std::get<2>(*blob)[offset].fetch_and(static_cast<uint8_t>(~UNLISTED), 
MEMORY_ORDER);
+  } else {
+    std::get<2>(*blob)[offset].fetch_or(UNLISTED, MEMORY_ORDER);
+  }
+
+  return true;
+}
+
+bool
+Metrics::Storage::listed(Metrics::IdType id) const
+{
+  if (!allocated(id)) {
+    return false;
+  }
+
+  auto [blob_ix, offset]         = _splitID(id);
+  Metrics::NamesAndAtomics *blob = _blobs[blob_ix].get();
+
+  return (std::get<2>(*blob)[offset].load(MEMORY_ORDER) & UNLISTED) == 0;
+}
+
 // Iterator implementation
+Metrics::iterator::iterator(const Metrics &m) : _metrics(m), _it(0), 
_bound(m._storage->current_id())
+{
+  skip_unlisted();
+}
+
+Metrics::iterator::iterator(const Metrics &m, IdType pos) : _metrics(m), 
_it(pos), _bound(m._storage->current_id())
+{
+  // Iteration never visits an unlisted slot, so an iterator must not rest on 
one either: used as a
+  // range bound it would be stepped over and never reached. find() resolves 
that case to end()
+  // before it gets here; this keeps the invariant true for any other 
positional construction.
+  skip_unlisted();
+}

Review Comment:
   The iterator bound check uses numeric comparison against `_bound` (built 
with `MetricType::COUNTER` type bits). When `find()` constructs an iterator 
from a GAUGE id, `_it` includes GAUGE type bits (bit 29), so `_it >= _bound` is 
immediately true and the iterator behaves as exhausted. This makes 
`Metrics::find()` incorrectly return `end()` for listed GAUGE metrics.
   
   Normalize positional iterator state to always use a COUNTER-typed positional 
id (as `advance()` already does) before calling `skip_unlisted()`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to