added senderUUID arg to seq stats

This commit is contained in:
wangyix 2014-06-27 15:39:11 -07:00
parent ff438a2434
commit 0ae58bd7f9
15 changed files with 284 additions and 238 deletions

View file

@ -148,11 +148,13 @@ void Agent::readPendingDatagrams() {
} else if (datagramPacketType == PacketTypeMixedAudio) { } else if (datagramPacketType == PacketTypeMixedAudio) {
QUuid senderUUID = uuidFromPacketHeader(receivedPacket);
// parse sequence number for this packet // parse sequence number for this packet
int numBytesPacketHeader = numBytesForPacketHeader(receivedPacket); int numBytesPacketHeader = numBytesForPacketHeader(receivedPacket);
const char* sequenceAt = receivedPacket.constData() + numBytesPacketHeader; const char* sequenceAt = receivedPacket.constData() + numBytesPacketHeader;
quint16 sequence = *(reinterpret_cast<const quint16*>(sequenceAt)); quint16 sequence = *(reinterpret_cast<const quint16*>(sequenceAt));
_incomingMixedAudioSequenceNumberStats.sequenceNumberReceived(sequence); _incomingMixedAudioSequenceNumberStats.sequenceNumberReceived(sequence, senderUUID);
printf("mixed audio received %d\n", sequence); printf("mixed audio received %d\n", sequence);
// parse the data and grab the average loudness // parse the data and grab the average loudness

View file

@ -623,7 +623,7 @@ void AudioMixer::run() {
dataAt += NETWORK_BUFFER_LENGTH_BYTES_STEREO; dataAt += NETWORK_BUFFER_LENGTH_BYTES_STEREO;
// send mixed audio packet // send mixed audio packet
//nodeList->writeDatagram(clientMixBuffer, dataAt - clientMixBuffer, node); nodeList->writeDatagram(clientMixBuffer, dataAt - clientMixBuffer, node);
printf("mixed audio sent %d\n", sequence); printf("mixed audio sent %d\n", sequence);
nodeData->incrementOutgoingSequenceNumber(); nodeData->incrementOutgoingSequenceNumber();

View file

@ -98,7 +98,6 @@ printf("injected stream %s received seq %d\n", streamIdentifier.toString().toLat
if (_ringBuffers[i]->getType() == PositionalAudioRingBuffer::Injector if (_ringBuffers[i]->getType() == PositionalAudioRingBuffer::Injector
&& ((InjectedAudioRingBuffer*) _ringBuffers[i])->getStreamIdentifier() == streamIdentifier) { && ((InjectedAudioRingBuffer*) _ringBuffers[i])->getStreamIdentifier() == streamIdentifier) {
matchingInjectedRingBuffer = (InjectedAudioRingBuffer*) _ringBuffers[i]; matchingInjectedRingBuffer = (InjectedAudioRingBuffer*) _ringBuffers[i];
printf("\t matching ring buffer found.\n");
} }
} }
@ -107,7 +106,6 @@ printf("\t matching ring buffer found.\n");
matchingInjectedRingBuffer = new InjectedAudioRingBuffer(streamIdentifier, matchingInjectedRingBuffer = new InjectedAudioRingBuffer(streamIdentifier,
AudioMixer::getUseDynamicJitterBuffers()); AudioMixer::getUseDynamicJitterBuffers());
_ringBuffers.push_back(matchingInjectedRingBuffer); _ringBuffers.push_back(matchingInjectedRingBuffer);
printf("\t no matching ring buffer, creating new one. _ringBuffer size now %d\n", _ringBuffers.size());
} }
matchingInjectedRingBuffer->parseData(packet); matchingInjectedRingBuffer->parseData(packet);

View file

