From 18a9d74b88cb48841a22a8e881e59df85bc0e3b3 Mon Sep 17 00:00:00 2001 From: wangyix Date: Mon, 16 Jun 2014 16:35:30 -0700 Subject: [PATCH] changed OctreeEditPacketSender to queue packets for resend as nack is parsed --- libraries/networking/src/SentPacketHistory.h | 2 +- .../octree/src/OctreeEditPacketSender.cpp | 79 ++++++++----------- libraries/octree/src/OctreeEditPacketSender.h | 17 +--- 3 files changed, 38 insertions(+), 60 deletions(-) diff --git a/libraries/networking/src/SentPacketHistory.h b/libraries/networking/src/SentPacketHistory.h index e3c7736b72..53a6919c42 100644 --- a/libraries/networking/src/SentPacketHistory.h +++ b/libraries/networking/src/SentPacketHistory.h @@ -18,7 +18,7 @@ class SentPacketHistory { public: - SentPacketHistory(int size); + SentPacketHistory(int size = 1000); void packetSent(uint16_t sequenceNumber, const QByteArray& packet); const QByteArray* getPacket(uint16_t sequenceNumber) const; diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 69b58aaa41..439148a9a5 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -17,44 +17,6 @@ #include #include "OctreeEditPacketSender.h" -void NackedPacketHistory::packetSent(const QByteArray& packet) { - // extract sequence number for the sent packet history - int numBytesPacketHeader = numBytesForPacketHeader(packet); - const char* dataAt = reinterpret_cast(packet.data()); - unsigned short int sequence = (*((unsigned short int*)(dataAt + numBytesPacketHeader))); - - // add packet to history - _sentPacketHistory.packetSent(sequence, packet); -} - -bool NackedPacketHistory::hasNextNackedPacket() const { - return !_nackedSequenceNumbers.isEmpty(); -} - -const QByteArray* NackedPacketHistory::getNextNackedPacket() { - if (!_nackedSequenceNumbers.isEmpty()) { - // could return null if packet is not in the history - return _sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue()); - } - return NULL; -} - -void NackedPacketHistory::parseNackPacket(const QByteArray& packet) { - int numBytesPacketHeader = numBytesForPacketHeader(packet); - const unsigned char* dataAt = reinterpret_cast(packet.data()) + numBytesPacketHeader; - - // read number of sequence numbers - uint16_t numSequenceNumbers = (*(uint16_t*)dataAt); - dataAt += sizeof(uint16_t); - - // read sequence numbers - for (int i = 0; i < numSequenceNumbers; i++) { - unsigned short int sequenceNumber = (*(unsigned short int*)dataAt); - _nackedSequenceNumbers.enqueue(sequenceNumber); - dataAt += sizeof(unsigned short int); - } -} - EditPacketBuffer::EditPacketBuffer(PacketType type, unsigned char* buffer, ssize_t length, QUuid nodeUUID) : _nodeUUID(nodeUUID), _currentType(type), @@ -126,7 +88,7 @@ bool OctreeEditPacketSender::serversExist() const { // This method is called when the edit packet layer has determined that it has a fully formed packet destined for // a known nodeID. -void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer, ssize_t length) { +void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, const unsigned char* buffer, ssize_t length) { NodeList* nodeList = NodeList::getInstance(); foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { @@ -134,14 +96,19 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c if (node->getType() == getMyNodeType() && ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) { if (node->getActiveSocket()) { - QByteArray packet(reinterpret_cast(buffer), length); + QByteArray packet(reinterpret_cast(buffer), length); queuePacketForSending(node, packet); - _nackedPacketHistories[nodeUUID].packetSent(packet); + + // extract sequence number and add packet to history + int numBytesPacketHeader = numBytesForPacketHeader(packet); + const char* dataAt = reinterpret_cast(packet.data()); + unsigned short int sequence = (*((unsigned short int*)(dataAt + numBytesPacketHeader))); + _sentPacketHistories[nodeUUID].packetSent(sequence, packet); // debugging output... bool wantDebugging = false; if (wantDebugging) { - int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(buffer)); + int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(buffer)); unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader))); quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence)))); quint64 queuedAt = usecTimestampNow(); @@ -377,7 +344,31 @@ bool OctreeEditPacketSender::process() { } void OctreeEditPacketSender::parseNackPacket(const QByteArray& packet) { - // parse sending node from packet + // parse sending node from packet, retrieve packet history for that node QUuid sendingNodeUUID = uuidFromPacketHeader(packet); - _nackedPacketHistories[sendingNodeUUID].parseNackPacket(packet); + + // if packet history doesn't exist for the sender node (somehow), bail + if (!_sentPacketHistories.contains(sendingNodeUUID)) { + return; + } + const SentPacketHistory& sentPacketHistory = _sentPacketHistories.value(sendingNodeUUID); + + int numBytesPacketHeader = numBytesForPacketHeader(packet); + const unsigned char* dataAt = reinterpret_cast(packet.data()) + numBytesPacketHeader; + + // read number of sequence numbers + uint16_t numSequenceNumbers = (*(uint16_t*)dataAt); + dataAt += sizeof(uint16_t); + + // read sequence numbers and queue packets for resend + for (int i = 0; i < numSequenceNumbers; i++) { + unsigned short int sequenceNumber = (*(unsigned short int*)dataAt); + dataAt += sizeof(unsigned short int); + + // retrieve packet from history + const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber); + if (packet) { + queuePacketToNode(sendingNodeUUID, (const unsigned char*)packet->constData(), packet->length()); + } + } } diff --git a/libraries/octree/src/OctreeEditPacketSender.h b/libraries/octree/src/OctreeEditPacketSender.h index a737131dff..45913b8db2 100644 --- a/libraries/octree/src/OctreeEditPacketSender.h +++ b/libraries/octree/src/OctreeEditPacketSender.h @@ -18,19 +18,6 @@ #include "JurisdictionMap.h" #include "SentPacketHistory.h" -class NackedPacketHistory { -public: - NackedPacketHistory() : _sentPacketHistory(1000), _nackedSequenceNumbers() { } -public: - void packetSent(const QByteArray& packet); - bool hasNextNackedPacket() const; - const QByteArray* getNextNackedPacket(); - void parseNackPacket(const QByteArray& packet); -private: - SentPacketHistory _sentPacketHistory; - QQueue _nackedSequenceNumbers; -}; - /// Used for construction of edit packets class EditPacketBuffer { public: @@ -110,7 +97,7 @@ public: protected: bool _shouldSend; - void queuePacketToNode(const QUuid& nodeID, unsigned char* buffer, ssize_t length); + void queuePacketToNode(const QUuid& nodeID, const unsigned char* buffer, ssize_t length); void queuePendingPacketToNodes(PacketType type, unsigned char* buffer, ssize_t length); void queuePacketToNodes(unsigned char* buffer, ssize_t length); void initializePacket(EditPacketBuffer& packetBuffer, PacketType type); @@ -134,6 +121,6 @@ protected: int _maxPacketSize; // TODO: garbage-collect this and _pendingEditPackets - QHash _nackedPacketHistories; + QHash _sentPacketHistories; }; #endif // hifi_OctreeEditPacketSender_h