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


##########
include/tsutil/Metrics.h:
##########
@@ -94,13 +94,20 @@ class Metrics
   static constexpr int      METRIC_TYPE_MASK = 0x1FFF;
 
 private:
-  using NameAndId       = std::tuple<std::string, IdType>;
-  using LookupTable     = std::unordered_map<std::string_view, IdType>;
-  using NameStorage     = std::array<NameAndId, MAX_SIZE>;
-  using AtomicStorage   = std::array<AtomicType, MAX_SIZE>;
-  using NamesAndAtomics = std::tuple<NameStorage, AtomicStorage>;
+  using NameAndId     = std::tuple<std::string, IdType>;
+  using LookupTable   = std::unordered_map<std::string_view, IdType>;
+  using NameStorage   = std::array<NameAndId, MAX_SIZE>;
+  using AtomicStorage = std::array<AtomicType, MAX_SIZE>;
+  /// Per slot flag bits, see @c UNLISTED. A parallel array rather than a 
member of @c NameAndId
+  /// because an atomic member would make that tuple neither copyable nor 
movable, and the slot is
+  /// written there with a tuple assignment.
+  using FlagStorage     = std::array<std::atomic<uint8_t>, MAX_SIZE>;

Review Comment:
   `FlagStorage` uses `std::atomic<uint8_t>`, whose default constructor does 
not guarantee zero-initialization. If the code doesn’t explicitly `store(0)` 
for each slot (both when a blob is created and when a new slot is allocated), 
flags can start with indeterminate values and metrics may appear randomly 
unlisted. Ensure flags are deterministically initialized (e.g., clear the 
entire `FlagStorage` when allocating a blob, and explicitly clear the flag for 
each newly allocated slot in `Storage::create`).



##########
include/tsutil/Metrics.h:
##########
@@ -231,43 +299,80 @@ class Metrics
       return std::make_tuple(name, type, metric->_value.load());
     }
 
+    /** Equality.
+     *
+     * Three way rather than a plain position compare: any exhausted iterator 
equals the end
+     * sentinel, and equals any other exhausted iterator, since two of them 
may have skipped a
+     * different number of unlisted slots. Two live iterators still compare by 
position.
+     *
+     * Two positional iterators may hold different snapshots, so exhaustion 
between them is judged
+     * against the earlier bound. Otherwise a walk could pass its own bound 
while a stop iterator
+     * made later was still live: they would never compare equal and @c 
operator++ could not make
+     * progress. The sentinel keeps its own answer, since its bound is 
meaningless.
+     *
+     * @note A snapshot is the sequence: iterators from different ones are no 
more comparable than
+     *   iterators into different containers, and mixing them is unspecified. 
Within one snapshot
+     *   equality is the equivalence relation an input iterator requires. The 
rule above keeps the
+     *   unspecified case terminating rather than hanging.
+     */
     bool
     operator==(const iterator &o) const
     {
-      return _it == o._it && std::addressof(_metrics) == 
std::addressof(o._metrics);
-    }
+      if (std::addressof(_metrics) != std::addressof(o._metrics)) {
+        return false;
+      }
 
-    bool
-    operator!=(const iterator &o) const
-    {
-      return _it != o._it || std::addressof(_metrics) != 
std::addressof(o._metrics);
+      if (_end || o._end) {
+        return at_end() == o.at_end();
+      }
+
+      auto const bound = _bound < o._bound ? _bound : o._bound;
+      bool const a = _it >= bound, b = o._it >= bound;
+
+      if (a || b) {
+        return a && b;
+      }
+      return _it == o._it;
     }
 

Review Comment:
   This change appears to rely on `operator!=` being available via C++20 
rewritten comparisons (since `operator!=` was removed but call sites/tests 
still use `!=`). If any build targets still compile this code as C++17 (or 
earlier), `a != b` will fail to compile without an explicit `operator!=`. 
Either confirm the project is C++20+ everywhere, or re-introduce `operator!=` 
as `return !(*this == o);` to preserve compatibility.



-- 
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