15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/congestion_control/leaky_bucket.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)LeakyBucket::LeakyBucket(QuicBandwidth draining_rate)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : bytes_(0),
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      time_last_updated_(QuicTime::Zero()),
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draining_rate_(draining_rate) {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LeakyBucket::SetDrainingRate(QuicTime now, QuicBandwidth draining_rate) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Update(now);
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  draining_rate_ = draining_rate;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LeakyBucket::Add(QuicTime now, QuicByteCount bytes) {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Update(now);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_ += bytes;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)QuicTime::Delta LeakyBucket::TimeRemaining(QuicTime now) const {
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  QuicTime::Delta time_since_last_update = now.Subtract(time_last_updated_);
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  QuicTime::Delta send_delay = QuicTime::Delta::FromMicroseconds(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (bytes_ * base::Time::kMicrosecondsPerSecond) /
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draining_rate_.ToBytesPerSecond());
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (send_delay < time_since_last_update) {
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return QuicTime::Delta::Zero();
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return send_delay.Subtract(time_since_last_update);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicByteCount LeakyBucket::BytesPending(QuicTime now) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Update(now);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LeakyBucket::Update(QuicTime now) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicTime::Delta elapsed_time = now.Subtract(time_last_updated_);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicByteCount bytes_cleared = draining_rate_.ToBytesPerPeriod(elapsed_time);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_cleared >= bytes_) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_ = 0;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_ -= bytes_cleared;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  time_last_updated_ = now;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
55