Index: sync/internal_api/processor_entity_tracker.cc |
diff --git a/sync/internal_api/processor_entity_tracker.cc b/sync/internal_api/processor_entity_tracker.cc |
index 8e3e149ad5ca869a1b76e028a35be87843787662..6aa5677c57306722aa32c53fec5aa03f9132cb33 100644 |
--- a/sync/internal_api/processor_entity_tracker.cc |
+++ b/sync/internal_api/processor_entity_tracker.cc |
@@ -19,6 +19,7 @@ namespace { |
void HashSpecifics(const sync_pb::EntitySpecifics& specifics, |
std::string* hash) { |
+ DCHECK_GT(specifics.ByteSize(), 0); |
base::Base64Encode(base::SHA1HashString(specifics.SerializeAsString()), hash); |
} |
@@ -80,19 +81,21 @@ bool ProcessorEntityTracker::HasCommitData() const { |
return !commit_data_->client_tag_hash.empty(); |
} |
-bool ProcessorEntityTracker::MatchesSpecificsHash( |
- const sync_pb::EntitySpecifics& specifics) const { |
- DCHECK_GT(specifics.ByteSize(), 0); |
- std::string hash; |
- HashSpecifics(specifics, &hash); |
- return hash == metadata_.specifics_hash(); |
-} |
- |
bool ProcessorEntityTracker::MatchesData(const EntityData& data) const { |
- return (data.is_deleted() && metadata_.is_deleted()) || |
+ return metadata_.is_deleted() ? data.is_deleted() : |
MatchesSpecificsHash(data.specifics); |
} |
+bool ProcessorEntityTracker::MatchesBaseData(const EntityData& data) const { |
+ DCHECK(IsUnsynced()); |
+ if (data.is_deleted() || metadata_.base_specifics_hash().empty()) { |
+ return false; |
+ } |
+ std::string hash; |
+ HashSpecifics(data.specifics, &hash); |
+ return hash == metadata_.base_specifics_hash(); |
+} |
+ |
bool ProcessorEntityTracker::IsUnsynced() const { |
return metadata_.sequence_number() > metadata_.acked_sequence_number(); |
} |
@@ -149,11 +152,11 @@ void ProcessorEntityTracker::MakeLocalChange(std::unique_ptr<EntityData> data) { |
data->modification_time = base::Time::Now(); |
} |
+ IncrementSequenceNumber(); |
+ UpdateSpecificsHash(data->specifics); |
metadata_.set_modification_time( |
syncer::TimeToProtoTime(data->modification_time)); |
metadata_.set_is_deleted(false); |
- IncrementSequenceNumber(); |
- UpdateSpecificsHash(data->specifics); |
data->id = metadata_.server_id(); |
data->creation_time = syncer::ProtoTimeToTime(metadata_.creation_time()); |
@@ -187,23 +190,27 @@ void ProcessorEntityTracker::InitializeCommitRequestData( |
request->sequence_number = metadata_.sequence_number(); |
request->base_version = metadata_.server_version(); |
+ request->specifics_hash = metadata_.specifics_hash(); |
commit_requested_sequence_number_ = metadata_.sequence_number(); |
} |
void ProcessorEntityTracker::ReceiveCommitResponse( |
- const std::string& id, |
- int64_t sequence_number, |
- int64_t response_version) { |
- DCHECK(sequence_number > metadata_.acked_sequence_number()); |
+ const CommitResponseData& data) { |
+ DCHECK_EQ(metadata_.client_tag_hash(), data.client_tag_hash); |
+ DCHECK_GT(data.sequence_number, metadata_.acked_sequence_number()); |
+ DCHECK_GT(data.response_version, metadata_.server_version()); |
// The server can assign us a new ID in a commit response. |
- metadata_.set_server_id(id); |
- metadata_.set_acked_sequence_number(sequence_number); |
- metadata_.set_server_version(response_version); |
+ metadata_.set_server_id(data.id); |
+ metadata_.set_acked_sequence_number(data.sequence_number); |
+ metadata_.set_server_version(data.response_version); |
if (!IsUnsynced()) { |
// Clear pending commit data if there hasn't been another commit request |
// since the one that is currently getting acked. |
commit_data_.reset(); |
+ metadata_.clear_base_specifics_hash(); |
+ } else { |
+ metadata_.set_base_specifics_hash(data.specifics_hash); |
} |
} |
@@ -215,10 +222,21 @@ void ProcessorEntityTracker::ClearTransientSyncState() { |
void ProcessorEntityTracker::IncrementSequenceNumber() { |
DCHECK(metadata_.has_sequence_number()); |
+ if (!IsUnsynced()) { |
+ // Update the base specifics hash if this entity wasn't already out of sync. |
+ metadata_.set_base_specifics_hash(metadata_.specifics_hash()); |
+ } |
metadata_.set_sequence_number(metadata_.sequence_number() + 1); |
} |
-// Update hash string for EntitySpecifics. |
+bool ProcessorEntityTracker::MatchesSpecificsHash( |
+ const sync_pb::EntitySpecifics& specifics) const { |
+ DCHECK(!metadata_.is_deleted()); |
+ std::string hash; |
+ HashSpecifics(specifics, &hash); |
+ return hash == metadata_.specifics_hash(); |
+} |
+ |
void ProcessorEntityTracker::UpdateSpecificsHash( |
const sync_pb::EntitySpecifics& specifics) { |
if (specifics.ByteSize() > 0) { |