Initial commit
This commit is contained in:
86
ZNet/ZNetBandwidthMeter.cpp
Normal file
86
ZNet/ZNetBandwidthMeter.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user