1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#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(const CommitQuota&) = default;
CommitQuota& CommitQuota::operator=(const CommitQuota&) = default;
CommitQuota::CommitQuota(CommitQuota&&) = default;
CommitQuota& CommitQuota::operator=(CommitQuota&&) = default;
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) {
// Cap current tokens by the newly lowered `new_max_tokens` count.
tokens_ = std::min(tokens_, new_max_tokens);
} else if (max_tokens_ < new_max_tokens) {
// Raise current tokens by the newly raised `max_tokens` count. This
// respects the current level of consumed tokens and does not automatically
// reset the token count to `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;
}
// When no token is available to consume, at least push away the next refill
// time to make sure any `HasTokensAvailable()` calls in the next
// `refill_interval_` period return false.
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);
}
} // namespace syncer
|