summaryrefslogtreecommitdiffstats
path: root/sync/sessions/data_type_tracker.cc
blob: 857b86a0f9f15c22b7a9459d692ab09b7ff7d974 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sync/sessions/data_type_tracker.h"

#include "sync/sessions/nudge_tracker.h"

namespace syncer {
namespace sessions {

DataTypeTracker::DataTypeTracker()
  : local_nudge_count_(0),
    local_refresh_request_count_(0),
    local_payload_overflow_(false),
    server_payload_overflow_(false),
    payload_buffer_size_(NudgeTracker::kDefaultMaxPayloadsPerType) { }

DataTypeTracker::~DataTypeTracker() { }

void DataTypeTracker::RecordLocalChange() {
  local_nudge_count_++;
}

void DataTypeTracker::RecordLocalRefreshRequest() {
  local_refresh_request_count_++;
}

void DataTypeTracker::RecordRemoteInvalidation(
    const std::string& payload) {
  pending_payloads_.push_back(payload);
  if (pending_payloads_.size() > payload_buffer_size_) {
    // Drop the oldest payload if we've overflowed.
    pending_payloads_.pop_front();
    local_payload_overflow_ = true;
  }
}

void DataTypeTracker::RecordSuccessfulSyncCycle() {
  // If we were throttled, then we would have been excluded from this cycle's
  // GetUpdates and Commit actions.  Our state remains unchanged.
  if (IsThrottled())
    return;

  local_nudge_count_ = 0;
  local_refresh_request_count_ = 0;
  pending_payloads_.clear();
  local_payload_overflow_ = false;
  server_payload_overflow_ = false;
}

// This limit will take effect on all future invalidations received.
void DataTypeTracker::UpdatePayloadBufferSize(size_t new_size) {
  payload_buffer_size_ = new_size;
}

bool DataTypeTracker::IsSyncRequired() const {
  return !IsThrottled() &&
      (local_nudge_count_ > 0 ||
       local_refresh_request_count_ > 0 ||
       !pending_payloads_.empty());
}

bool DataTypeTracker::HasLocalChangePending() const {
  return local_nudge_count_ > 0;
}

bool DataTypeTracker::HasPendingInvalidation() const {
  return !pending_payloads_.empty();
}

std::string DataTypeTracker::GetMostRecentInvalidationPayload() const {
  return pending_payloads_.back();
}

void DataTypeTracker::FillGetUpdatesTriggersMessage(
    sync_pb::GetUpdateTriggers* msg) const {
  // Fill the list of payloads, if applicable.  The payloads must be ordered
  // oldest to newest, so we insert them in the same order as we've been storing
  // them internally.
  for (PayloadList::const_iterator payload_it = pending_payloads_.begin();
       payload_it != pending_payloads_.end(); ++payload_it) {
    msg->add_notification_hint(*payload_it);
  }

  msg->set_client_dropped_hints(local_payload_overflow_);
  msg->set_local_modification_nudges(local_nudge_count_);
  msg->set_datatype_refresh_nudges(local_refresh_request_count_);

  // TODO(rlarocque): Support Tango trickles.  See crbug.com/223437.
  // msg->set_server_dropped_hints(server_payload_oveflow_);
}

bool DataTypeTracker::IsThrottled() const {
  return !unthrottle_time_.is_null();
}

base::TimeDelta DataTypeTracker::GetTimeUntilUnthrottle(
    base::TimeTicks now) const {
  if (!IsThrottled()) {
    NOTREACHED();
    return base::TimeDelta::FromSeconds(0);
  }
  return std::max(base::TimeDelta::FromSeconds(0),
                  unthrottle_time_ - now);
}

void DataTypeTracker::ThrottleType(base::TimeDelta duration,
                                      base::TimeTicks now) {
  unthrottle_time_ = std::max(unthrottle_time_, now + duration);
}

void DataTypeTracker::UpdateThrottleState(base::TimeTicks now) {
  if (now >= unthrottle_time_) {
    unthrottle_time_ = base::TimeTicks();
  }
}

}  // namespace sessions
}  // namespace syncer