@ -18,7 +18,7 @@
#include "AvatarAudioRingBuffer.h" #include "AvatarAudioRingBuffer.h"
#include "AudioStreamStats.h" #include "AudioStreamStats.h"
#include "SequenceNumbersStats.h" #include "SequenceNumberStats.h"
class AudioMixerClientData : public NodeData { class AudioMixerClientData : public NodeData {
public: public:

View file

@ -206,7 +206,7 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
} }
const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID); const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID);
const QSet<unsigned short int>& missingSequenceNumbers = nodeStats.getSequenceNumberStats().getMissingSet(); const QSet<unsigned short int>& missingSequenceNumbers = nodeStats.getIncomingEditSequenceNumberStats().getMissingSet();
// construct nack packet(s) for this node // construct nack packet(s) for this node
int numSequenceNumbersAvailable = missingSequenceNumbers.size(); int numSequenceNumbersAvailable = missingSequenceNumbers.size();
@ -254,7 +254,7 @@ SingleSenderStats::SingleSenderStats()
_totalLockWaitTime(0), _totalLockWaitTime(0),
_totalElementsInPacket(0), _totalElementsInPacket(0),
_totalPackets(0), _totalPackets(0),
_sequenceNumberStats() _incomingEditSequenceNumberStats()
{ {
} }
@ -263,7 +263,7 @@ void SingleSenderStats::trackInboundPacket(unsigned short int incomingSequence,
int editsInPacket, quint64 processTime, quint64 lockWaitTime) { int editsInPacket, quint64 processTime, quint64 lockWaitTime) {
// track sequence number // track sequence number
_sequenceNumberStats.sequenceNumberReceived(incomingSequence); _incomingEditSequenceNumberStats.sequenceNumberReceived(incomingSequence);
// update other stats // update other stats
_totalTransitTime += transitTime; _totalTransitTime += transitTime;

View file

@ -16,7 +16,7 @@
#include <ReceivedPacketProcessor.h> #include <ReceivedPacketProcessor.h>
#include "SequenceNumbersStats.h" #include "SequenceNumberStats.h"
class OctreeServer; class OctreeServer;
@ -34,7 +34,7 @@ public:
quint64 getAverageLockWaitTimePerElement() const quint64 getAverageLockWaitTimePerElement() const
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; } { return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
const SequenceNumberStats& getSequenceNumberStats() const { return _sequenceNumberStats; } const SequenceNumberStats& getIncomingEditSequenceNumberStats() const { return _incomingEditSequenceNumberStats; }
void trackInboundPacket(unsigned short int incomingSequence, quint64 transitTime, void trackInboundPacket(unsigned short int incomingSequence, quint64 transitTime,
int editsInPacket, quint64 processTime, quint64 lockWaitTime); int editsInPacket, quint64 processTime, quint64 lockWaitTime);
@ -44,7 +44,7 @@ public:
quint64 _totalLockWaitTime; quint64 _totalLockWaitTime;
quint64 _totalElementsInPacket; quint64 _totalElementsInPacket;
quint64 _totalPackets; quint64 _totalPackets;
SequenceNumberStats _sequenceNumberStats; SequenceNumberStats _incomingEditSequenceNumberStats;
}; };
typedef QHash<QUuid, SingleSenderStats> NodeToSenderStatsMap; typedef QHash<QUuid, SingleSenderStats> NodeToSenderStatsMap;

View file

