More updates to bandwidth accounting.

This commit is contained in:
Adam Ierymenko 2013-09-11 16:08:31 -04:00
parent 9cdaefdb9a
commit 5885c6186d
2 changed files with 37 additions and 20 deletions

View file

@ -66,7 +66,7 @@ public:
* @param maxb Maximum allowed balance (> 0) * @param maxb Maximum allowed balance (> 0)
* @param acc Rate of accrual in bytes per second * @param acc Rate of accrual in bytes per second
*/ */
BandwidthAccount(int32_t preload,int32_t maxb,int32_t acc) BandwidthAccount(uint32_t preload,uint32_t maxb,uint32_t acc)
throw() throw()
{ {
init(preload,maxb,acc); init(preload,maxb,acc);
@ -79,7 +79,7 @@ public:
* @param maxb Maximum allowed balance (> 0) * @param maxb Maximum allowed balance (> 0)
* @param acc Rate of accrual in bytes per second * @param acc Rate of accrual in bytes per second
*/ */
inline void init(int32_t preload,int32_t maxb,int32_t acc) inline void init(uint32_t preload,uint32_t maxb,uint32_t acc)
throw() throw()
{ {
_lastTime = Utils::nowf(); _lastTime = Utils::nowf();
@ -89,27 +89,43 @@ public:
} }
/** /**
* Update balance by accruing and then deducting * Update and retrieve balance of this account
* *
* @param deduct Amount to deduct, or 0.0 to just update * @return New balance updated from current clock
* @return New balance after deduction -- if negative, it didn't fit
*/ */
inline int32_t update(int32_t deduct) inline uint32_t update()
throw() throw()
{ {
double lt = _lastTime; double lt = _lastTime;
double now = Utils::nowf(); double now = Utils::nowf();
_lastTime = now; _lastTime = now;
int32_t newbal = (int32_t)round((double)_balance + ((double)_accrual * (now - lt))) - deduct; return (_balance = std::min(_maxBalance,(uint32_t)round((double)_balance + ((double)_accrual * (now - lt)))));
_balance = std::max((int32_t)0,std::min(_maxBalance,newbal)); }
return newbal;
/**
* Update balance and conditionally deduct
*
* If the deduction amount fits, it is deducted after update. Otherwise
* balance is updated and false is returned.
*
* @param amt Amount to deduct
* @return True if amount fit within balance and was deducted
*/
inline bool deduct(uint32_t amt)
throw()
{
if (update() >= amt) {
_balance -= amt;
return true;
}
return false;
} }
private: private:
double _lastTime; double _lastTime;
int32_t _balance; uint32_t _balance;
int32_t _maxBalance; uint32_t _maxBalance;
int32_t _accrual; uint32_t _accrual;
}; };
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -34,6 +34,7 @@
#include <set> #include <set>
#include <map> #include <map>
#include <vector> #include <vector>
#include <algorithm>
#include <stdexcept> #include <stdexcept>
#include "Constants.hpp" #include "Constants.hpp"
@ -185,15 +186,15 @@ public:
struct Rate struct Rate
{ {
Rate() {} Rate() {}
Rate(int32_t pl,int32_t maxb,int32_t acc) Rate(uint32_t pl,uint32_t maxb,uint32_t acc)
{ {
preload = pl; preload = pl;
maxBalance = maxb; maxBalance = maxb;
accrual = acc; accrual = acc;
} }
int32_t preload; uint32_t preload;
int32_t maxBalance; uint32_t maxBalance;
int32_t accrual; uint32_t accrual;
}; };
MulticastRates() {} MulticastRates() {}
@ -243,13 +244,13 @@ public:
for(char *f=Utils::stok(tmp,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) { for(char *f=Utils::stok(tmp,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
switch(fn++) { switch(fn++) {
case 0: case 0:
r.preload = (int32_t)Utils::hexStrToLong(f); r.preload = (uint32_t)Utils::hexStrToULong(f);
break; break;
case 1: case 1:
r.maxBalance = (int32_t)Utils::hexStrToLong(f); r.maxBalance = (uint32_t)Utils::hexStrToULong(f);
break; break;
case 2: case 2:
r.accrual = (int32_t)Utils::hexStrToLong(f); r.accrual = (uint32_t)Utils::hexStrToULong(f);
break; break;
} }
} }
@ -579,7 +580,7 @@ public:
MulticastRates::Rate r(_mcRates.get(mg)); MulticastRates::Rate r(_mcRates.get(mg));
bal = _multicastRateAccounts.insert(std::pair< std::pair<Address,MulticastGroup>,BandwidthAccount >(k,BandwidthAccount(r.preload,r.maxBalance,r.accrual))).first; bal = _multicastRateAccounts.insert(std::pair< std::pair<Address,MulticastGroup>,BandwidthAccount >(k,BandwidthAccount(r.preload,r.maxBalance,r.accrual))).first;
} }
return (bal->second.update((int32_t)bytes) >= 0); return bal->second.deduct(bytes);
} }
private: private: