Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: chrome/browser/sync/engine/get_commit_ids_command.cc

Issue 8922015: [Sync] Don't commit items with predecessors/parents in conflict. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/engine/get_commit_ids_command.h" 5 #include "chrome/browser/sync/engine/get_commit_ids_command.h"
6 6
7 #include <set> 7 #include <set>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 namespace { 70 namespace {
71 71
72 // An entry ready for commit is defined as: 72 // An entry ready for commit is defined as:
73 // 1. Not in conflict (SERVER_VERSION == BASE_VERSION || SERVER_VERSION == 0) 73 // 1. Not in conflict (SERVER_VERSION == BASE_VERSION || SERVER_VERSION == 0)
74 // and not requiring encryption (any entry containing an encrypted datatype 74 // and not requiring encryption (any entry containing an encrypted datatype
75 // while the cryptographer requires a passphrase is not ready for commit.) 75 // while the cryptographer requires a passphrase is not ready for commit.)
76 // 2. Its type is not currently throttled. 76 // 2. Its type is not currently throttled.
77 bool IsEntryReadyForCommit(syncable::ModelTypeSet encrypted_types, 77 bool IsEntryReadyForCommit(syncable::ModelTypeSet encrypted_types,
78 bool passphrase_missing, 78 bool passphrase_missing,
79 const syncable::Entry& entry, 79 syncable::ModelTypeSet throttled_types,
80 syncable::ModelTypeSet throttled_types) { 80 const syncable::Entry& entry) {
81 if (!entry.Get(syncable::IS_UNSYNCED))
82 return false;
83
84 if (entry.Get(syncable::SERVER_VERSION) > 0 && 81 if (entry.Get(syncable::SERVER_VERSION) > 0 &&
85 (entry.Get(syncable::SERVER_VERSION) > 82 (entry.Get(syncable::SERVER_VERSION) >
86 entry.Get(syncable::BASE_VERSION))) { 83 entry.Get(syncable::BASE_VERSION))) {
87 // The local and server versions don't match. The item must be in 84 // The local and server versions don't match. The item must be in
88 // conflict, so there's no point in attempting to commit. 85 // conflict, so there's no point in attempting to commit.
89 DCHECK(entry.Get(syncable::IS_UNAPPLIED_UPDATE)); // In conflict. 86 DCHECK(entry.Get(syncable::IS_UNAPPLIED_UPDATE)); // In conflict.
90 DVLOG(1) << "Excluding entry from commit due to version mismatch " 87 DVLOG(1) << "Excluding entry from commit due to version mismatch "
91 << entry; 88 << entry;
92 return false; 89 return false;
93 } 90 }
(...skipping 27 matching lines...) Expand all
121 syncable::BaseTransaction* trans, 118 syncable::BaseTransaction* trans,
122 syncable::ModelTypeSet throttled_types, 119 syncable::ModelTypeSet throttled_types,
123 syncable::Directory::UnsyncedMetaHandles* unsynced_handles) { 120 syncable::Directory::UnsyncedMetaHandles* unsynced_handles) {
124 syncable::Directory::UnsyncedMetaHandles::iterator iter; 121 syncable::Directory::UnsyncedMetaHandles::iterator iter;
125 syncable::Directory::UnsyncedMetaHandles new_unsynced_handles; 122 syncable::Directory::UnsyncedMetaHandles new_unsynced_handles;
126 new_unsynced_handles.reserve(unsynced_handles->size()); 123 new_unsynced_handles.reserve(unsynced_handles->size());
127 for (iter = unsynced_handles->begin(); 124 for (iter = unsynced_handles->begin();
128 iter != unsynced_handles->end(); 125 iter != unsynced_handles->end();
129 ++iter) { 126 ++iter) {
130 syncable::Entry entry(trans, syncable::GET_BY_HANDLE, *iter); 127 syncable::Entry entry(trans, syncable::GET_BY_HANDLE, *iter);
131 if (IsEntryReadyForCommit(encrypted_types_, 128 if (entry.Get(syncable::IS_UNSYNCED) &&
129 IsEntryReadyForCommit(encrypted_types_,
132 passphrase_missing_, 130 passphrase_missing_,
133 entry, 131 throttled_types,
134 throttled_types)) 132 entry)) {
135 new_unsynced_handles.push_back(*iter); 133 new_unsynced_handles.push_back(*iter);
134 }
136 } 135 }
137 if (new_unsynced_handles.size() != unsynced_handles->size()) 136 if (new_unsynced_handles.size() != unsynced_handles->size())
138 unsynced_handles->swap(new_unsynced_handles); 137 unsynced_handles->swap(new_unsynced_handles);
139 } 138 }
140 139
141 void GetCommitIdsCommand::AddUncommittedParentsAndTheirPredecessors( 140 void GetCommitIdsCommand::AddUncommittedParentsAndTheirPredecessors(
142 syncable::BaseTransaction* trans, 141 syncable::BaseTransaction* trans,
143 syncable::Id parent_id, 142 syncable::Id parent_id,
144 const ModelSafeRoutingInfo& routes, 143 const ModelSafeRoutingInfo& routes,
145 syncable::ModelTypeSet throttled_types) { 144 syncable::ModelTypeSet throttled_types) {
146 OrderedCommitSet item_dependencies(routes); 145 OrderedCommitSet item_dependencies(routes);
147 146
148 // Climb the tree adding entries leaf -> root. 147 // Climb the tree adding entries leaf -> root.
149 while (!parent_id.ServerKnows()) { 148 while (!parent_id.ServerKnows()) {
150 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id); 149 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id);
151 CHECK(parent.good()) << "Bad user-only parent in item path."; 150 CHECK(parent.good()) << "Bad user-only parent in item path.";
152 int64 handle = parent.Get(syncable::META_HANDLE); 151 int64 handle = parent.Get(syncable::META_HANDLE);
153 if (ordered_commit_set_->HaveCommitItem(handle) || 152 if (ordered_commit_set_->HaveCommitItem(handle) ||
154 item_dependencies.HaveCommitItem(handle)) { 153 item_dependencies.HaveCommitItem(handle)) {
155 break; 154 break;
156 } 155 }
157 if (!AddItemThenPredecessors(trans, throttled_types, &parent, 156 if (!AddItemThenPredecessors(trans, throttled_types, &parent,
158 syncable::IS_UNSYNCED,
159 &item_dependencies)) { 157 &item_dependencies)) {
160 break; // Parent was already present in the set. 158 // Either the parent/it's predecessor's are not ready for commit, in which
akalin 2011/12/14 03:39:52 it's -> its predecessor's -> predecessors
159 // case item_dependencies has been cleared and we should return, or the
160 // parent has already been added to the commit set, in which case it's
161 // predecessors and parent's must already be in there too. Either way,
162 // no more work to do in this loop.
163 return;
161 } 164 }
162 parent_id = parent.Get(syncable::PARENT_ID); 165 parent_id = parent.Get(syncable::PARENT_ID);
163 } 166 }
164 167
165 // Reverse what we added to get the correct order. 168 // Reverse what we added to get the correct order.
166 ordered_commit_set_->AppendReverse(item_dependencies); 169 ordered_commit_set_->AppendReverse(item_dependencies);
167 } 170 }
168 171
169 bool GetCommitIdsCommand::AddItem(syncable::Entry* item, 172 bool GetCommitIdsCommand::AddItem(syncable::Entry* item,
170 syncable::ModelTypeSet throttled_types, 173 syncable::ModelTypeSet throttled_types,
171 OrderedCommitSet* result) { 174 OrderedCommitSet* result) {
172 if (!IsEntryReadyForCommit(encrypted_types_, passphrase_missing_, *item, 175 DCHECK(item->Get(syncable::IS_UNSYNCED));
173 throttled_types)) 176 if (!IsEntryReadyForCommit(encrypted_types_, passphrase_missing_,
177 throttled_types, *item)) {
178 // If the item is not ready for commit, then all items that depend on this
179 // one are also not ready for commit. Clear the OrderedCommitSet and return.
180 result->Clear();
174 return false; 181 return false;
182 }
175 int64 item_handle = item->Get(syncable::META_HANDLE); 183 int64 item_handle = item->Get(syncable::META_HANDLE);
176 if (result->HaveCommitItem(item_handle) || 184 if (result->HaveCommitItem(item_handle) ||
177 ordered_commit_set_->HaveCommitItem(item_handle)) { 185 ordered_commit_set_->HaveCommitItem(item_handle)) {
178 return false; 186 return false;
179 } 187 }
180 result->AddCommitItem(item_handle, item->Get(syncable::ID), 188 result->AddCommitItem(item_handle, item->Get(syncable::ID),
181 item->GetModelType()); 189 item->GetModelType());
182 return true; 190 return true;
183 } 191 }
184 192
185 bool GetCommitIdsCommand::AddItemThenPredecessors( 193 bool GetCommitIdsCommand::AddItemThenPredecessors(
186 syncable::BaseTransaction* trans, 194 syncable::BaseTransaction* trans,
187 syncable::ModelTypeSet throttled_types, 195 syncable::ModelTypeSet throttled_types,
188 syncable::Entry* item, 196 syncable::Entry* item,
189 syncable::IndexedBitField inclusion_filter,
190 OrderedCommitSet* result) { 197 OrderedCommitSet* result) {
191 if (!AddItem(item, throttled_types, result)) 198 if (!AddItem(item, throttled_types, result))
192 return false; 199 return false;
193 if (item->Get(syncable::IS_DEL)) 200 if (item->Get(syncable::IS_DEL))
194 return true; // Deleted items have no predecessors. 201 return true; // Deleted items have no predecessors.
195 202
196 syncable::Id prev_id = item->Get(syncable::PREV_ID); 203 syncable::Id prev_id = item->Get(syncable::PREV_ID);
197 while (!prev_id.IsRoot()) { 204 while (!prev_id.IsRoot()) {
198 syncable::Entry prev(trans, syncable::GET_BY_ID, prev_id); 205 syncable::Entry prev(trans, syncable::GET_BY_ID, prev_id);
199 CHECK(prev.good()) << "Bad id when walking predecessors."; 206 CHECK(prev.good()) << "Bad id when walking predecessors.";
200 if (!prev.Get(inclusion_filter)) 207 if (!prev.Get(syncable::IS_UNSYNCED))
201 break; 208 break;
202 if (!AddItem(&prev, throttled_types, result)) 209 if (!AddItem(&prev, throttled_types, result))
203 break; 210 return false;
204 prev_id = prev.Get(syncable::PREV_ID); 211 prev_id = prev.Get(syncable::PREV_ID);
205 } 212 }
206 return true; 213 return true;
207 } 214 }
208 215
209 void GetCommitIdsCommand::AddPredecessorsThenItem( 216 void GetCommitIdsCommand::AddPredecessorsThenItem(
210 syncable::BaseTransaction* trans, 217 syncable::BaseTransaction* trans,
211 syncable::ModelTypeSet throttled_types, 218 syncable::ModelTypeSet throttled_types,
212 syncable::Entry* item, 219 syncable::Entry* item,
213 syncable::IndexedBitField inclusion_filter,
214 const ModelSafeRoutingInfo& routes) { 220 const ModelSafeRoutingInfo& routes) {
215 OrderedCommitSet item_dependencies(routes); 221 OrderedCommitSet item_dependencies(routes);
216 AddItemThenPredecessors(trans, throttled_types, item, inclusion_filter, 222 if (!AddItemThenPredecessors(trans, throttled_types, item,
217 &item_dependencies); 223 &item_dependencies)) {
224 // Either the item or it's predecessors are not ready for commit, so don't
225 // add any items to the commit set.
226 return;
227 }
218 228
219 // Reverse what we added to get the correct order. 229 // Reverse what we added to get the correct order.
220 ordered_commit_set_->AppendReverse(item_dependencies); 230 ordered_commit_set_->AppendReverse(item_dependencies);
221 } 231 }
222 232
223 bool GetCommitIdsCommand::IsCommitBatchFull() { 233 bool GetCommitIdsCommand::IsCommitBatchFull() {
224 return ordered_commit_set_->Size() >= requested_commit_batch_size_; 234 return ordered_commit_set_->Size() >= requested_commit_batch_size_;
225 } 235 }
226 236
227 void GetCommitIdsCommand::AddCreatesAndMoves( 237 void GetCommitIdsCommand::AddCreatesAndMoves(
228 const vector<int64>& unsynced_handles, 238 const vector<int64>& unsynced_handles,
229 syncable::WriteTransaction* write_transaction, 239 syncable::WriteTransaction* write_transaction,
230 const ModelSafeRoutingInfo& routes, 240 const ModelSafeRoutingInfo& routes,
231 syncable::ModelTypeSet throttled_types) { 241 syncable::ModelTypeSet throttled_types) {
232 // Add moves and creates, and prepend their uncommitted parents. 242 // Add moves and creates, and prepend their uncommitted parents.
233 for (CommitMetahandleIterator iterator(unsynced_handles, write_transaction, 243 for (CommitMetahandleIterator iterator(unsynced_handles, write_transaction,
234 ordered_commit_set_.get()); 244 ordered_commit_set_.get());
235 !IsCommitBatchFull() && iterator.Valid(); 245 !IsCommitBatchFull() && iterator.Valid();
236 iterator.Increment()) { 246 iterator.Increment()) {
237 int64 metahandle = iterator.Current(); 247 int64 metahandle = iterator.Current();
238 248
239 syncable::Entry entry(write_transaction, 249 syncable::Entry entry(write_transaction,
240 syncable::GET_BY_HANDLE, 250 syncable::GET_BY_HANDLE,
241 metahandle); 251 metahandle);
242 if (!entry.Get(syncable::IS_DEL)) { 252 if (!entry.Get(syncable::IS_DEL)) {
243 AddUncommittedParentsAndTheirPredecessors(write_transaction, 253 AddUncommittedParentsAndTheirPredecessors(write_transaction,
244 entry.Get(syncable::PARENT_ID), routes, throttled_types); 254 entry.Get(syncable::PARENT_ID), routes, throttled_types);
245 AddPredecessorsThenItem(write_transaction, throttled_types, &entry, 255 AddPredecessorsThenItem(write_transaction, throttled_types, &entry,
246 syncable::IS_UNSYNCED, routes); 256 routes);
247 } 257 }
248 } 258 }
249 259
250 // It's possible that we overcommitted while trying to expand dependent 260 // It's possible that we overcommitted while trying to expand dependent
251 // items. If so, truncate the set down to the allowed size. 261 // items. If so, truncate the set down to the allowed size.
252 ordered_commit_set_->Truncate(requested_commit_batch_size_); 262 ordered_commit_set_->Truncate(requested_commit_batch_size_);
253 } 263 }
254 264
255 void GetCommitIdsCommand::AddDeletes(const vector<int64>& unsynced_handles, 265 void GetCommitIdsCommand::AddDeletes(const vector<int64>& unsynced_handles,
256 syncable::WriteTransaction* write_transaction) { 266 syncable::WriteTransaction* write_transaction) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 362
353 // Add moves and creates, and prepend their uncommitted parents. 363 // Add moves and creates, and prepend their uncommitted parents.
354 AddCreatesAndMoves(unsynced_handles, write_transaction, routes, 364 AddCreatesAndMoves(unsynced_handles, write_transaction, routes,
355 throttled_types); 365 throttled_types);
356 366
357 // Add all deletes. 367 // Add all deletes.
358 AddDeletes(unsynced_handles, write_transaction); 368 AddDeletes(unsynced_handles, write_transaction);
359 } 369 }
360 370
361 } // namespace browser_sync 371 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698