| // Copyright 2025 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef QUICHE_QUIC_MOQT_MOQT_OUTSTANDING_OBJECTS_H_ |
| #define QUICHE_QUIC_MOQT_MOQT_OUTSTANDING_OBJECTS_H_ |
| |
| #include <cstddef> |
| #include <cstdint> |
| |
| #include "absl/container/flat_hash_map.h" |
| #include "quiche/quic/moqt/moqt_messages.h" |
| #include "quiche/common/quiche_circular_deque.h" |
| |
| namespace moqt { |
| |
| // MoqtOutstandingObjects tracks the outgoing objects using Object ACKs. It lets |
| // the sender detect if the objects arrive at the receiver out of order. In |
| // MOQT, the objects get out of order when: |
| // - the subgroup they were a part of is timed out or explicitly reset, |
| // - the track deliver order is descending, and a new group preempted the tail |
| // of the old one. |
| // Note that in the latter scenario, the older objects may still arrive, which |
| // is why this class returns the size of out-of-order gap. |
| // |
| // MoqtOutstandingObjects is also generally not suitable for track with more |
| // than a single subgroup per group. |
| class MoqtOutstandingObjects { |
| public: |
| static constexpr size_t kMaxObjectsTracked = 512; |
| |
| // All objects that are `max_out_of_order_objects` behind the largest object |
| // acked are deemed no longer useful and removed. |
| explicit MoqtOutstandingObjects(uint64_t max_out_of_order_objects) |
| : max_out_of_order_objects_(max_out_of_order_objects) {} |
| |
| // Adds an object into the list. |
| void OnObjectAdded(Location location); |
| |
| // Marks the object as received. Returns the zero if the object arrived |
| // in-order, positive value equal to the delta if it arrives out-of-order, and |
| // -1 if the state to compute the delta is not available. |
| int OnObjectAcked(Location location); |
| |
| size_t tracked_objects_count() const; |
| |
| private: |
| using SequenceNumber = int64_t; |
| struct OutstandingObject { |
| explicit OutstandingObject(Location location) : location(location) {} |
| |
| Location location; |
| bool acked = false; |
| }; |
| |
| void PopFront(); |
| |
| // If reordering for an individual object exceeds the specified threshold, |
| // discard it. |
| const uint64_t max_out_of_order_objects_; |
| |
| // The object at the end of `objects_` has sequence number of |
| // `next_sequence_number_ - 1`. |
| quiche::QuicheCircularDeque<OutstandingObject> objects_; |
| absl::flat_hash_map<Location, SequenceNumber> location_map_; |
| SequenceNumber next_sequence_number_ = 0; |
| }; |
| |
| } // namespace moqt |
| |
| #endif // QUICHE_QUIC_MOQT_MOQT_OUTSTANDING_OBJECTS_H_ |