simpletokenbucket.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /* Original author: bcampen@mozilla.com */
  6. #include "simpletokenbucket.h"
  7. #include <stdint.h>
  8. #include "prinrval.h"
  9. namespace mozilla {
  10. SimpleTokenBucket::SimpleTokenBucket(size_t bucket_size,
  11. size_t tokens_per_second) :
  12. max_tokens_(bucket_size),
  13. num_tokens_(bucket_size),
  14. tokens_per_second_(tokens_per_second),
  15. last_time_tokens_added_(PR_IntervalNow()) {
  16. }
  17. size_t SimpleTokenBucket::getTokens(size_t num_requested_tokens) {
  18. // Only fill if there isn't enough to satisfy the request.
  19. // If we get tokens so seldomly that we are able to roll the timer all
  20. // the way around its range, then we lose that entire range of time
  21. // for token accumulation. Probably not the end of the world.
  22. if (num_requested_tokens > num_tokens_) {
  23. PRIntervalTime now = PR_IntervalNow();
  24. // If we roll over the max, since everything in this calculation is the same
  25. // unsigned type, this will still yield the elapsed time (unless we've
  26. // wrapped more than once).
  27. PRIntervalTime elapsed_ticks = now - last_time_tokens_added_;
  28. uint32_t elapsed_milli_sec = PR_IntervalToMilliseconds(elapsed_ticks);
  29. size_t tokens_to_add = (elapsed_milli_sec * tokens_per_second_)/1000;
  30. // Only update our timestamp if we added some tokens
  31. // TODO:(bcampen@mozilla.com) Should we attempt to "save" leftover time?
  32. if (tokens_to_add) {
  33. num_tokens_ += tokens_to_add;
  34. if (num_tokens_ > max_tokens_) {
  35. num_tokens_ = max_tokens_;
  36. }
  37. last_time_tokens_added_ = now;
  38. }
  39. if (num_requested_tokens > num_tokens_) {
  40. return num_tokens_;
  41. }
  42. }
  43. num_tokens_ -= num_requested_tokens;
  44. return num_requested_tokens;
  45. }
  46. } // namespace mozilla