OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/quic/test_tools/simulator/traffic_policer.h" |
| 6 |
| 7 #include <algorithm> |
| 8 |
| 9 namespace net { |
| 10 namespace simulator { |
| 11 |
| 12 TrafficPolicer::TrafficPolicer(Simulator* simulator, |
| 13 std::string name, |
| 14 QuicByteCount initial_bucket_size, |
| 15 QuicByteCount max_bucket_size, |
| 16 QuicBandwidth target_bandwidth, |
| 17 Endpoint* input) |
| 18 : Actor(simulator, name), |
| 19 initial_bucket_size_(initial_bucket_size), |
| 20 max_bucket_size_(max_bucket_size), |
| 21 target_bandwidth_(target_bandwidth), |
| 22 last_refill_time_(clock_->Now()), |
| 23 input_(input), |
| 24 output_(this) { |
| 25 input_->SetTxPort(this); |
| 26 } |
| 27 |
| 28 TrafficPolicer::~TrafficPolicer() {} |
| 29 |
| 30 void TrafficPolicer::Act() {} |
| 31 |
| 32 void TrafficPolicer::Refill() { |
| 33 QuicTime::Delta time_passed = clock_->Now() - last_refill_time_; |
| 34 QuicByteCount refill_size = time_passed * target_bandwidth_; |
| 35 |
| 36 for (auto& bucket : token_buckets_) { |
| 37 bucket.second = std::min(bucket.second + refill_size, max_bucket_size_); |
| 38 } |
| 39 |
| 40 last_refill_time_ = clock_->Now(); |
| 41 } |
| 42 |
| 43 void TrafficPolicer::AcceptPacket(std::unique_ptr<Packet> packet) { |
| 44 // Refill existing buckets. |
| 45 Refill(); |
| 46 |
| 47 // Create a new bucket if one does not exist. |
| 48 if (token_buckets_.count(packet->destination) == 0) { |
| 49 token_buckets_.insert( |
| 50 std::make_pair(packet->destination, initial_bucket_size_)); |
| 51 } |
| 52 |
| 53 auto bucket = token_buckets_.find(packet->destination); |
| 54 DCHECK(bucket != token_buckets_.end()); |
| 55 |
| 56 // Silently drop the packet on the floor if out of tokens |
| 57 if (bucket->second < packet->size) { |
| 58 return; |
| 59 } |
| 60 |
| 61 bucket->second -= packet->size; |
| 62 output_tx_port_->AcceptPacket(std::move(packet)); |
| 63 } |
| 64 |
| 65 QuicTime::Delta TrafficPolicer::TimeUntilAvailable() { |
| 66 return output_tx_port_->TimeUntilAvailable(); |
| 67 } |
| 68 |
| 69 TrafficPolicer::Output::Output(TrafficPolicer* policer) |
| 70 : Endpoint(policer->simulator(), policer->name() + " (output port)"), |
| 71 policer_(policer) {} |
| 72 |
| 73 TrafficPolicer::Output::~Output() {} |
| 74 |
| 75 UnconstrainedPortInterface* TrafficPolicer::Output::GetRxPort() { |
| 76 return policer_->input_->GetRxPort(); |
| 77 } |
| 78 |
| 79 void TrafficPolicer::Output::SetTxPort(ConstrainedPortInterface* port) { |
| 80 policer_->output_tx_port_ = port; |
| 81 } |
| 82 |
| 83 void TrafficPolicer::Output::Act() {} |
| 84 |
| 85 } // namespace simulator |
| 86 } // namespace net |
OLD | NEW |