This source file includes following definitions.
- drop_tracker_
- RecordLocalChange
- RecordLocalRefreshRequest
- IsInvalidationVersionLessThan
- RecordRemoteInvalidations
- RecordSuccessfulSyncCycle
- UpdatePayloadBufferSize
- IsSyncRequired
- IsGetUpdatesRequired
- HasLocalChangePending
- HasRefreshRequestPending
- HasPendingInvalidation
- SetLegacyNotificationHint
- FillGetUpdatesTriggersMessage
- IsThrottled
- GetTimeUntilUnthrottle
- ThrottleType
- UpdateThrottleState
#include "sync/sessions/data_type_tracker.h"
#include "base/logging.h"
#include "sync/internal_api/public/base/invalidation.h"
#include "sync/notifier/invalidation_util.h"
#include "sync/notifier/single_object_invalidation_set.h"
#include "sync/sessions/nudge_tracker.h"
namespace syncer {
namespace sessions {
DataTypeTracker::DataTypeTracker(const invalidation::ObjectId& object_id)
: local_nudge_count_(0),
local_refresh_request_count_(0),
payload_buffer_size_(NudgeTracker::kDefaultMaxPayloadsPerType),
drop_tracker_(object_id) { }
DataTypeTracker::~DataTypeTracker() { }
void DataTypeTracker::RecordLocalChange() {
local_nudge_count_++;
}
void DataTypeTracker::RecordLocalRefreshRequest() {
local_refresh_request_count_++;
}
namespace {
bool IsInvalidationVersionLessThan(
const Invalidation& a,
const Invalidation& b) {
InvalidationVersionLessThan comparator;
return comparator(a, b);
}
}
void DataTypeTracker::RecordRemoteInvalidations(
const SingleObjectInvalidationSet& invalidations) {
SingleObjectInvalidationSet::const_iterator incoming_it =
invalidations.begin();
SingleObjectInvalidationSet::const_iterator existing_it =
pending_invalidations_.begin();
while (incoming_it != invalidations.end()) {
while (existing_it != pending_invalidations_.end()
&& IsInvalidationVersionLessThan(*existing_it, *incoming_it)) {
existing_it++;
}
if (existing_it != pending_invalidations_.end()
&& !IsInvalidationVersionLessThan(*incoming_it, *existing_it)
&& !IsInvalidationVersionLessThan(*existing_it, *incoming_it)) {
SingleObjectInvalidationSet::const_iterator old_inv = existing_it;
existing_it++;
old_inv->Acknowledge();
pending_invalidations_.Erase(old_inv);
pending_invalidations_.Insert(*incoming_it);
incoming_it++;
} else {
DCHECK(existing_it == pending_invalidations_.end()
|| IsInvalidationVersionLessThan(*incoming_it, *existing_it));
pending_invalidations_.Insert(*incoming_it);
incoming_it++;
}
}
while (pending_invalidations_.GetSize() > payload_buffer_size_) {
pending_invalidations_.begin()->Drop(&drop_tracker_);
pending_invalidations_.Erase(pending_invalidations_.begin());
}
}
void DataTypeTracker::RecordSuccessfulSyncCycle() {
if (IsThrottled())
return;
local_nudge_count_ = 0;
local_refresh_request_count_ = 0;
for (SingleObjectInvalidationSet::const_iterator it =
pending_invalidations_.begin();
it != pending_invalidations_.end(); ++it) {
it->Acknowledge();
}
pending_invalidations_.Clear();
if (drop_tracker_.IsRecoveringFromDropEvent()) {
drop_tracker_.RecordRecoveryFromDropEvent();
}
}
void DataTypeTracker::UpdatePayloadBufferSize(size_t new_size) {
payload_buffer_size_ = new_size;
}
bool DataTypeTracker::IsSyncRequired() const {
return !IsThrottled() && (HasLocalChangePending() || IsGetUpdatesRequired());
}
bool DataTypeTracker::IsGetUpdatesRequired() const {
return !IsThrottled() &&
(HasRefreshRequestPending() || HasPendingInvalidation());
}
bool DataTypeTracker::HasLocalChangePending() const {
return local_nudge_count_ > 0;
}
bool DataTypeTracker::HasRefreshRequestPending() const {
return local_refresh_request_count_ > 0;
}
bool DataTypeTracker::HasPendingInvalidation() const {
return !pending_invalidations_.IsEmpty()
|| drop_tracker_.IsRecoveringFromDropEvent();
}
void DataTypeTracker::SetLegacyNotificationHint(
sync_pb::DataTypeProgressMarker* progress) const {
DCHECK(!IsThrottled())
<< "We should not make requests if the type is throttled.";
if (!pending_invalidations_.IsEmpty() &&
!pending_invalidations_.back().is_unknown_version()) {
progress->set_notification_hint(pending_invalidations_.back().payload());
} else if (HasLocalChangePending()) {
progress->set_notification_hint("");
}
}
void DataTypeTracker::FillGetUpdatesTriggersMessage(
sync_pb::GetUpdateTriggers* msg) const {
for (SingleObjectInvalidationSet::const_iterator it =
pending_invalidations_.begin();
it != pending_invalidations_.end(); ++it) {
if (!it->is_unknown_version()) {
msg->add_notification_hint(it->payload());
}
}
msg->set_server_dropped_hints(
pending_invalidations_.StartsWithUnknownVersion());
msg->set_client_dropped_hints(drop_tracker_.IsRecoveringFromDropEvent());
msg->set_local_modification_nudges(local_nudge_count_);
msg->set_datatype_refresh_nudges(local_refresh_request_count_);
}
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();
}
}
}
}