@ -2164,7 +2164,8 @@ int Application::sendNackPackets() {
OctreeSceneStats& stats = _octreeServerSceneStats[nodeUUID]; OctreeSceneStats& stats = _octreeServerSceneStats[nodeUUID];
// make copy of missing sequence numbers from stats // make copy of missing sequence numbers from stats
const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = stats.getSequenceNumberStats().getMissingSet(); const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers =
stats.getIncomingOctreeSequenceNumberStats().getMissingSet();
_octreeSceneStatsLock.unlock(); _octreeSceneStatsLock.unlock();

View file

@ -829,11 +829,13 @@ void Audio::toggleStereoInput() {
void Audio::processReceivedAudio(const QByteArray& audioByteArray) { void Audio::processReceivedAudio(const QByteArray& audioByteArray) {
QUuid senderUUID = uuidFromPacketHeader(audioByteArray);
// parse sequence number for this packet // parse sequence number for this packet
int numBytesPacketHeader = numBytesForPacketHeader(audioByteArray); int numBytesPacketHeader = numBytesForPacketHeader(audioByteArray);
const char* sequenceAt = audioByteArray.constData() + numBytesPacketHeader; const char* sequenceAt = audioByteArray.constData() + numBytesPacketHeader;
quint16 sequence = *((quint16*)sequenceAt); quint16 sequence = *((quint16*)sequenceAt);
_incomingMixedAudioSequenceNumberStats.sequenceNumberReceived(sequence); _incomingMixedAudioSequenceNumberStats.sequenceNumberReceived(sequence, senderUUID);
printf("mixed audio received %d\n", sequence); printf("mixed audio received %d\n", sequence);
// parse audio data // parse audio data

View file

@ -365,7 +365,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets()); QString incomingPacketsString = locale.toString((uint)stats.getIncomingPackets());
QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes()); QString incomingBytesString = locale.toString((uint)stats.getIncomingBytes());
QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes()); QString incomingWastedBytesString = locale.toString((uint)stats.getIncomingWastedBytes());
const SequenceNumberStats& seqStats = stats.getSequenceNumberStats(); const SequenceNumberStats& seqStats = stats.getIncomingOctreeSequenceNumberStats();
QString incomingOutOfOrderString = locale.toString((uint)seqStats.getNumOutOfOrder()); QString incomingOutOfOrderString = locale.toString((uint)seqStats.getNumOutOfOrder());
QString incomingLateString = locale.toString((uint)seqStats.getNumLate()); QString incomingLateString = locale.toString((uint)seqStats.getNumLate());
QString incomingUnreasonableString = locale.toString((uint)seqStats.getNumUnreasonable()); QString incomingUnreasonableString = locale.toString((uint)seqStats.getNumUnreasonable());

View file

@ -9,7 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "SequenceNumbersStats.h" #include "SequenceNumberStats.h"
#include <limits> #include <limits>
@ -22,20 +22,40 @@ SequenceNumberStats::SequenceNumberStats()
_numLate(0), _numLate(0),
_numLost(0), _numLost(0),
_numRecovered(0), _numRecovered(0),
_numDuplicate(0) _numDuplicate(0),
_lastSenderUUID()
{ {
} }
void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, const bool wantExtraDebugging) { void SequenceNumberStats::reset() {
_missingSet.clear();
_numReceived = 0;
_numUnreasonable = 0;
_numEarly = 0;
_numLate = 0;
_numLost = 0;
_numRecovered = 0;
_numDuplicate = 0;
}
static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1; static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1;
static const int MAX_REASONABLE_SEQUENCE_GAP = 1000; // this must be less than UINT16_RANGE / 2 for rollover handling to work static const int MAX_REASONABLE_SEQUENCE_GAP = 1000; // this must be less than UINT16_RANGE / 2 for rollover handling to work
_numReceived++; void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderUUID, const bool wantExtraDebugging) {
// if the sender node has changed, reset all stats
if (senderUUID != _lastSenderUUID) {
qDebug() << "sequence number stats was reset due to new sender node";
qDebug() << "previous:" << _lastSenderUUID << "current:" << senderUUID;
reset();
_lastSenderUUID = senderUUID;
}
// determine our expected sequence number... handle rollover appropriately // determine our expected sequence number... handle rollover appropriately
quint16 expected = _numReceived > 0 ? _lastReceived + (quint16)1 : incoming; quint16 expected = _numReceived > 0 ? _lastReceived + (quint16)1 : incoming;
_numReceived++;
if (incoming == expected) { // on time if (incoming == expected) { // on time
_lastReceived = incoming; _lastReceived = incoming;
} else { // out of order } else { // out of order
@ -80,6 +100,13 @@ void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, const bool wa
for (int missingInt = expectedInt; missingInt < incomingInt; missingInt++) { for (int missingInt = expectedInt; missingInt < incomingInt; missingInt++) {
_missingSet.insert((quint16)(missingInt < 0 ? missingInt + UINT16_RANGE : missingInt)); _missingSet.insert((quint16)(missingInt < 0 ? missingInt + UINT16_RANGE : missingInt));
} }
// prune missing sequence list if it gets too big; sequence numbers that are older than MAX_REASONABLE_SEQUENCE_GAP
// will be removed.
if (_missingSet.size() > MAX_REASONABLE_SEQUENCE_GAP) {
pruneMissingSet(wantExtraDebugging);
}
_lastReceived = incoming; _lastReceived = incoming;
} else { // late } else { // late
if (wantExtraDebugging) { if (wantExtraDebugging) {
@ -104,55 +131,53 @@ void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, const bool wa
// do not update _incomingLastSequence; it shouldn't become smaller // do not update _incomingLastSequence; it shouldn't become smaller
} }
} }
}
// prune missing sequence list if it gets too big; sequence numbers that are older than MAX_REASONABLE_SEQUENCE_GAP void SequenceNumberStats::pruneMissingSet(const bool wantExtraDebugging) {
// will be removed. if (wantExtraDebugging) {
if (_missingSet.size() > MAX_REASONABLE_SEQUENCE_GAP) { qDebug() << "pruning _missingSet! size:" << _missingSet.size();
if (wantExtraDebugging) { }
qDebug() << "_missingSet is too large! size:" << _missingSet.size();
}
// some older sequence numbers may be from before a rollover point; this must be handled. // some older sequence numbers may be from before a rollover point; this must be handled.
// some sequence numbers in this list may be larger than _incomingLastSequence, indicating that they were received // some sequence numbers in this list may be larger than _incomingLastSequence, indicating that they were received
// before the most recent rollover. // before the most recent rollover.
int cutoff = (int)_lastReceived - MAX_REASONABLE_SEQUENCE_GAP; int cutoff = (int)_lastReceived - MAX_REASONABLE_SEQUENCE_GAP;
if (cutoff >= 0) { if (cutoff >= 0) {
quint16 nonRolloverCutoff = (quint16)cutoff; quint16 nonRolloverCutoff = (quint16)cutoff;
QSet<quint16>::iterator i = _missingSet.begin(); QSet<quint16>::iterator i = _missingSet.begin();
while (i != _missingSet.end()) { while (i != _missingSet.end()) {
quint16 missing = *i; quint16 missing = *i;
if (wantExtraDebugging) { if (wantExtraDebugging) {
qDebug() << "checking item:" << missing << "is it in need of pruning?"; qDebug() << "checking item:" << missing << "is it in need of pruning?";
qDebug() << "old age cutoff:" << nonRolloverCutoff; qDebug() << "old age cutoff:" << nonRolloverCutoff;
}
if (missing > _lastReceived || missing < nonRolloverCutoff) {
i = _missingSet.erase(i);
if (wantExtraDebugging) {
qDebug() << "pruning really old missing sequence:" << missing;
}
} else {
i++;
}
} }
} else {
quint16 rolloverCutoff = (quint16)(cutoff + UINT16_RANGE);
QSet<quint16>::iterator i = _missingSet.begin();
while (i != _missingSet.end()) {
quint16 missing = *i;
if (wantExtraDebugging) {
qDebug() << "checking item:" << missing << "is it in need of pruning?";
qDebug() << "old age cutoff:" << rolloverCutoff;
}
if (missing > _lastReceived && missing < rolloverCutoff) { if (missing > _lastReceived || missing < nonRolloverCutoff) {
i = _missingSet.erase(i); i = _missingSet.erase(i);
if (wantExtraDebugging) { if (wantExtraDebugging) {
qDebug() << "pruning really old missing sequence:" << missing; qDebug() << "pruning really old missing sequence:" << missing;
}
} else {
i++;
} }
} else {
i++;
}
}
} else {
quint16 rolloverCutoff = (quint16)(cutoff + UINT16_RANGE);
QSet<quint16>::iterator i = _missingSet.begin();
while (i != _missingSet.end()) {
quint16 missing = *i;
if (wantExtraDebugging) {
qDebug() << "checking item:" << missing << "is it in need of pruning?";
qDebug() << "old age cutoff:" << rolloverCutoff;
}
if (missing > _lastReceived && missing < rolloverCutoff) {
i = _missingSet.erase(i);
if (wantExtraDebugging) {
qDebug() << "pruning really old missing sequence:" << missing;
}
} else {
i++;
} }
} }
} }

