87 lines
2.1 KiB
C++
87 lines
2.1 KiB
C++
/*
|
|
ZNetBandwidthMeter.cpp
|
|
Author: Patrick Baggett <ptbaggett@762studios.com>
|
|
Created: 7/10/2013
|
|
|
|
Purpose:
|
|
|
|
** NOT PART OF PUBLIC SDK **
|
|
This class is not part of the public SDK; its fields and methods are not present
|
|
in the documentation and cannot be guaranteed in future revisions.
|
|
** NOT PART OF PUBLIC SDK **
|
|
|
|
Bandwidth metering using a simple token bucket algorithm. A single value is
|
|
metered, so a incoming / outgoing each need an instance.
|
|
|
|
License:
|
|
|
|
Copyright 2013, 762 Studios
|
|
*/
|
|
|
|
#include <ZNet/ZNetBandwidthMeter.hpp>
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZNetBandwidthMeter::SetLimit(uint32_t newLimit)
|
|
{
|
|
limit = newLimit;
|
|
|
|
//Clamp existing token bucket
|
|
if(tokens > newLimit)
|
|
tokens = newLimit;
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZNetBandwidthMeter::Reset(uint64_t newStartTime)
|
|
{
|
|
lastTime = newStartTime;
|
|
tokens = limit;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
bool ZNetBandwidthMeter::TryAllocate(uint32_t bytes)
|
|
{
|
|
if(bytes <= tokens)
|
|
{
|
|
tokens -= bytes;
|
|
return true;
|
|
}
|
|
|
|
//Not enough
|
|
return false;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
void ZNetBandwidthMeter::Update(uint64_t newTime)
|
|
{
|
|
//Sanity check -- the time _did_ monotonically increase, right?
|
|
if(newTime > lastTime)
|
|
{
|
|
uint32_t delta = (uint32_t)(newTime - lastTime);
|
|
|
|
//If less than a second has passed...
|
|
if(delta < 1000)
|
|
{
|
|
//We could do: delta / 1000.0 * limit, but that involves int -> float conversions
|
|
//instead we do u32 x u32 = u64 multiply and divide by 1000, keeping it all in fixed
|
|
//point happiness. Because delta < 1000, dividing by 1000 should put it back in the
|
|
//range of a u32.
|
|
uint32_t amount = (uint64_t)delta * (uint64_t)limit / 1000;
|
|
|
|
//Add newly generated tokens, but clamp to the limit.
|
|
tokens += amount;
|
|
if(tokens > limit)
|
|
tokens = limit;
|
|
}
|
|
else //More than a second, so restore all tokens
|
|
tokens = limit;
|
|
|
|
//Save this as the new time
|
|
lastTime = newTime;
|
|
}
|
|
}
|