Index: net/quic/quic_unacked_packet_map.cc |
diff --git a/net/quic/quic_unacked_packet_map.cc b/net/quic/quic_unacked_packet_map.cc |
deleted file mode 100644 |
index 25e2a8afaf3b62561d7f4bad79c3fb63c4ff818a..0000000000000000000000000000000000000000 |
--- a/net/quic/quic_unacked_packet_map.cc |
+++ /dev/null |
@@ -1,409 +0,0 @@ |
-// Copyright 2014 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. |
- |
-#include "net/quic/quic_unacked_packet_map.h" |
- |
-#include "base/logging.h" |
-#include "base/stl_util.h" |
-#include "net/quic/quic_connection_stats.h" |
-#include "net/quic/quic_utils_chromium.h" |
- |
-using std::max; |
- |
-namespace net { |
- |
-QuicUnackedPacketMap::QuicUnackedPacketMap() |
- : largest_sent_packet_(0), |
- largest_observed_(0), |
- least_unacked_(1), |
- bytes_in_flight_(0), |
- pending_crypto_packet_count_(0) { |
-} |
- |
-QuicUnackedPacketMap::~QuicUnackedPacketMap() { |
- QuicPacketSequenceNumber index = least_unacked_; |
- for (UnackedPacketMap::iterator it = unacked_packets_.begin(); |
- it != unacked_packets_.end(); ++it, ++index) { |
- delete it->retransmittable_frames; |
- // Only delete all_transmissions once, for the newest packet. |
- if (it->all_transmissions != nullptr && |
- index == *it->all_transmissions->rbegin()) { |
- delete it->all_transmissions; |
- } |
- } |
-} |
- |
-void QuicUnackedPacketMap::AddSentPacket( |
- const SerializedPacket& packet, |
- QuicPacketSequenceNumber old_sequence_number, |
- TransmissionType transmission_type, |
- QuicTime sent_time, |
- QuicByteCount bytes_sent, |
- bool set_in_flight) { |
- QuicPacketSequenceNumber sequence_number = packet.sequence_number; |
- LOG_IF(DFATAL, largest_sent_packet_ > sequence_number); |
- DCHECK_GE(sequence_number, least_unacked_ + unacked_packets_.size()); |
- while (least_unacked_ + unacked_packets_.size() < sequence_number) { |
- unacked_packets_.push_back(TransmissionInfo()); |
- unacked_packets_.back().is_unackable = true; |
- } |
- |
- TransmissionInfo info(packet.retransmittable_frames, |
- packet.sequence_number_length, |
- transmission_type, |
- sent_time); |
- info.is_fec_packet = packet.is_fec_packet; |
- |
- if (old_sequence_number == 0) { |
- if (packet.retransmittable_frames != nullptr && |
- packet.retransmittable_frames->HasCryptoHandshake() == IS_HANDSHAKE) { |
- ++pending_crypto_packet_count_; |
- } |
- } else { |
- TransferRetransmissionInfo( |
- old_sequence_number, sequence_number, transmission_type, &info); |
- } |
- |
- largest_sent_packet_ = sequence_number; |
- if (set_in_flight) { |
- bytes_in_flight_ += bytes_sent; |
- info.bytes_sent = bytes_sent; |
- info.in_flight = true; |
- } |
- unacked_packets_.push_back(info); |
-} |
- |
-void QuicUnackedPacketMap::RemoveObsoletePackets() { |
- while (!unacked_packets_.empty()) { |
- if (!IsPacketRemovable(least_unacked_, unacked_packets_.front())) { |
- break; |
- } |
- unacked_packets_.pop_front(); |
- ++least_unacked_; |
- } |
-} |
- |
-void QuicUnackedPacketMap::TransferRetransmissionInfo( |
- QuicPacketSequenceNumber old_sequence_number, |
- QuicPacketSequenceNumber new_sequence_number, |
- TransmissionType transmission_type, |
- TransmissionInfo* info) { |
- DCHECK_GE(old_sequence_number, least_unacked_); |
- DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size()); |
- DCHECK_GE(new_sequence_number, least_unacked_ + unacked_packets_.size()); |
- DCHECK_NE(NOT_RETRANSMISSION, transmission_type); |
- |
- // TODO(ianswett): Discard and lose the packet lazily instead of immediately. |
- TransmissionInfo* transmission_info = |
- &unacked_packets_.at(old_sequence_number - least_unacked_); |
- RetransmittableFrames* frames = transmission_info->retransmittable_frames; |
- transmission_info->retransmittable_frames = nullptr; |
- LOG_IF(DFATAL, frames == nullptr) |
- << "Attempt to retransmit packet with no " |
- << "retransmittable frames: " << old_sequence_number; |
- |
- // Only keep one transmission older than largest observed, because only the |
- // most recent is expected to possibly be a spurious retransmission. |
- while (transmission_info->all_transmissions != nullptr && |
- transmission_info->all_transmissions->size() > 1 && |
- *(++transmission_info->all_transmissions->begin()) < |
- largest_observed_) { |
- QuicPacketSequenceNumber old_transmission = |
- *transmission_info->all_transmissions->begin(); |
- TransmissionInfo* old_info = |
- &unacked_packets_[old_transmission - least_unacked_]; |
- // Don't remove old packets if they're still in flight. |
- if (old_info->in_flight) { |
- break; |
- } |
- old_info->all_transmissions->pop_front(); |
- // This will cause the packet be removed in RemoveObsoletePackets. |
- old_info->all_transmissions = nullptr; |
- } |
- // Don't link old transmissions to new ones when version or |
- // encryption changes. |
- if (transmission_type == ALL_INITIAL_RETRANSMISSION || |
- transmission_type == ALL_UNACKED_RETRANSMISSION) { |
- RemoveAckability(transmission_info); |
- } else { |
- if (transmission_info->all_transmissions == nullptr) { |
- transmission_info->all_transmissions = new SequenceNumberList(); |
- transmission_info->all_transmissions->push_back(old_sequence_number); |
- } |
- transmission_info->all_transmissions->push_back(new_sequence_number); |
- } |
- info->retransmittable_frames = frames; |
- info->all_transmissions = transmission_info->all_transmissions; |
- // Proactively remove obsolete packets so the least unacked can be raised. |
- RemoveObsoletePackets(); |
-} |
- |
-void QuicUnackedPacketMap::ClearAllPreviousRetransmissions() { |
- while (!unacked_packets_.empty() && least_unacked_ < largest_observed_) { |
- // If this packet is in flight, or has retransmittable data, then there is |
- // no point in clearing out any further packets, because they would not |
- // affect the high water mark. |
- TransmissionInfo* info = &unacked_packets_.front(); |
- if (info->in_flight || info->retransmittable_frames != nullptr) { |
- break; |
- } |
- |
- if (info->all_transmissions != nullptr) { |
- if (info->all_transmissions->size() < 2) { |
- LOG(DFATAL) << "all_transmissions must be nullptr or have multiple " |
- << "elements. size:" << info->all_transmissions->size(); |
- delete info->all_transmissions; |
- } else { |
- info->all_transmissions->pop_front(); |
- if (info->all_transmissions->size() == 1) { |
- // Set the newer transmission's 'all_transmissions' entry to nullptr. |
- QuicPacketSequenceNumber new_transmission = |
- info->all_transmissions->front(); |
- TransmissionInfo* new_info = |
- &unacked_packets_.at(new_transmission - least_unacked_); |
- delete new_info->all_transmissions; |
- new_info->all_transmissions = nullptr; |
- } |
- } |
- } |
- unacked_packets_.pop_front(); |
- ++least_unacked_; |
- } |
-} |
- |
-bool QuicUnackedPacketMap::HasRetransmittableFrames( |
- QuicPacketSequenceNumber sequence_number) const { |
- DCHECK_GE(sequence_number, least_unacked_); |
- DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
- return unacked_packets_[sequence_number - least_unacked_] |
- .retransmittable_frames != nullptr; |
-} |
- |
-void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number, |
- QuicPacketCount min_nacks) { |
- DCHECK_GE(sequence_number, least_unacked_); |
- DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
- unacked_packets_[sequence_number - least_unacked_].nack_count = |
- max(min_nacks, |
- unacked_packets_[sequence_number - least_unacked_].nack_count); |
-} |
- |
-void QuicUnackedPacketMap::RemoveRetransmittability( |
- QuicPacketSequenceNumber sequence_number) { |
- DCHECK_GE(sequence_number, least_unacked_); |
- DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
- TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; |
- SequenceNumberList* all_transmissions = info->all_transmissions; |
- if (all_transmissions == nullptr) { |
- MaybeRemoveRetransmittableFrames(info); |
- return; |
- } |
- // TODO(ianswett): Consider adding a check to ensure there are retransmittable |
- // frames associated with this packet. |
- for (SequenceNumberList::const_iterator it = all_transmissions->begin(); |
- it != all_transmissions->end(); ++it) { |
- TransmissionInfo* transmission_info = |
- &unacked_packets_[*it - least_unacked_]; |
- MaybeRemoveRetransmittableFrames(transmission_info); |
- transmission_info->all_transmissions = nullptr; |
- } |
- delete all_transmissions; |
-} |
- |
-void QuicUnackedPacketMap::RemoveAckability(TransmissionInfo* info) { |
- DCHECK(info->retransmittable_frames == nullptr); |
- info->is_unackable = true; |
- SequenceNumberList* all_transmissions = info->all_transmissions; |
- if (all_transmissions == nullptr) { |
- return; |
- } |
- for (SequenceNumberList::const_iterator it = all_transmissions->begin(); |
- it != all_transmissions->end(); ++it) { |
- TransmissionInfo* transmission_info = |
- &unacked_packets_[*it - least_unacked_]; |
- transmission_info->all_transmissions = nullptr; |
- transmission_info->is_unackable = true; |
- } |
- delete all_transmissions; |
-} |
- |
-void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( |
- TransmissionInfo* transmission_info) { |
- if (transmission_info->retransmittable_frames != nullptr) { |
- if (transmission_info->retransmittable_frames->HasCryptoHandshake() |
- == IS_HANDSHAKE) { |
- --pending_crypto_packet_count_; |
- } |
- delete transmission_info->retransmittable_frames; |
- transmission_info->retransmittable_frames = nullptr; |
- } |
-} |
- |
-void QuicUnackedPacketMap::IncreaseLargestObserved( |
- QuicPacketSequenceNumber largest_observed) { |
- DCHECK_LE(largest_observed_, largest_observed); |
- largest_observed_ = largest_observed; |
-} |
- |
-bool QuicUnackedPacketMap::IsPacketUsefulForMeasuringRtt( |
- QuicPacketSequenceNumber sequence_number, |
- const TransmissionInfo& info) const { |
- // Packet can be used for RTT measurement if it may yet be acked as the |
- // largest observed packet by the receiver. |
- return !info.is_unackable && sequence_number > largest_observed_; |
-} |
- |
-bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl( |
- QuicPacketSequenceNumber sequence_number, |
- const TransmissionInfo& info) const { |
- // Packet contributes to congestion control if it is considered inflight. |
- return info.in_flight; |
-} |
- |
-bool QuicUnackedPacketMap::IsPacketUsefulForRetransmittableData( |
- QuicPacketSequenceNumber sequence_number, |
- const TransmissionInfo& info) const { |
- // Packet may have retransmittable frames, or the data may have been |
- // retransmitted with a new sequence number. |
- return info.retransmittable_frames != nullptr || |
- info.all_transmissions != nullptr; |
-} |
- |
-bool QuicUnackedPacketMap::IsPacketUseless( |
- QuicPacketSequenceNumber sequence_number, |
- const TransmissionInfo& info) const { |
- return !IsPacketUsefulForMeasuringRtt(sequence_number, info) && |
- !IsPacketUsefulForCongestionControl(sequence_number, info) && |
- !IsPacketUsefulForRetransmittableData(sequence_number, info); |
-} |
- |
-bool QuicUnackedPacketMap::IsPacketRemovable( |
- QuicPacketSequenceNumber sequence_number, |
- const TransmissionInfo& info) const { |
- return (!IsPacketUsefulForMeasuringRtt(sequence_number, info) || |
- unacked_packets_.size() > kMaxTcpCongestionWindow) && |
- !IsPacketUsefulForCongestionControl(sequence_number, info) && |
- !IsPacketUsefulForRetransmittableData(sequence_number, info); |
-} |
- |
-bool QuicUnackedPacketMap::IsUnacked( |
- QuicPacketSequenceNumber sequence_number) const { |
- if (sequence_number < least_unacked_ || |
- sequence_number >= least_unacked_ + unacked_packets_.size()) { |
- return false; |
- } |
- return !IsPacketUseless(sequence_number, |
- unacked_packets_[sequence_number - least_unacked_]); |
-} |
- |
-void QuicUnackedPacketMap::RemoveFromInFlight( |
- QuicPacketSequenceNumber sequence_number) { |
- DCHECK_GE(sequence_number, least_unacked_); |
- DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
- TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; |
- if (info->in_flight) { |
- LOG_IF(DFATAL, bytes_in_flight_ < info->bytes_sent); |
- bytes_in_flight_ -= info->bytes_sent; |
- info->in_flight = false; |
- } |
-} |
- |
-bool QuicUnackedPacketMap::HasUnackedPackets() const { |
- return !unacked_packets_.empty(); |
-} |
- |
-bool QuicUnackedPacketMap::HasInFlightPackets() const { |
- return bytes_in_flight_ > 0; |
-} |
- |
-const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( |
- QuicPacketSequenceNumber sequence_number) const { |
- return unacked_packets_[sequence_number - least_unacked_]; |
-} |
- |
-QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { |
- UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
- while (it != unacked_packets_.rend()) { |
- if (it->in_flight) { |
- LOG_IF(DFATAL, it->sent_time == QuicTime::Zero()) |
- << "Sent time can never be zero for a packet in flight."; |
- return it->sent_time; |
- } |
- ++it; |
- } |
- LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets."; |
- return QuicTime::Zero(); |
-} |
- |
-QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const { |
- UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
- while (it != unacked_packets_.end() && !it->in_flight) { |
- ++it; |
- } |
- if (it == unacked_packets_.end()) { |
- LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets."; |
- return QuicTime::Zero(); |
- } |
- return it->sent_time; |
-} |
- |
-size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const { |
- size_t unacked_packet_count = 0; |
- QuicPacketSequenceNumber sequence_number = least_unacked_; |
- for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
- it != unacked_packets_.end(); ++it, ++sequence_number) { |
- if (!IsPacketUseless(sequence_number, *it)) { |
- ++unacked_packet_count; |
- } |
- } |
- return unacked_packet_count; |
-} |
- |
-bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const { |
- size_t num_in_flight = 0; |
- for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); |
- it != unacked_packets_.rend(); ++it) { |
- if (it->in_flight) { |
- ++num_in_flight; |
- } |
- if (num_in_flight > 1) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { |
- return pending_crypto_packet_count_ > 0; |
-} |
- |
-bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { |
- for (UnackedPacketMap::const_reverse_iterator it = |
- unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { |
- if (it->in_flight && it->retransmittable_frames) { |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-QuicPacketSequenceNumber |
-QuicUnackedPacketMap::GetLeastUnacked() const { |
- return least_unacked_; |
-} |
- |
-void QuicUnackedPacketMap::RestoreInFlight( |
- QuicPacketSequenceNumber sequence_number) { |
- DCHECK_GE(sequence_number, least_unacked_); |
- DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size()); |
- TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_]; |
- DCHECK(!info->in_flight); |
- DCHECK_NE(0u, info->bytes_sent); |
- DCHECK(info->sent_time.IsInitialized()); |
- |
- bytes_in_flight_ += info->bytes_sent; |
- info->in_flight = true; |
-} |
- |
-} // namespace net |