View file

@ -13,12 +13,15 @@
#define hifi_SequenceNumberStats_h #define hifi_SequenceNumberStats_h
#include "SharedUtil.h" #include "SharedUtil.h"
#include <quuid.h>
class SequenceNumberStats { class SequenceNumberStats {
public: public:
SequenceNumberStats(); SequenceNumberStats();
void sequenceNumberReceived(quint16 incoming, const bool wantExtraDebugging = false); void reset();
void sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false);
quint32 getNumReceived() const { return _numReceived; } quint32 getNumReceived() const { return _numReceived; }
quint32 getNumUnreasonable() const { return _numUnreasonable; } quint32 getNumUnreasonable() const { return _numUnreasonable; }
@ -31,6 +34,8 @@ public:
const QSet<quint16>& getMissingSet() const { return _missingSet; } const QSet<quint16>& getMissingSet() const { return _missingSet; }
private: private:
void pruneMissingSet(const bool wantExtraDebugging);
quint16 _lastReceived; quint16 _lastReceived;
QSet<quint16> _missingSet; QSet<quint16> _missingSet;
@ -41,6 +46,8 @@ private:
quint32 _numLost; quint32 _numLost;
quint32 _numRecovered; quint32 _numRecovered;
quint32 _numDuplicate; quint32 _numDuplicate;
QUuid _lastSenderUUID;
}; };
#endif // hifi_SequenceNumberStats_h #endif // hifi_SequenceNumberStats_h

