Commit 9c6f20f0 authored by Jonathon Duerig's avatar Jonathon Duerig
Browse files

Added a first rough draft of the least squares path saturation sensor. There...

Added a first rough draft of the least squares path saturation sensor. There are a lot of rough edges detailed earlier in a message to Rob. This is totally untested code.
parent a2e29d0a
// LeastSquaresThroughput.cc
#include "lib.h"
#include "LeastSquaresThroughput.h"
#include "ThroughputSensor.h"
#include "DelaySensor.h"
#include "CommandOutput.h"
using namespace std;
LeastSquaresThroughput::LeastSquaresThroughput(
ThroughputSensor const * newThroughput,
DelaySensor const * newDelay)
: throughput(newThroughput)
, delay(newDelay)
, oldest(0)
, totalSamples(0)
{
}
LeastSquaresThroughput::~LeastSquaresThroughput()
{
}
void LeastSquaresThroughput::localSend(PacketInfo * packet)
{
ackValid = false;
sendValid = true;
}
void LeastSquaresThroughput::localAck(PacketInfo * packet)
{
sendValid = false;
if (throughput->isAckValid() && delay->isAckValid())
{
throughputSamples[oldest] = throughput->getThroughputInKbps();
delaySamples[oldest] = delay->getLastDelay();
oldest = (oldest + 1) % SAMPLE_COUNT;
++totalSamples;
if (totalSamples >= SAMPLE_COUNT)
{
int i = 0;
double throughputAverage = 0;
double numA = 0.0;
double numB = 0.0;
double numC = 0.0;
double numD = SAMPLE_COUNT;
double denomA = 0.0;
double denomB = 0.0;
double denomC = 0.0;
double denomD = SAMPLE_COUNT;
for (; i < SAMPLE_COUNT; ++i)
{
int index = (oldest + i) % SAMPLE_COUNT;
throughputAverage += throughputSamples[index];
logWrite(SENSOR_DETAIL, "LeastSquares: Delay sample #%d: %d", i,
delaySamples[index]);
numA += i * delaySamples[index];
numB += i;
numC += delaySamples[index];
denomA += i * i;
denomB += i;
denomC += i;
}
throughputAverage /= SAMPLE_COUNT;
double num = (numA * numD) - (numB * numC);
double denom = (denomA * denomD) - (denomB * denomC);
// Theoretically denom cannot be 0 because our x values are
// sample numbers which monotonically increase.
double slope = num/denom;
logWrite(SENSOR, "LeastSquares: SLOPE: %f", slope);
if (slope > 0)
{
// The closest linear approximation indicates that buffers are
// being filled up, which means that the link was saturated
// over the last SAMPLE_COUNT samples. So use the average to
// yield a result.
ostringstream buffer;
buffer << static_cast<int>(throughputAverage);
global::output->genericMessage(AUTHORITATIVE_BANDWIDTH, buffer.str(),
packet->elab);
ackValid = true;
}
else
{
ackValid = false;
}
}
else
{
ackValid = false;
}
}
else
{
ackValid = false;
}
}
// LeastSquaresThroughput.h
// Algorithm based on the equations at:
// http://www.shodor.org/succeed/compchem/tools/llsalg.html
#ifndef LEAST_SQUARES_THROUGHPUT_H_STUB_2
#define LEAST_SQUARES_THROUGHPUT_H_STUB_2
#include "Sensor.h"
class ThroughputSensor;
class DelaySensor;
class LeastSquaresThroughput : public Sensor
{
public:
LeastSquaresThroughput(ThroughputSensor const * newThroughput,
DelaySensor const * newDelay);
virtual ~LeastSquaresThroughput();
protected:
virtual void localSend(PacketInfo * packet)=0;
virtual void localAck(PacketInfo * packet)=0;
private:
ThroughputSensor const * throughput;
DelaySensor const * delay;
// The number of samples kept at any given time.
static const int SAMPLE_COUNT = 5;
// Circular buffers of the last SAMPLE_COUNT samples.
int throughputSamples[SAMPLE_COUNT];
int delaySamples[SAMPLE_COUNT];
// The index of the oldest stored sample.
int oldest;
// The total number of samples ever encountered.
int totalSamples;
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment