1// Copyright 2014 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 "sync/engine/model_thread_sync_entity.h"
6#include "sync/syncable/syncable_util.h"
7
8namespace syncer {
9
10scoped_ptr<ModelThreadSyncEntity> ModelThreadSyncEntity::NewLocalItem(
11    const std::string& client_tag,
12    const sync_pb::EntitySpecifics& specifics,
13    base::Time now) {
14  return scoped_ptr<ModelThreadSyncEntity>(new ModelThreadSyncEntity(
15      1,
16      0,
17      0,
18      kUncommittedVersion,
19      true,
20      std::string(),  // Sync thread will assign the initial ID.
21      syncable::GenerateSyncableHash(GetModelTypeFromSpecifics(specifics),
22                                     client_tag),
23      client_tag,  // As non-unique name.
24      specifics,
25      false,
26      now,
27      now));
28}
29
30scoped_ptr<ModelThreadSyncEntity> ModelThreadSyncEntity::FromServerUpdate(
31    const std::string& id,
32    const std::string& client_tag_hash,
33    const std::string& non_unique_name,
34    int64 version,
35    const sync_pb::EntitySpecifics& specifics,
36    bool deleted,
37    base::Time ctime,
38    base::Time mtime) {
39  return scoped_ptr<ModelThreadSyncEntity>(
40      new ModelThreadSyncEntity(0,
41                                0,
42                                0,
43                                version,
44                                true,
45                                id,
46                                client_tag_hash,
47                                non_unique_name,
48                                specifics,
49                                deleted,
50                                ctime,
51                                mtime));
52}
53
54ModelThreadSyncEntity::ModelThreadSyncEntity(
55    int64 sequence_number,
56    int64 commit_requested_sequence_number,
57    int64 acked_sequence_number,
58    int64 base_version,
59    bool is_dirty,
60    const std::string& id,
61    const std::string& client_tag_hash,
62    const std::string& non_unique_name,
63    const sync_pb::EntitySpecifics& specifics,
64    bool deleted,
65    base::Time ctime,
66    base::Time mtime)
67    : sequence_number_(sequence_number),
68      commit_requested_sequence_number_(commit_requested_sequence_number),
69      acked_sequence_number_(acked_sequence_number),
70      base_version_(base_version),
71      is_dirty_(is_dirty),
72      id_(id),
73      client_tag_hash_(client_tag_hash),
74      non_unique_name_(non_unique_name),
75      specifics_(specifics),
76      deleted_(deleted),
77      ctime_(ctime),
78      mtime_(mtime) {
79}
80
81ModelThreadSyncEntity::~ModelThreadSyncEntity() {
82}
83
84bool ModelThreadSyncEntity::IsWriteRequired() const {
85  return is_dirty_;
86}
87
88bool ModelThreadSyncEntity::IsUnsynced() const {
89  return sequence_number_ > acked_sequence_number_;
90}
91
92bool ModelThreadSyncEntity::RequiresCommitRequest() const {
93  return sequence_number_ > commit_requested_sequence_number_;
94}
95
96bool ModelThreadSyncEntity::UpdateIsReflection(int64 update_version) const {
97  return base_version_ >= update_version;
98}
99
100bool ModelThreadSyncEntity::UpdateIsInConflict(int64 update_version) const {
101  return IsUnsynced() && !UpdateIsReflection(update_version);
102}
103
104void ModelThreadSyncEntity::ApplyUpdateFromServer(
105    int64 update_version,
106    bool deleted,
107    const sync_pb::EntitySpecifics& specifics,
108    base::Time mtime) {
109  // There was a conflict and the server just won it.
110  // This implicitly acks all outstanding commits because a received update
111  // will clobber any pending commits on the sync thread.
112  acked_sequence_number_ = sequence_number_;
113  commit_requested_sequence_number_ = sequence_number_;
114
115  base_version_ = update_version;
116  specifics_ = specifics;
117  mtime_ = mtime;
118}
119
120void ModelThreadSyncEntity::MakeLocalChange(
121    const sync_pb::EntitySpecifics& specifics) {
122  sequence_number_++;
123  specifics_ = specifics;
124}
125
126void ModelThreadSyncEntity::Delete() {
127  sequence_number_++;
128  specifics_.Clear();
129  deleted_ = true;
130}
131
132void ModelThreadSyncEntity::InitializeCommitRequestData(
133    CommitRequestData* request) const {
134  request->id = id_;
135  request->client_tag_hash = client_tag_hash_;
136  request->sequence_number = sequence_number_;
137  request->base_version = base_version_;
138  request->ctime = ctime_;
139  request->mtime = mtime_;
140  request->non_unique_name = non_unique_name_;
141  request->deleted = deleted_;
142  request->specifics.CopyFrom(specifics_);
143}
144
145void ModelThreadSyncEntity::SetCommitRequestInProgress() {
146  commit_requested_sequence_number_ = sequence_number_;
147}
148
149void ModelThreadSyncEntity::ReceiveCommitResponse(const std::string& id,
150                                                  int64 sequence_number,
151                                                  int64 response_version) {
152  id_ = id;  // The server can assign us a new ID in a commit response.
153  acked_sequence_number_ = sequence_number;
154  base_version_ = response_version;
155}
156
157}  // namespace syncer
158