View file

@ -39,7 +39,7 @@ OctreeSceneStats::OctreeSceneStats() :
_incomingPacket(0), _incomingPacket(0),
_incomingBytes(0), _incomingBytes(0),
_incomingWastedBytes(0), _incomingWastedBytes(0),
_sequenceNumberStats(), _incomingOctreeSequenceNumberStats(),
_incomingFlightTimeAverage(samples), _incomingFlightTimeAverage(samples),
_jurisdictionRoot(NULL) _jurisdictionRoot(NULL)
{ {
@ -144,7 +144,7 @@ void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) {
_incomingBytes = other._incomingBytes; _incomingBytes = other._incomingBytes;
_incomingWastedBytes = other._incomingWastedBytes; _incomingWastedBytes = other._incomingWastedBytes;
_sequenceNumberStats = other._sequenceNumberStats; _incomingOctreeSequenceNumberStats = other._incomingOctreeSequenceNumberStats;
} }
@ -862,7 +862,7 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
return; // ignore any packets that are unreasonable return; // ignore any packets that are unreasonable
} }
_sequenceNumberStats.sequenceNumberReceived(sequence); _incomingOctreeSequenceNumberStats.sequenceNumberReceived(sequence);
// track packets here... // track packets here...
_incomingPacket++; _incomingPacket++;

View file

@ -17,7 +17,7 @@
#include <SharedUtil.h> #include <SharedUtil.h>
#include "JurisdictionMap.h" #include "JurisdictionMap.h"
#include "OctreePacketData.h" #include "OctreePacketData.h"
#include "SequenceNumbersStats.h" #include "SequenceNumberStats.h"
#define GREENISH 0x40ff40d0 #define GREENISH 0x40ff40d0
#define YELLOWISH 0xffef40c0 #define YELLOWISH 0xffef40c0
@ -167,7 +167,7 @@ public:
quint64 getIncomingWastedBytes() const { return _incomingWastedBytes; } quint64 getIncomingWastedBytes() const { return _incomingWastedBytes; }
float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); } float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); }
const SequenceNumberStats& getSequenceNumberStats() const { return _sequenceNumberStats; } const SequenceNumberStats& getIncomingOctreeSequenceNumberStats() const { return _incomingOctreeSequenceNumberStats; }
private: private:
@ -262,7 +262,7 @@ private:
quint64 _incomingBytes; quint64 _incomingBytes;
quint64 _incomingWastedBytes; quint64 _incomingWastedBytes;
SequenceNumberStats _sequenceNumberStats; SequenceNumberStats _incomingOctreeSequenceNumberStats;
SimpleMovingAverage _incomingFlightTimeAverage; SimpleMovingAverage _incomingFlightTimeAverage;

View file

