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

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

Issue 10210009: sync: Loop committing items without downloading updates (v2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 6 months 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
« no previous file with comments | « sync/engine/get_commit_ids_command.h ('k') | sync/engine/net/server_connection_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sync/engine/get_commit_ids_command.h" 5 #include "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
11 #include "sync/engine/nigori_util.h" 11 #include "sync/engine/nigori_util.h"
12 #include "sync/engine/syncer_util.h" 12 #include "sync/engine/syncer_util.h"
13 #include "sync/syncable/syncable.h" 13 #include "sync/syncable/syncable.h"
14 #include "sync/util/cryptographer.h" 14 #include "sync/util/cryptographer.h"
15 15
16 using std::set; 16 using std::set;
17 using std::vector; 17 using std::vector;
18 18
19 namespace browser_sync { 19 namespace browser_sync {
20 20
21 using sessions::OrderedCommitSet; 21 using sessions::OrderedCommitSet;
22 using sessions::SyncSession; 22 using sessions::SyncSession;
23 using sessions::StatusController; 23 using sessions::StatusController;
24 24
25 GetCommitIdsCommand::GetCommitIdsCommand(int commit_batch_size) 25 GetCommitIdsCommand::GetCommitIdsCommand(
26 : requested_commit_batch_size_(commit_batch_size) {} 26 const size_t commit_batch_size,
27 sessions::OrderedCommitSet* commit_set)
28 : requested_commit_batch_size_(commit_batch_size),
29 commit_set_(commit_set) {
30 }
27 31
28 GetCommitIdsCommand::~GetCommitIdsCommand() {} 32 GetCommitIdsCommand::~GetCommitIdsCommand() {}
29 33
30 SyncerError GetCommitIdsCommand::ExecuteImpl(SyncSession* session) { 34 SyncerError GetCommitIdsCommand::ExecuteImpl(SyncSession* session) {
31 // Gather the full set of unsynced items and store it in the session. They 35 // Gather the full set of unsynced items and store it in the session. They
32 // are not in the correct order for commit. 36 // are not in the correct order for commit.
33 std::set<int64> ready_unsynced_set; 37 std::set<int64> ready_unsynced_set;
34 syncable::Directory::UnsyncedMetaHandles all_unsynced_handles; 38 syncable::Directory::UnsyncedMetaHandles all_unsynced_handles;
35 SyncerUtil::GetUnsyncedEntries(session->write_transaction(), 39 SyncerUtil::GetUnsyncedEntries(session->write_transaction(),
36 &all_unsynced_handles); 40 &all_unsynced_handles);
(...skipping 17 matching lines...) Expand all
54 throttled_types, 58 throttled_types,
55 encrypted_types, 59 encrypted_types,
56 passphrase_missing, 60 passphrase_missing,
57 all_unsynced_handles, 61 all_unsynced_handles,
58 &ready_unsynced_set); 62 &ready_unsynced_set);
59 63
60 BuildCommitIds(session->write_transaction(), 64 BuildCommitIds(session->write_transaction(),
61 session->routing_info(), 65 session->routing_info(),
62 ready_unsynced_set); 66 ready_unsynced_set);
63 67
64 StatusController* status = session->mutable_status_controller();
65 syncable::Directory::UnsyncedMetaHandles ready_unsynced_vector(
66 ready_unsynced_set.begin(), ready_unsynced_set.end());
67 status->set_unsynced_handles(ready_unsynced_vector);
68 const vector<syncable::Id>& verified_commit_ids = 68 const vector<syncable::Id>& verified_commit_ids =
69 ordered_commit_set_->GetAllCommitIds(); 69 commit_set_->GetAllCommitIds();
70 70
71 for (size_t i = 0; i < verified_commit_ids.size(); i++) 71 for (size_t i = 0; i < verified_commit_ids.size(); i++)
72 DVLOG(1) << "Debug commit batch result:" << verified_commit_ids[i]; 72 DVLOG(1) << "Debug commit batch result:" << verified_commit_ids[i];
73 73
74 status->set_commit_set(*ordered_commit_set_.get());
75 return SYNCER_OK; 74 return SYNCER_OK;
76 } 75 }
77 76
78 namespace { 77 namespace {
79 78
80 bool IsEntryInConflict(const syncable::Entry& entry) { 79 bool IsEntryInConflict(const syncable::Entry& entry) {
81 if (entry.Get(syncable::IS_UNSYNCED) && 80 if (entry.Get(syncable::IS_UNSYNCED) &&
82 entry.Get(syncable::SERVER_VERSION) > 0 && 81 entry.Get(syncable::SERVER_VERSION) > 0 &&
83 (entry.Get(syncable::SERVER_VERSION) > 82 (entry.Get(syncable::SERVER_VERSION) >
84 entry.Get(syncable::BASE_VERSION))) { 83 entry.Get(syncable::BASE_VERSION))) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 const syncable::Entry& item, 172 const syncable::Entry& item,
174 sessions::OrderedCommitSet* result) const { 173 sessions::OrderedCommitSet* result) const {
175 OrderedCommitSet item_dependencies(routes); 174 OrderedCommitSet item_dependencies(routes);
176 syncable::Id parent_id = item.Get(syncable::PARENT_ID); 175 syncable::Id parent_id = item.Get(syncable::PARENT_ID);
177 176
178 // Climb the tree adding entries leaf -> root. 177 // Climb the tree adding entries leaf -> root.
179 while (!parent_id.ServerKnows()) { 178 while (!parent_id.ServerKnows()) {
180 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id); 179 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id);
181 CHECK(parent.good()) << "Bad user-only parent in item path."; 180 CHECK(parent.good()) << "Bad user-only parent in item path.";
182 int64 handle = parent.Get(syncable::META_HANDLE); 181 int64 handle = parent.Get(syncable::META_HANDLE);
183 if (ordered_commit_set_->HaveCommitItem(handle)) { 182 if (commit_set_->HaveCommitItem(handle)) {
184 // We've already added this parent (and therefore all of its parents). 183 // We've already added this parent (and therefore all of its parents).
185 // We can return early. 184 // We can return early.
186 break; 185 break;
187 } 186 }
188 if (!AddItemThenPredecessors(trans, ready_unsynced_set, parent, 187 if (!AddItemThenPredecessors(trans, ready_unsynced_set, parent,
189 &item_dependencies)) { 188 &item_dependencies)) {
190 // There was a parent/predecessor in conflict. We return without adding 189 // There was a parent/predecessor in conflict. We return without adding
191 // anything to |ordered_commit_set_|. 190 // anything to |commit_set|.
192 DVLOG(1) << "Parent or parent's predecessor was in conflict, omitting " 191 DVLOG(1) << "Parent or parent's predecessor was in conflict, omitting "
193 << item; 192 << item;
194 return false; 193 return false;
195 } 194 }
196 parent_id = parent.Get(syncable::PARENT_ID); 195 parent_id = parent.Get(syncable::PARENT_ID);
197 } 196 }
198 197
199 // Reverse what we added to get the correct order. 198 // Reverse what we added to get the correct order.
200 result->AppendReverse(item_dependencies); 199 result->AppendReverse(item_dependencies);
201 return true; 200 return true;
(...skipping 17 matching lines...) Expand all
219 item.GetModelType()); 218 item.GetModelType());
220 return true; 219 return true;
221 } 220 }
222 221
223 bool GetCommitIdsCommand::AddItemThenPredecessors( 222 bool GetCommitIdsCommand::AddItemThenPredecessors(
224 syncable::BaseTransaction* trans, 223 syncable::BaseTransaction* trans,
225 const std::set<int64>& ready_unsynced_set, 224 const std::set<int64>& ready_unsynced_set,
226 const syncable::Entry& item, 225 const syncable::Entry& item,
227 OrderedCommitSet* result) const { 226 OrderedCommitSet* result) const {
228 int64 item_handle = item.Get(syncable::META_HANDLE); 227 int64 item_handle = item.Get(syncable::META_HANDLE);
229 if (ordered_commit_set_->HaveCommitItem(item_handle)) { 228 if (commit_set_->HaveCommitItem(item_handle)) {
230 // We've already added this item to the commit set, and so must have 229 // We've already added this item to the commit set, and so must have
231 // already added the predecessors as well. 230 // already added the predecessors as well.
232 return true; 231 return true;
233 } 232 }
234 if (!AddItem(ready_unsynced_set, item, result)) 233 if (!AddItem(ready_unsynced_set, item, result))
235 return false; // Item is in conflict. 234 return false; // Item is in conflict.
236 if (item.Get(syncable::IS_DEL)) 235 if (item.Get(syncable::IS_DEL))
237 return true; // Deleted items have no predecessors. 236 return true; // Deleted items have no predecessors.
238 237
239 syncable::Id prev_id = item.Get(syncable::PREV_ID); 238 syncable::Id prev_id = item.Get(syncable::PREV_ID);
240 while (!prev_id.IsRoot()) { 239 while (!prev_id.IsRoot()) {
241 syncable::Entry prev(trans, syncable::GET_BY_ID, prev_id); 240 syncable::Entry prev(trans, syncable::GET_BY_ID, prev_id);
242 CHECK(prev.good()) << "Bad id when walking predecessors."; 241 CHECK(prev.good()) << "Bad id when walking predecessors.";
243 if (!prev.Get(syncable::IS_UNSYNCED)) 242 if (!prev.Get(syncable::IS_UNSYNCED))
244 break; 243 break;
245 int64 handle = prev.Get(syncable::META_HANDLE); 244 int64 handle = prev.Get(syncable::META_HANDLE);
246 if (ordered_commit_set_->HaveCommitItem(handle)) { 245 if (commit_set_->HaveCommitItem(handle)) {
247 // We've already added this item to the commit set, and so must have 246 // We've already added this item to the commit set, and so must have
248 // already added the predecessors as well. 247 // already added the predecessors as well.
249 return true; 248 return true;
250 } 249 }
251 if (!AddItem(ready_unsynced_set, prev, result)) 250 if (!AddItem(ready_unsynced_set, prev, result))
252 return false; // Item is in conflict. 251 return false; // Item is in conflict.
253 prev_id = prev.Get(syncable::PREV_ID); 252 prev_id = prev.Get(syncable::PREV_ID);
254 } 253 }
255 return true; 254 return true;
256 } 255 }
(...skipping 12 matching lines...) Expand all
269 DVLOG(1) << "Predecessor was in conflict, omitting " << item; 268 DVLOG(1) << "Predecessor was in conflict, omitting " << item;
270 return false; 269 return false;
271 } 270 }
272 271
273 // Reverse what we added to get the correct order. 272 // Reverse what we added to get the correct order.
274 result->AppendReverse(item_dependencies); 273 result->AppendReverse(item_dependencies);
275 return true; 274 return true;
276 } 275 }
277 276
278 bool GetCommitIdsCommand::IsCommitBatchFull() const { 277 bool GetCommitIdsCommand::IsCommitBatchFull() const {
279 return ordered_commit_set_->Size() >= requested_commit_batch_size_; 278 return commit_set_->Size() >= requested_commit_batch_size_;
280 } 279 }
281 280
282 void GetCommitIdsCommand::AddCreatesAndMoves( 281 void GetCommitIdsCommand::AddCreatesAndMoves(
283 syncable::WriteTransaction* write_transaction, 282 syncable::WriteTransaction* write_transaction,
284 const ModelSafeRoutingInfo& routes, 283 const ModelSafeRoutingInfo& routes,
285 const std::set<int64>& ready_unsynced_set) { 284 const std::set<int64>& ready_unsynced_set) {
286 // Add moves and creates, and prepend their uncommitted parents. 285 // Add moves and creates, and prepend their uncommitted parents.
287 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin(); 286 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin();
288 !IsCommitBatchFull() && iter != ready_unsynced_set.end(); ++iter) { 287 !IsCommitBatchFull() && iter != ready_unsynced_set.end(); ++iter) {
289 int64 metahandle = *iter; 288 int64 metahandle = *iter;
290 if (ordered_commit_set_->HaveCommitItem(metahandle)) 289 if (commit_set_->HaveCommitItem(metahandle))
291 continue; 290 continue;
292 291
293 syncable::Entry entry(write_transaction, 292 syncable::Entry entry(write_transaction,
294 syncable::GET_BY_HANDLE, 293 syncable::GET_BY_HANDLE,
295 metahandle); 294 metahandle);
296 if (!entry.Get(syncable::IS_DEL)) { 295 if (!entry.Get(syncable::IS_DEL)) {
297 // We only commit an item + its dependencies if it and all its 296 // We only commit an item + its dependencies if it and all its
298 // dependencies are not in conflict. 297 // dependencies are not in conflict.
299 OrderedCommitSet item_dependencies(routes); 298 OrderedCommitSet item_dependencies(routes);
300 if (AddUncommittedParentsAndTheirPredecessors( 299 if (AddUncommittedParentsAndTheirPredecessors(
301 write_transaction, 300 write_transaction,
302 routes, 301 routes,
303 ready_unsynced_set, 302 ready_unsynced_set,
304 entry, 303 entry,
305 &item_dependencies) && 304 &item_dependencies) &&
306 AddPredecessorsThenItem(write_transaction, 305 AddPredecessorsThenItem(write_transaction,
307 routes, 306 routes,
308 ready_unsynced_set, 307 ready_unsynced_set,
309 entry, 308 entry,
310 &item_dependencies)) { 309 &item_dependencies)) {
311 ordered_commit_set_->Append(item_dependencies); 310 commit_set_->Append(item_dependencies);
312 } 311 }
313 } 312 }
314 } 313 }
315 314
316 // It's possible that we overcommitted while trying to expand dependent 315 // It's possible that we overcommitted while trying to expand dependent
317 // items. If so, truncate the set down to the allowed size. 316 // items. If so, truncate the set down to the allowed size.
318 ordered_commit_set_->Truncate(requested_commit_batch_size_); 317 commit_set_->Truncate(requested_commit_batch_size_);
319 } 318 }
320 319
321 void GetCommitIdsCommand::AddDeletes( 320 void GetCommitIdsCommand::AddDeletes(
322 syncable::WriteTransaction* write_transaction, 321 syncable::WriteTransaction* write_transaction,
323 const std::set<int64>& ready_unsynced_set) { 322 const std::set<int64>& ready_unsynced_set) {
324 set<syncable::Id> legal_delete_parents; 323 set<syncable::Id> legal_delete_parents;
325 324
326 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin(); 325 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin();
327 !IsCommitBatchFull() && iter != ready_unsynced_set.end(); ++iter) { 326 !IsCommitBatchFull() && iter != ready_unsynced_set.end(); ++iter) {
328 int64 metahandle = *iter; 327 int64 metahandle = *iter;
329 if (ordered_commit_set_->HaveCommitItem(metahandle)) 328 if (commit_set_->HaveCommitItem(metahandle))
330 continue; 329 continue;
331 330
332 syncable::Entry entry(write_transaction, syncable::GET_BY_HANDLE, 331 syncable::Entry entry(write_transaction, syncable::GET_BY_HANDLE,
333 metahandle); 332 metahandle);
334 333
335 if (entry.Get(syncable::IS_DEL)) { 334 if (entry.Get(syncable::IS_DEL)) {
336 syncable::Entry parent(write_transaction, syncable::GET_BY_ID, 335 syncable::Entry parent(write_transaction, syncable::GET_BY_ID,
337 entry.Get(syncable::PARENT_ID)); 336 entry.Get(syncable::PARENT_ID));
338 // If the parent is deleted and unsynced, then any children of that 337 // If the parent is deleted and unsynced, then any children of that
339 // parent don't need to be added to the delete queue. 338 // parent don't need to be added to the delete queue.
(...skipping 10 matching lines...) Expand all
350 // then we'll miss it in the roll up. We have to add it in manually. 349 // then we'll miss it in the roll up. We have to add it in manually.
351 // TODO(chron): Unit test for move / delete cases: 350 // TODO(chron): Unit test for move / delete cases:
352 // Case 1: Locally moved, then parent deleted 351 // Case 1: Locally moved, then parent deleted
353 // Case 2: Server moved, then locally issue recursive delete. 352 // Case 2: Server moved, then locally issue recursive delete.
354 if (entry.Get(syncable::ID).ServerKnows() && 353 if (entry.Get(syncable::ID).ServerKnows() &&
355 entry.Get(syncable::PARENT_ID) != 354 entry.Get(syncable::PARENT_ID) !=
356 entry.Get(syncable::SERVER_PARENT_ID)) { 355 entry.Get(syncable::SERVER_PARENT_ID)) {
357 DVLOG(1) << "Inserting moved and deleted entry, will be missed by " 356 DVLOG(1) << "Inserting moved and deleted entry, will be missed by "
358 << "delete roll." << entry.Get(syncable::ID); 357 << "delete roll." << entry.Get(syncable::ID);
359 358
360 ordered_commit_set_->AddCommitItem(metahandle, 359 commit_set_->AddCommitItem(metahandle,
361 entry.Get(syncable::ID), 360 entry.Get(syncable::ID),
362 entry.GetModelType()); 361 entry.GetModelType());
363 } 362 }
364 363
365 // Skip this entry since it's a child of a parent that will be 364 // Skip this entry since it's a child of a parent that will be
366 // deleted. The server will unroll the delete and delete the 365 // deleted. The server will unroll the delete and delete the
367 // child as well. 366 // child as well.
368 continue; 367 continue;
369 } 368 }
370 369
(...skipping 10 matching lines...) Expand all
381 // entry, then check if the parent is in legal_delete_parents. 380 // entry, then check if the parent is in legal_delete_parents.
382 // 381 //
383 // Parent being in legal_delete_parents means for the child: 382 // Parent being in legal_delete_parents means for the child:
384 // a recursive delete is not currently happening (no recent deletes in same 383 // a recursive delete is not currently happening (no recent deletes in same
385 // folder) 384 // folder)
386 // parent did expect at least one old deleted child 385 // parent did expect at least one old deleted child
387 // parent was not deleted 386 // parent was not deleted
388 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin(); 387 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin();
389 !IsCommitBatchFull() && iter != ready_unsynced_set.end(); ++iter) { 388 !IsCommitBatchFull() && iter != ready_unsynced_set.end(); ++iter) {
390 int64 metahandle = *iter; 389 int64 metahandle = *iter;
391 if (ordered_commit_set_->HaveCommitItem(metahandle)) 390 if (commit_set_->HaveCommitItem(metahandle))
392 continue; 391 continue;
393 syncable::MutableEntry entry(write_transaction, syncable::GET_BY_HANDLE, 392 syncable::MutableEntry entry(write_transaction, syncable::GET_BY_HANDLE,
394 metahandle); 393 metahandle);
395 if (entry.Get(syncable::IS_DEL)) { 394 if (entry.Get(syncable::IS_DEL)) {
396 syncable::Id parent_id = entry.Get(syncable::PARENT_ID); 395 syncable::Id parent_id = entry.Get(syncable::PARENT_ID);
397 if (legal_delete_parents.count(parent_id)) { 396 if (legal_delete_parents.count(parent_id)) {
398 ordered_commit_set_->AddCommitItem(metahandle, entry.Get(syncable::ID), 397 commit_set_->AddCommitItem(metahandle, entry.Get(syncable::ID),
399 entry.GetModelType()); 398 entry.GetModelType());
400 } 399 }
401 } 400 }
402 } 401 }
403 } 402 }
404 403
405 void GetCommitIdsCommand::BuildCommitIds( 404 void GetCommitIdsCommand::BuildCommitIds(
406 syncable::WriteTransaction* write_transaction, 405 syncable::WriteTransaction* write_transaction,
407 const ModelSafeRoutingInfo& routes, 406 const ModelSafeRoutingInfo& routes,
408 const std::set<int64>& ready_unsynced_set) { 407 const std::set<int64>& ready_unsynced_set) {
409 ordered_commit_set_.reset(new OrderedCommitSet(routes));
410 // Commits follow these rules: 408 // Commits follow these rules:
411 // 1. Moves or creates are preceded by needed folder creates, from 409 // 1. Moves or creates are preceded by needed folder creates, from
412 // root to leaf. For folders whose contents are ordered, moves 410 // root to leaf. For folders whose contents are ordered, moves
413 // and creates appear in order. 411 // and creates appear in order.
414 // 2. Moves/Creates before deletes. 412 // 2. Moves/Creates before deletes.
415 // 3. Deletes, collapsed. 413 // 3. Deletes, collapsed.
416 // We commit deleted moves under deleted items as moves when collapsing 414 // We commit deleted moves under deleted items as moves when collapsing
417 // delete trees. 415 // delete trees.
418 416
419 // Add moves and creates, and prepend their uncommitted parents. 417 // Add moves and creates, and prepend their uncommitted parents.
420 AddCreatesAndMoves(write_transaction, routes, ready_unsynced_set); 418 AddCreatesAndMoves(write_transaction, routes, ready_unsynced_set);
421 419
422 // Add all deletes. 420 // Add all deletes.
423 AddDeletes(write_transaction, ready_unsynced_set); 421 AddDeletes(write_transaction, ready_unsynced_set);
424 } 422 }
425 423
426 } // namespace browser_sync 424 } // namespace browser_sync
OLDNEW
« no previous file with comments | « sync/engine/get_commit_ids_command.h ('k') | sync/engine/net/server_connection_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698