mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 20:48:56 +02:00
added senderUUID arg to seq stats
This commit is contained in:
parent
ff438a2434
commit
0ae58bd7f9
15 changed files with 284 additions and 238 deletions
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
|
@ -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++;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue