From 98b3c526ec8206f2091bff59dece85b278b7196d Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 3 Dec 2012 16:16:50 -0800 Subject: [PATCH] Finish the load manager class. --- src/cpp/ripple/LoadManager.cpp | 105 +++++++++++++++++++++++++++++++++ src/cpp/ripple/LoadManager.h | 25 ++++---- 2 files changed, 118 insertions(+), 12 deletions(-) diff --git a/src/cpp/ripple/LoadManager.cpp b/src/cpp/ripple/LoadManager.cpp index 3e251c218..7ccb72060 100644 --- a/src/cpp/ripple/LoadManager.cpp +++ b/src/cpp/ripple/LoadManager.cpp @@ -1,2 +1,107 @@ #include "LoadManager.h" +int LoadManager::getCreditRate() const +{ + boost::mutex::scoped_lock sl(mLock); + return mCreditRate; +} + +int LoadManager::getCreditLimit() const +{ + boost::mutex::scoped_lock sl(mLock); + return mCreditLimit; +} + +int LoadManager::getDebitWarn() const +{ + boost::mutex::scoped_lock sl(mLock); + return mDebitWarn; +} + +int LoadManager::getDebitLimit() const +{ + boost::mutex::scoped_lock sl(mLock); + return mDebitLimit; +} + +void LoadManager::setCreditRate(int r) +{ + boost::mutex::scoped_lock sl(mLock); + mCreditRate = r; +} + +void LoadManager::setCreditLimit(int r) +{ + boost::mutex::scoped_lock sl(mLock); + mCreditLimit = r; +} + +void LoadManager::setDebitWarn(int r) +{ + boost::mutex::scoped_lock sl(mLock); + mDebitWarn = r; +} + +void LoadManager::setDebitLimit(int r) +{ + boost::mutex::scoped_lock sl(mLock); + mDebitLimit = r; +} + +void LoadManager::canonicalize(LoadSource& source, const time_t now) const +{ + if (source.mLastUpdate != now) + { + if (source.mLastUpdate < now) + { + source.mBalance += mCreditRate * (now - source.mLastUpdate); + if (source.mBalance > mCreditLimit) + source.mBalance = mCreditLimit; + } + source.mLastUpdate = now; + } +} + +bool LoadManager::shouldWarn(LoadSource& source) const +{ + time_t now = time(NULL); + boost::mutex::scoped_lock sl(mLock); + + canonicalize(source, now); + if (source.isPrivileged() || (source.mBalance < mDebitWarn) || (source.mLastWarning == now)) + return false; + source.mLastWarning = now; + return true; +} + +bool LoadManager::shouldCutoff(LoadSource& source) const +{ + time_t now = time(NULL); + boost::mutex::scoped_lock sl(mLock); + + canonicalize(source, now); + return !source.isPrivileged() && (source.mBalance < mDebitLimit); +} + +bool LoadManager::adjust(LoadSource& source, int credits) const +{ + time_t now = time(NULL); + boost::mutex::scoped_lock sl(mLock); + + // We do it this way in case we want to add exponential decay later + canonicalize(source, now); + source.mBalance += credits; + if (source.mBalance > mCreditLimit) + source.mBalance = mCreditLimit; + + if (source.isPrivileged()) // privileged sources never warn/cutoff + return false; + + if (source.mBalance < mDebitLimit) // over-limit + return true; + + if ((source.mBalance < mDebitWarn) && (source.mLastWarning != now)) // need to warn + return true; + + return false; +} diff --git a/src/cpp/ripple/LoadManager.h b/src/cpp/ripple/LoadManager.h index 11312ba31..5b9e2207b 100644 --- a/src/cpp/ripple/LoadManager.h +++ b/src/cpp/ripple/LoadManager.h @@ -19,8 +19,8 @@ protected: time_t mLastWarning; public: - LoadSource() : mBalance(0), mFlags(0), mLastUpdate(0), mLastWarning(0) - { ; } + LoadSource() : mBalance(0), mFlags(0), mLastWarning(0) + { mLastUpdate = time(NULL); } bool isPrivileged() const { return (mFlags & lsfPrivileged) != 0; } void setPrivileged() { mFlags |= lsfPrivileged; } @@ -35,28 +35,29 @@ protected: int mCreditRate; // credits gained/lost per second int mCreditLimit; // the most credits a source can have int mDebitWarn; // when a source drops below this, we warn - int mDebitLimit; // when a source drops below this, we cut it off + int mDebitLimit; // when a source drops below this, we cut it off (should be negative) - boost::mutex mLock; + mutable boost::mutex mLock; + + void canonicalize(LoadSource&, const time_t now) const; public: LoadManager(int creditRate, int creditLimit, int debitWarn, int debitLimit) : mCreditRate(creditRate), mCreditLimit(creditLimit), mDebitWarn(debitWarn), mDebitLimit(debitLimit) { ; } - int getCreditRate(); - int getCreditLimit(); - int getDebitWarn(); - int getDebitLimit(); + int getCreditRate() const; + int getCreditLimit() const; + int getDebitWarn() const; + int getDebitLimit() const; void setCreditRate(int); void setCreditLimit(int); void setDebitWarn(int); void setDebitLimit(int); - bool shouldWarn(const LoadSource&); - bool shouldCutoff(const LoadSource&); - void credit(LoadSource&, int credits); - bool debit(LoadSource&, int credits); // return value: false = balance okay, true = warn/cutoff + bool shouldWarn(LoadSource&) const; + bool shouldCutoff(LoadSource&) const; + bool adjust(LoadSource&, int credits) const; // return value: false = balance okay, true = warn/cutoff }; #endif