1// Copyright 2013 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/quic_ack_notifier.h"
6
7#include <set>
8
9#include "base/logging.h"
10#include "base/stl_util.h"
11
12using base::hash_map;
13using std::make_pair;
14
15namespace net {
16
17QuicAckNotifier::PacketInfo::PacketInfo() : packet_payload_size(0) {
18}
19
20QuicAckNotifier::PacketInfo::PacketInfo(int payload_size)
21    : packet_payload_size(payload_size) {
22}
23
24QuicAckNotifier::DelegateInterface::DelegateInterface() {}
25
26QuicAckNotifier::DelegateInterface::~DelegateInterface() {}
27
28QuicAckNotifier::QuicAckNotifier(DelegateInterface* delegate)
29    : delegate_(delegate),
30      original_packet_count_(0),
31      original_byte_count_(0),
32      retransmitted_packet_count_(0),
33      retransmitted_byte_count_(0) {
34  DCHECK(delegate);
35}
36
37QuicAckNotifier::~QuicAckNotifier() {
38}
39
40void QuicAckNotifier::AddSequenceNumber(
41    const QuicPacketSequenceNumber& sequence_number,
42    int packet_payload_size) {
43  sequence_numbers_.insert(make_pair(sequence_number,
44                                     PacketInfo(packet_payload_size)));
45  ++original_packet_count_;
46  original_byte_count_ += packet_payload_size;
47}
48
49bool QuicAckNotifier::OnAck(QuicPacketSequenceNumber sequence_number,
50                            QuicTime::Delta delta_largest_observed) {
51  DCHECK(ContainsKey(sequence_numbers_, sequence_number));
52  sequence_numbers_.erase(sequence_number);
53  if (IsEmpty()) {
54    // We have seen all the sequence numbers we were waiting for, trigger
55    // callback notification.
56    delegate_->OnAckNotification(
57        original_packet_count_, original_byte_count_,
58        retransmitted_packet_count_, retransmitted_byte_count_,
59        delta_largest_observed);
60    return true;
61  }
62  return false;
63}
64
65void QuicAckNotifier::UpdateSequenceNumber(
66    QuicPacketSequenceNumber old_sequence_number,
67    QuicPacketSequenceNumber new_sequence_number) {
68  DCHECK(!ContainsKey(sequence_numbers_, new_sequence_number));
69
70  PacketInfo packet_info;
71  hash_map<QuicPacketSequenceNumber, PacketInfo>::iterator it =
72      sequence_numbers_.find(old_sequence_number);
73  if (it != sequence_numbers_.end()) {
74    packet_info = it->second;
75    sequence_numbers_.erase(it);
76  } else {
77    DLOG(DFATAL) << "Old sequence number not found.";
78  }
79
80  ++retransmitted_packet_count_;
81  retransmitted_byte_count_ += packet_info.packet_payload_size;
82  sequence_numbers_.insert(make_pair(new_sequence_number, packet_info));
83}
84
85};  // namespace net
86