b8f4b252ef
Change-Id: I75130cc8d5964ef0f95a672858da8bbce8ffd78c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/200520 Commit-Queue: Devon Carew <devoncarew@google.com> Reviewed-by: Phil Quitslund <pquitslund@google.com>
45 lines
1.4 KiB
Dart
45 lines
1.4 KiB
Dart
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:math' as math;
|
|
|
|
/// A throttling algorithm. This models the throttling after a bucket with
|
|
/// water dripping into it at the rate of 1 drop per replenish duration. If the
|
|
/// bucket has water when an operation is requested, 1 drop of water is removed
|
|
/// and the operation is performed. If not the operation is skipped. This
|
|
/// algorithm lets operations be performed in bursts without throttling, but
|
|
/// holds the overall average rate of operations to 1 per replenish duration.
|
|
class ThrottlingBucket {
|
|
final int bucketSize;
|
|
final Duration replenishDuration;
|
|
|
|
late int _drops = bucketSize;
|
|
late int _lastReplenish = DateTime.now().millisecondsSinceEpoch;
|
|
|
|
ThrottlingBucket(this.bucketSize, this.replenishDuration);
|
|
|
|
bool removeDrop() {
|
|
_checkReplenish();
|
|
|
|
if (_drops <= 0) {
|
|
return false;
|
|
} else {
|
|
_drops--;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void _checkReplenish() {
|
|
int now = DateTime.now().millisecondsSinceEpoch;
|
|
|
|
int replenishMillis = replenishDuration.inMilliseconds;
|
|
|
|
if (_lastReplenish + replenishMillis >= now) {
|
|
int inc = (now - _lastReplenish) ~/ replenishMillis;
|
|
_drops = math.min(_drops + inc, bucketSize);
|
|
_lastReplenish += (replenishMillis * inc);
|
|
}
|
|
}
|
|
}
|