blob: 0348044f8a8afd24e986ec225eb73ed7836ab4a9 [file] [log] [blame] [edit]
// Copyright 2023 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_SUBSCRIBE_WINDOWS_H
#define QUICHE_QUIC_MOQT_SUBSCRIBE_WINDOWS_H
#include <cstdint>
#include <optional>
#include <vector>
#include "absl/container/btree_map.h"
#include "quiche/quic/core/quic_interval.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_publisher.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/web_transport/web_transport.h"
namespace moqt {
// SubscribeWindow represents a window of objects for which an MoQT subscription
// can be valid.
class QUICHE_EXPORT SubscribeWindow {
public:
// Creates a half-open window for SUBSCRIBES.
SubscribeWindow() = default;
SubscribeWindow(Location start) : start_(start) {}
// Creates a closed window for SUBSCRIBE or FETCH with no end object;
SubscribeWindow(Location start, std::optional<uint64_t> end_group)
: start_(start),
end_(Location(end_group.value_or(UINT64_MAX), UINT64_MAX)) {}
// For FETCH with end object
SubscribeWindow(Location start, uint64_t end_group,
std::optional<uint64_t> end_object)
: start_(start),
end_(Location(end_group, end_object.value_or(UINT64_MAX))) {}
bool InWindow(const Location& seq) const {
return start_ <= seq && seq <= end_;
}
bool GroupInWindow(uint64_t group) const;
Location start() const { return start_; }
Location end() const { return end_; }
// Updates the subscription window. Returns true if the update is valid (in
// MoQT, subscription windows are only allowed to shrink, not to expand).
// Called only as a result of SUBSCRIBE_OK (largest_id) or SUBSCRIBE_UPDATE.
bool TruncateStart(Location start);
// Called only as a result of SUBSCRIBE_UPDATE.
bool TruncateEnd(uint64_t end_group);
// Called only as a result of FETCH_OK (largest_id)
bool TruncateEnd(Location largest_id);
private:
// The subgroups in these sequences have no meaning.
Location start_ = Location();
Location end_ = Location(UINT64_MAX, UINT64_MAX);
};
// A tuple uniquely identifying a WebTransport data stream associated with a
// subscription. By convention, if a DataStreamIndex is necessary for a datagram
// track, `subgroup` is set to zero.
struct DataStreamIndex {
uint64_t group = 0;
uint64_t subgroup = 0;
DataStreamIndex() = default;
DataStreamIndex(uint64_t group, uint64_t subgroup)
: group(group), subgroup(subgroup) {}
explicit DataStreamIndex(const PublishedObject& object)
: group(object.metadata.location.group),
subgroup(object.metadata.subgroup) {}
auto operator<=>(const DataStreamIndex&) const = default;
template <typename H>
friend H AbslHashValue(H h, const DataStreamIndex& index) {
return H::combine(std::move(h), index.group, index.subgroup);
}
};
// A map of outgoing data streams indexed by object sequence numbers.
class QUICHE_EXPORT SendStreamMap {
public:
SendStreamMap() = default;
std::optional<webtransport::StreamId> GetStreamFor(
DataStreamIndex index) const;
void AddStream(DataStreamIndex index, webtransport::StreamId stream_id);
void RemoveStream(DataStreamIndex index);
std::vector<webtransport::StreamId> GetAllStreams() const;
std::vector<webtransport::StreamId> GetStreamsForGroup(
uint64_t group_id) const;
private:
absl::btree_map<DataStreamIndex, webtransport::StreamId> send_streams_;
};
} // namespace moqt
#endif // QUICHE_QUIC_MOQT_SUBSCRIBE_WINDOWS_H