quic/state/AckEvent.cpp (136 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include <folly/MapUtil.h> #include <quic/state/AckEvent.h> #include <utility> namespace quic { void AckEvent::AckPacket::DetailsPerStream::recordFrameDelivered( const WriteStreamFrame& frame, const bool retransmission) { if (!frame.len) { // may be FIN only return; } auto [it, inserted] = emplace( std::piecewise_construct, std::make_tuple(frame.streamId), std::make_tuple()); auto& outstandingPacketStreamDetails = it->second; outstandingPacketStreamDetails.streamBytesAcked += frame.len; if (retransmission) { outstandingPacketStreamDetails.streamBytesAckedByRetrans += frame.len; } } void AckEvent::AckPacket::DetailsPerStream::recordFrameAlreadyDelivered( const WriteStreamFrame& frame, const bool /* retransmission */) { if (!frame.len) { // may be FIN only return; } auto [it, inserted] = try_emplace(frame.streamId); auto& outstandingPacketStreamDetails = it->second; outstandingPacketStreamDetails.dupAckedStreamIntervals.insert( frame.offset, frame.offset + frame.len - 1); } void AckEvent::AckPacket::DetailsPerStream::recordDeliveryOffsetUpdate( StreamId streamId, uint64_t newOffset) { auto [it, inserted] = try_emplace(streamId); auto& outstandingPacketStreamDetails = it->second; CHECK( !outstandingPacketStreamDetails.maybeNewDeliveryOffset.has_value() || outstandingPacketStreamDetails.maybeNewDeliveryOffset.value() < newOffset); outstandingPacketStreamDetails.maybeNewDeliveryOffset = newOffset; } AckEvent::AckPacket::AckPacket( quic::PacketNum packetNumIn, OutstandingPacketMetadata&& outstandingPacketMetadataIn, DetailsPerStream&& detailsPerStreamIn, folly::Optional<OutstandingPacket::LastAckedPacketInfo> lastAckedPacketInfoIn, bool isAppLimitedIn) : packetNum(packetNumIn), outstandingPacketMetadata(std::move(outstandingPacketMetadataIn)), detailsPerStream(std::move(detailsPerStreamIn)), lastAckedPacketInfo(std::move(lastAckedPacketInfoIn)), isAppLimited(isAppLimitedIn) {} AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setPacketNum( quic::PacketNum packetNumIn) { packetNum = packetNumIn; return std::move(*this); } AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setOutstandingPacketMetadata( OutstandingPacketMetadata&& outstandingPacketMetadataIn) { outstandingPacketMetadata = std::move(outstandingPacketMetadataIn); return std::move(*this); } AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setDetailsPerStream( DetailsPerStream&& detailsPerStreamIn) { detailsPerStream = std::move(detailsPerStreamIn); return std::move(*this); } AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setLastAckedPacketInfo( folly::Optional<OutstandingPacket::LastAckedPacketInfo>&& lastAckedPacketInfoIn) { lastAckedPacketInfo = std::move(lastAckedPacketInfoIn); return std::move(*this); } AckEvent::AckPacket::Builder&& AckEvent::AckPacket::Builder::setAppLimited( bool appLimitedIn) { isAppLimited = appLimitedIn; return std::move(*this); } AckEvent::AckPacket AckEvent::AckPacket::Builder::build() && { CHECK(packetNum.has_value()); CHECK(outstandingPacketMetadata.has_value()); CHECK(detailsPerStream.has_value()); return AckEvent::AckPacket( packetNum.value(), std::move(outstandingPacketMetadata.value()), std::move(detailsPerStream.value()), std::move(lastAckedPacketInfo), isAppLimited); } AckEvent::Builder&& AckEvent::Builder::setAckTime(TimePoint ackTimeIn) { maybeAckTime = ackTimeIn; return std::move(*this); } AckEvent::Builder&& AckEvent::Builder::setAdjustedAckTime( TimePoint adjustedAckTimeIn) { maybeAdjustedAckTime = adjustedAckTimeIn; return std::move(*this); } AckEvent::Builder&& AckEvent::Builder::setAckDelay( std::chrono::microseconds ackDelayIn) { maybeAckDelay = ackDelayIn; return std::move(*this); } AckEvent::Builder&& AckEvent::Builder::setPacketNumberSpace( PacketNumberSpace packetNumberSpaceIn) { maybePacketNumberSpace = packetNumberSpaceIn; return std::move(*this); } AckEvent::Builder&& AckEvent::Builder::setLargestAckedPacket( PacketNum largestAckedPacketIn) { maybeLargestAckedPacket = largestAckedPacketIn; return std::move(*this); } AckEvent::Builder&& AckEvent::Builder::setIsImplicitAck(bool isImplicitAckIn) { isImplicitAck = isImplicitAckIn; return std::move(*this); } AckEvent AckEvent::Builder::build() && { return AckEvent(std::move(*this)); } AckEvent::AckEvent(AckEvent::BuilderFields&& builderFields) : ackTime(*CHECK_NOTNULL(builderFields.maybeAckTime.get_pointer())), adjustedAckTime( *CHECK_NOTNULL(builderFields.maybeAdjustedAckTime.get_pointer())), ackDelay(*CHECK_NOTNULL(builderFields.maybeAckDelay.get_pointer())), packetNumberSpace( *CHECK_NOTNULL(builderFields.maybePacketNumberSpace.get_pointer())), largestAckedPacket( *CHECK_NOTNULL(builderFields.maybeLargestAckedPacket.get_pointer())), implicit(builderFields.isImplicitAck) {} } // namespace quic