use a list of pairs of pairs for ACK2

This commit is contained in:
Stephen Birarda 2015-07-31 18:13:11 -07:00
parent 5e716c36f9
commit e74f47b64c
2 changed files with 34 additions and 20 deletions

View file

@ -161,8 +161,11 @@ void Connection::sendACK(bool wasCausedBySyncTimeout) {
// have the socket send off our packet
_parentSocket->writeBasePacket(*ackPacket, _destination);
Q_ASSERT_X(_sentACKs.empty() || _sentACKs.back().first + 1 == _currentACKSubSequenceNumber,
"Connection::sendACK", "Adding an invalid ACK to _sentACKs");
// write this ACK to the map of sent ACKs
_sentACKs[_currentACKSubSequenceNumber] = { nextACKNumber, high_resolution_clock::now() };
_sentACKs.push_back({ _currentACKSubSequenceNumber, { nextACKNumber, high_resolution_clock::now() }});
// reset the number of data packets received since last ACK
_packetsSinceACK = 0;
@ -372,7 +375,7 @@ void Connection::processACK(std::unique_ptr<ControlPacket> controlPacket) {
// read the ACKed sequence number
SequenceNumber ack;
controlPacket->readPrimitive(&ack);
// validate that this isn't a BS ACK
if (ack > getSendQueue().getCurrentSequenceNumber()) {
// in UDT they specifically break the connection here - do we want to do anything?
@ -463,23 +466,32 @@ void Connection::processACK2(std::unique_ptr<ControlPacket> controlPacket) {
controlPacket->readPrimitive(&subSequenceNumber);
// check if we had that subsequence number in our map
auto it = _sentACKs.find(subSequenceNumber);
auto it = std::find_if_not(_sentACKs.begin(), _sentACKs.end(), [subSequenceNumber](const ACKListPair& pair){
return subSequenceNumber < pair.first;
});
if (it != _sentACKs.end()) {
// update the RTT using the ACK window
SequenceNumberTimePair& pair = it->second;
// calculate the RTT (time now - time ACK sent)
auto now = high_resolution_clock::now();
int rtt = duration_cast<microseconds>(now - pair.second).count();
updateRTT(rtt);
// set the RTT for congestion control
_congestionControl->setRTT(_rtt);
// update the last ACKed ACK
if (pair.first > _lastReceivedAcknowledgedACK) {
_lastReceivedAcknowledgedACK = pair.first;
if (it->first == subSequenceNumber){
// update the RTT using the ACK window
// calculate the RTT (time now - time ACK sent)
auto now = high_resolution_clock::now();
int rtt = duration_cast<microseconds>(now - it->second.second).count();
updateRTT(rtt);
// set the RTT for congestion control
_congestionControl->setRTT(_rtt);
// update the last ACKed ACK
if (it->second.first > _lastReceivedAcknowledgedACK) {
_lastReceivedAcknowledgedACK = it->second.first;
}
// erase this sub-sequence number and anything below it now that we've gotten our timing information
_sentACKs.erase(_sentACKs.begin(), it);
} else {
Q_UNREACHABLE();
}
}

View file

@ -13,6 +13,7 @@
#define hifi_Connection_h
#include <chrono>
#include <list>
#include <memory>
#include <QtCore/QObject>
@ -35,7 +36,8 @@ class Connection : public QObject {
Q_OBJECT
public:
using SequenceNumberTimePair = std::pair<SequenceNumber, std::chrono::high_resolution_clock::time_point>;
using SentACKMap = std::unordered_map<SequenceNumber, SequenceNumberTimePair>;
using ACKListPair = std::pair<SequenceNumber, SequenceNumberTimePair>;
using SentACKList = std::list<ACKListPair>;
Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
~Connection();
@ -100,7 +102,7 @@ private:
int _bandwidth { 1 }; // Exponential moving average for estimated bandwidth, in packets per second
int _deliveryRate { 16 }; // Exponential moving average for receiver's receive rate, in packets per second
SentACKMap _sentACKs; // Map of ACK sub-sequence numbers to ACKed sequence number and sent time
SentACKList _sentACKs; // Map of ACK sub-sequence numbers to ACKed sequence number and sent time
Socket* _parentSocket { nullptr };
HifiSockAddr _destination;