@ -32,16 +32,20 @@ void SequenceNumberStatsTests::rolloverTest() {
// insert enough samples to cause 3 rollovers // insert enough samples to cause 3 rollovers
quint16 seq = 79; // start on some random number quint16 seq = 79; // start on some random number
for (int i = 0; i < 3 * UINT16_RANGE; i++) {
stats.sequenceNumberReceived(seq);
seq = seq + (quint16)1;
assert(stats.getNumDuplicate() == 0); for (int R = 0; R < 2; R++) {
assert(stats.getNumEarly() == 0); for (int i = 0; i < 3 * UINT16_RANGE; i++) {
assert(stats.getNumLate() == 0); stats.sequenceNumberReceived(seq);
assert(stats.getNumLost() == 0); seq = seq + (quint16)1;
assert(stats.getNumReceived() == i+1);
assert(stats.getNumRecovered() == 0); assert(stats.getNumDuplicate() == 0);
assert(stats.getNumEarly() == 0);
assert(stats.getNumLate() == 0);
assert(stats.getNumLost() == 0);
assert(stats.getNumReceived() == i + 1);
assert(stats.getNumRecovered() == 0);
}
stats.reset();
} }
} }
@ -56,59 +60,61 @@ void SequenceNumberStatsTests::earlyLateTest() {
int numLost = 0; int numLost = 0;
int numRecovered = 0; int numRecovered = 0;
for (int R = 0; R < 2; R++) {
for (int T = 0; T < 10000; T++) {
for (int T = 0; T < 10000; T++) { // insert 7 consecutive
for (int i = 0; i < 7; i++) {
stats.sequenceNumberReceived(seq);
seq = seq + (quint16)1;
numSent++;
// insert 7 consecutive assert(stats.getNumDuplicate() == 0);
for (int i = 0; i < 7; i++) { assert(stats.getNumEarly() == numEarly);
stats.sequenceNumberReceived(seq); assert(stats.getNumLate() == numLate);
seq = seq + (quint16)1; assert(stats.getNumLost() == numLost);
numSent++; assert(stats.getNumReceived() == numSent);
assert(stats.getNumRecovered() == numRecovered);
}
assert(stats.getNumDuplicate() == 0); // skip 10
assert(stats.getNumEarly() == numEarly); quint16 skipped = seq;
assert(stats.getNumLate() == numLate); seq = seq + (quint16)10;
assert(stats.getNumLost() == numLost);
assert(stats.getNumReceived() == numSent); // insert 36 consecutive
assert(stats.getNumRecovered() == numRecovered); numEarly++;
} numLost += 10;
for (int i = 0; i < 36; i++) {
// skip 10 stats.sequenceNumberReceived(seq);
quint16 skipped = seq; seq = seq + (quint16)1;
seq = seq + (quint16)10; numSent++;
// insert 36 consecutive assert(stats.getNumDuplicate() == 0);
numEarly++; assert(stats.getNumEarly() == numEarly);
numLost += 10; assert(stats.getNumLate() == numLate);
for (int i = 0; i < 36; i++) { assert(stats.getNumLost() == numLost);
stats.sequenceNumberReceived(seq); assert(stats.getNumReceived() == numSent);
seq = seq + (quint16)1; assert(stats.getNumRecovered() == numRecovered);
numSent++; }
assert(stats.getNumDuplicate() == 0); // send ones we skipped
assert(stats.getNumEarly() == numEarly); for (int i = 0; i < 10; i++) {
assert(stats.getNumLate() == numLate); stats.sequenceNumberReceived(skipped);
assert(stats.getNumLost() == numLost); skipped = skipped + (quint16)1;
assert(stats.getNumReceived() == numSent); numSent++;
assert(stats.getNumRecovered() == numRecovered); numLate++;
} numLost--;
numRecovered++;
// send ones we skipped
for (int i = 0; i < 10; i++) { assert(stats.getNumDuplicate() == 0);
stats.sequenceNumberReceived(skipped); assert(stats.getNumEarly() == numEarly);
skipped = skipped + (quint16)1; assert(stats.getNumLate() == numLate);
numSent++; assert(stats.getNumLost() == numLost);
numLate++; assert(stats.getNumReceived() == numSent);
numLost--; assert(stats.getNumRecovered() == numRecovered);
numRecovered++; }
assert(stats.getNumDuplicate() == 0);
assert(stats.getNumEarly() == numEarly);
assert(stats.getNumLate() == numLate);
assert(stats.getNumLost() == numLost);
assert(stats.getNumReceived() == numSent);
assert(stats.getNumRecovered() == numRecovered);
} }
stats.reset();
} }
} }
@ -123,79 +129,81 @@ void SequenceNumberStatsTests::duplicateTest() {
int numLate = 0; int numLate = 0;
int numLost = 0; int numLost = 0;
for (int R = 0; R < 2; R++) {
for (int T = 0; T < 10000; T++) {
for (int T = 0; T < 10000; T++) { quint16 duplicate = seq;
quint16 duplicate = seq; // insert 7 consecutive
for (int i = 0; i < 7; i++) {
stats.sequenceNumberReceived(seq);
seq = seq + (quint16)1;
numSent++;
// insert 7 consecutive assert(stats.getNumDuplicate() == numDuplicate);
for (int i = 0; i < 7; i++) { assert(stats.getNumEarly() == numEarly);
stats.sequenceNumberReceived(seq); assert(stats.getNumLate() == numLate);
seq = seq + (quint16)1; assert(stats.getNumLost() == numLost);
numSent++; assert(stats.getNumReceived() == numSent);
assert(stats.getNumRecovered() == 0);
}
assert(stats.getNumDuplicate() == numDuplicate); // skip 10
assert(stats.getNumEarly() == numEarly); quint16 skipped = seq;
assert(stats.getNumLate() == numLate); seq = seq + (quint16)10;
assert(stats.getNumLost() == numLost);
assert(stats.getNumReceived() == numSent);
assert(stats.getNumRecovered() == 0); quint16 duplicate2 = seq;
}
numEarly++;
// skip 10 numLost += 10;
quint16 skipped = seq; // insert 36 consecutive
seq = seq + (quint16)10; for (int i = 0; i < 36; i++) {
stats.sequenceNumberReceived(seq);
seq = seq + (quint16)1;
quint16 duplicate2 = seq; numSent++;
numEarly++; assert(stats.getNumDuplicate() == numDuplicate);
numLost += 10; assert(stats.getNumEarly() == numEarly);
// insert 36 consecutive assert(stats.getNumLate() == numLate);
for (int i = 0; i < 36; i++) { assert(stats.getNumLost() == numLost);
stats.sequenceNumberReceived(seq); assert(stats.getNumReceived() == numSent);
seq = seq + (quint16)1; assert(stats.getNumRecovered() == 0);
numSent++; }
assert(stats.getNumDuplicate() == numDuplicate); // send 5 duplicates from before skip
assert(stats.getNumEarly() == numEarly); for (int i = 0; i < 5; i++) {
assert(stats.getNumLate() == numLate); stats.sequenceNumberReceived(duplicate);
assert(stats.getNumLost() == numLost); duplicate = duplicate + (quint16)1;
assert(stats.getNumReceived() == numSent); numSent++;
assert(stats.getNumRecovered() == 0); numDuplicate++;
} numLate++;
// send 5 duplicates from before skip assert(stats.getNumDuplicate() == numDuplicate);
for (int i = 0; i < 5; i++) { assert(stats.getNumEarly() == numEarly);
stats.sequenceNumberReceived(duplicate); assert(stats.getNumLate() == numLate);
duplicate = duplicate + (quint16)1; assert(stats.getNumLost() == numLost);
numSent++; assert(stats.getNumReceived() == numSent);
numDuplicate++; assert(stats.getNumRecovered() == 0);
numLate++; }
assert(stats.getNumDuplicate() == numDuplicate); // send 5 duplicates from after skip
assert(stats.getNumEarly() == numEarly); for (int i = 0; i < 5; i++) {
assert(stats.getNumLate() == numLate); stats.sequenceNumberReceived(duplicate2);
assert(stats.getNumLost() == numLost); duplicate2 = duplicate2 + (quint16)1;
assert(stats.getNumReceived() == numSent); numSent++;
assert(stats.getNumRecovered() == 0); numDuplicate++;
} numLate++;
// send 5 duplicates from after skip assert(stats.getNumDuplicate() == numDuplicate);
for (int i = 0; i < 5; i++) { assert(stats.getNumEarly() == numEarly);
stats.sequenceNumberReceived(duplicate2); assert(stats.getNumLate() == numLate);
duplicate2 = duplicate2 + (quint16)1; assert(stats.getNumLost() == numLost);
numSent++; assert(stats.getNumReceived() == numSent);
numDuplicate++; assert(stats.getNumRecovered() == 0);
numLate++; }
assert(stats.getNumDuplicate() == numDuplicate);
assert(stats.getNumEarly() == numEarly);
assert(stats.getNumLate() == numLate);
assert(stats.getNumLost() == numLost);
assert(stats.getNumReceived() == numSent);
assert(stats.getNumRecovered() == 0);
} }
stats.reset();
} }
} }
@ -209,50 +217,53 @@ void SequenceNumberStatsTests::pruneTest() {
int numLate = 0; int numLate = 0;
int numLost = 0; int numLost = 0;
for (int T = 0; T < 1000; T++) { for (int R = 0; R < 2; R++) {
// insert 1 seq for (int T = 0; T < 1000; T++) {
stats.sequenceNumberReceived(seq); // insert 1 seq
seq = seq + (quint16)1; stats.sequenceNumberReceived(seq);
numSent++; seq = seq + (quint16)1;
numSent++;
// skip 1000 seq // skip 1000 seq
seq = seq + (quint16)1000; seq = seq + (quint16)1000;
quint16 highestSkipped = seq - (quint16)1; quint16 highestSkipped = seq - (quint16)1;
// insert 1 seq // insert 1 seq
stats.sequenceNumberReceived(seq); stats.sequenceNumberReceived(seq);
seq = seq + (quint16)1; seq = seq + (quint16)1;
numSent++; numSent++;
numEarly++; numEarly++;
numLost += 1000; numLost += 1000;
// skip 10 seq // skip 10 seq
seq = seq + (quint16)10; seq = seq + (quint16)10;
quint16 highestSkipped2 = seq - (quint16)1; quint16 highestSkipped2 = seq - (quint16)1;
// insert 1 seq // insert 1 seq
// insert 1 seq // insert 1 seq
stats.sequenceNumberReceived(seq); stats.sequenceNumberReceived(seq);
seq = seq + (quint16)1; seq = seq + (quint16)1;
numSent++; numSent++;
numEarly++; numEarly++;
numLost += 10; numLost += 10;
const QSet<quint16>& missingSet = stats.getMissingSet(); const QSet<quint16>& missingSet = stats.getMissingSet();
assert(missingSet.size() <= 1000); assert(missingSet.size() <= 1000);
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
assert(missingSet.contains(highestSkipped2)); assert(missingSet.contains(highestSkipped2));
highestSkipped2 = highestSkipped2 - (quint16)1; highestSkipped2 = highestSkipped2 - (quint16)1;
} }
for (int i = 0; i < 989; i++) { for (int i = 0; i < 989; i++) {
assert(missingSet.contains(highestSkipped)); assert(missingSet.contains(highestSkipped));
highestSkipped = highestSkipped - (quint16)1; highestSkipped = highestSkipped - (quint16)1;
} }
for (int i = 0; i < 11; i++) { for (int i = 0; i < 11; i++) {
assert(!missingSet.contains(highestSkipped)); assert(!missingSet.contains(highestSkipped));
highestSkipped = highestSkipped - (quint16)1; highestSkipped = highestSkipped - (quint16)1;
}
} }
stats.reset();
} }
} }

View file

@ -13,7 +13,7 @@
#define hifi_SequenceNumberStatsTests_h #define hifi_SequenceNumberStatsTests_h
#include "SequenceNumberStatsTests.h" #include "SequenceNumberStatsTests.h"
#include "SequenceNumbersStats.h" #include "SequenceNumberStats.h"
namespace SequenceNumberStatsTests { namespace SequenceNumberStatsTests {