#include "components/sync/engine/cycle/commit_quota.h"
#include <algorithm>
#include "base/check_op.h"
#include "base/time/time.h"
namespace syncer {
CommitQuota::CommitQuota(int max_tokens, base::TimeDelta refill_interval)
: max_tokens_(max_tokens),
refill_interval_(refill_interval),
tokens_(max_tokens),
last_refilled_(base::TimeTicks::Now()) {
DCHECK_GT(max_tokens_, 0);
DCHECK_GT(refill_interval_, base::TimeDelta());
}
CommitQuota::~CommitQuota() = default;
void CommitQuota::SetParams(int new_max_tokens,
base::TimeDelta refill_interval) {
DCHECK_GT(new_max_tokens, 0);
DCHECK_GT(refill_interval, base::TimeDelta());
if (max_tokens_ > new_max_tokens) {
tokens_ = std::min(tokens_, new_max_tokens);
} else if (max_tokens_ < new_max_tokens) {
const int additional_tokens = new_max_tokens - max_tokens_;
tokens_ += additional_tokens;
}
max_tokens_ = new_max_tokens;
refill_interval_ = refill_interval;
DCHECK_GE(tokens_, 0);
DCHECK_LE(tokens_, max_tokens_);
}
bool CommitQuota::HasTokensAvailable() {
RefillTokens();
return tokens_ > 0;
}
void CommitQuota::ConsumeToken() {
RefillTokens();
if (tokens_ > 0) {
--tokens_;
return;
}
last_refilled_ = base::TimeTicks::Now();
}
void CommitQuota::RefillTokens() {
const base::TimeDelta since_last_refilled =
base::TimeTicks::Now() - last_refilled_;
const int new_tokens = since_last_refilled / refill_interval_;
if (new_tokens == 0) {
return;
}
tokens_ = std::min(tokens_ + new_tokens, max_tokens_);
last_refilled_ += new_tokens * refill_interval_;
DCHECK_GE(tokens_, 0);
}
}