| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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.h" | 5 #include "sync/engine/get_commit_ids.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 void AddPredecessorsThenItem( | 247 void AddPredecessorsThenItem( |
| 248 const std::set<int64>& ready_unsynced_set, | 248 const std::set<int64>& ready_unsynced_set, |
| 249 const syncable::Entry& item, | 249 const syncable::Entry& item, |
| 250 syncable::Directory::Metahandles* result) const; | 250 syncable::Directory::Metahandles* result) const; |
| 251 | 251 |
| 252 bool AddDeletedParents(const std::set<int64>& ready_unsynced_set, | 252 bool AddDeletedParents(const std::set<int64>& ready_unsynced_set, |
| 253 const syncable::Entry& item, | 253 const syncable::Entry& item, |
| 254 const syncable::Directory::Metahandles& traversed, | 254 const syncable::Directory::Metahandles& traversed, |
| 255 syncable::Directory::Metahandles* result) const; | 255 syncable::Directory::Metahandles* result) const; |
| 256 | 256 |
| 257 bool SupportsHierarchy(const syncable::Entry& item) const; |
| 258 |
| 257 // Returns true if we've collected enough items. | 259 // Returns true if we've collected enough items. |
| 258 bool IsFull() const; | 260 bool IsFull() const; |
| 259 | 261 |
| 260 // Returns true if the specified handle is already in the traversal. | 262 // Returns true if the specified handle is already in the traversal. |
| 261 bool HaveItem(int64 handle) const; | 263 bool HaveItem(int64 handle) const; |
| 262 | 264 |
| 263 // Adds the specified handles to the traversal. | 265 // Adds the specified handles to the traversal. |
| 264 void AppendManyToTraversal(const syncable::Directory::Metahandles& handles); | 266 void AppendManyToTraversal(const syncable::Directory::Metahandles& handles); |
| 265 | 267 |
| 266 // Adds the specifed handle to the traversal. | 268 // Adds the specifed handle to the traversal. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 281 : out_(out), | 283 : out_(out), |
| 282 max_entries_(max_entries), | 284 max_entries_(max_entries), |
| 283 trans_(trans) { } | 285 trans_(trans) { } |
| 284 | 286 |
| 285 Traversal::~Traversal() {} | 287 Traversal::~Traversal() {} |
| 286 | 288 |
| 287 bool Traversal::AddUncommittedParentsAndTheirPredecessors( | 289 bool Traversal::AddUncommittedParentsAndTheirPredecessors( |
| 288 const std::set<int64>& ready_unsynced_set, | 290 const std::set<int64>& ready_unsynced_set, |
| 289 const syncable::Entry& item, | 291 const syncable::Entry& item, |
| 290 syncable::Directory::Metahandles* result) const { | 292 syncable::Directory::Metahandles* result) const { |
| 293 DCHECK(SupportsHierarchy(item)); |
| 291 syncable::Directory::Metahandles dependencies; | 294 syncable::Directory::Metahandles dependencies; |
| 292 syncable::Id parent_id = item.GetParentId(); | 295 syncable::Id parent_id = item.GetParentId(); |
| 293 | 296 |
| 294 // Climb the tree adding entries leaf -> root. | 297 // Climb the tree adding entries leaf -> root. |
| 295 while (!parent_id.ServerKnows()) { | 298 while (!parent_id.ServerKnows()) { |
| 296 syncable::Entry parent(trans_, syncable::GET_BY_ID, parent_id); | 299 syncable::Entry parent(trans_, syncable::GET_BY_ID, parent_id); |
| 297 CHECK(parent.good()) << "Bad user-only parent in item path."; | 300 CHECK(parent.good()) << "Bad user-only parent in item path."; |
| 298 int64 handle = parent.GetMetahandle(); | 301 int64 handle = parent.GetMetahandle(); |
| 299 if (HaveItem(handle)) { | 302 if (HaveItem(handle)) { |
| 300 // We've already added this parent (and therefore all of its parents). | 303 // We've already added this parent (and therefore all of its parents). |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 // (false) if a node along the traversal is in a conflict state. | 389 // (false) if a node along the traversal is in a conflict state. |
| 387 // | 390 // |
| 388 // The result list is reversed before it is returned, so the resulting | 391 // The result list is reversed before it is returned, so the resulting |
| 389 // traversal is in top to bottom order. Also note that this function appends | 392 // traversal is in top to bottom order. Also note that this function appends |
| 390 // to the result list without clearing it. | 393 // to the result list without clearing it. |
| 391 bool Traversal::AddDeletedParents( | 394 bool Traversal::AddDeletedParents( |
| 392 const std::set<int64>& ready_unsynced_set, | 395 const std::set<int64>& ready_unsynced_set, |
| 393 const syncable::Entry& item, | 396 const syncable::Entry& item, |
| 394 const syncable::Directory::Metahandles& traversed, | 397 const syncable::Directory::Metahandles& traversed, |
| 395 syncable::Directory::Metahandles* result) const { | 398 syncable::Directory::Metahandles* result) const { |
| 399 DCHECK(SupportsHierarchy(item)); |
| 396 syncable::Directory::Metahandles dependencies; | 400 syncable::Directory::Metahandles dependencies; |
| 397 syncable::Id parent_id = item.GetParentId(); | 401 syncable::Id parent_id = item.GetParentId(); |
| 398 | 402 |
| 399 // Climb the tree adding entries leaf -> root. | 403 // Climb the tree adding entries leaf -> root. |
| 400 while (!parent_id.IsRoot()) { | 404 while (!parent_id.IsRoot()) { |
| 401 syncable::Entry parent(trans_, syncable::GET_BY_ID, parent_id); | 405 syncable::Entry parent(trans_, syncable::GET_BY_ID, parent_id); |
| 402 | 406 |
| 403 if (!parent.good()) { | 407 if (!parent.good()) { |
| 404 // This is valid because the parent could have gone away a long time ago | 408 // This is valid because the parent could have gone away a long time ago |
| 405 // | 409 // |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 } | 445 } |
| 442 | 446 |
| 443 bool Traversal::IsFull() const { | 447 bool Traversal::IsFull() const { |
| 444 return out_->size() >= max_entries_; | 448 return out_->size() >= max_entries_; |
| 445 } | 449 } |
| 446 | 450 |
| 447 bool Traversal::HaveItem(int64 handle) const { | 451 bool Traversal::HaveItem(int64 handle) const { |
| 448 return added_handles_.find(handle) != added_handles_.end(); | 452 return added_handles_.find(handle) != added_handles_.end(); |
| 449 } | 453 } |
| 450 | 454 |
| 455 bool Traversal::SupportsHierarchy(const syncable::Entry& item) const { |
| 456 return !item.GetParentId().IsNull(); |
| 457 } |
| 458 |
| 451 void Traversal::AppendManyToTraversal( | 459 void Traversal::AppendManyToTraversal( |
| 452 const syncable::Directory::Metahandles& handles) { | 460 const syncable::Directory::Metahandles& handles) { |
| 453 out_->insert(out_->end(), handles.begin(), handles.end()); | 461 out_->insert(out_->end(), handles.begin(), handles.end()); |
| 454 added_handles_.insert(handles.begin(), handles.end()); | 462 added_handles_.insert(handles.begin(), handles.end()); |
| 455 } | 463 } |
| 456 | 464 |
| 457 void Traversal::AppendToTraversal(int64 metahandle) { | 465 void Traversal::AppendToTraversal(int64 metahandle) { |
| 458 out_->push_back(metahandle); | 466 out_->push_back(metahandle); |
| 459 added_handles_.insert(metahandle); | 467 added_handles_.insert(metahandle); |
| 460 } | 468 } |
| 461 | 469 |
| 462 void Traversal::AddCreatesAndMoves( | 470 void Traversal::AddCreatesAndMoves( |
| 463 const std::set<int64>& ready_unsynced_set) { | 471 const std::set<int64>& ready_unsynced_set) { |
| 464 // Add moves and creates, and prepend their uncommitted parents. | 472 // Add moves and creates, and prepend their uncommitted parents. |
| 465 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin(); | 473 for (std::set<int64>::const_iterator iter = ready_unsynced_set.begin(); |
| 466 !IsFull() && iter != ready_unsynced_set.end(); ++iter) { | 474 !IsFull() && iter != ready_unsynced_set.end(); ++iter) { |
| 467 int64 metahandle = *iter; | 475 int64 metahandle = *iter; |
| 468 if (HaveItem(metahandle)) | 476 if (HaveItem(metahandle)) |
| 469 continue; | 477 continue; |
| 470 | 478 |
| 471 syncable::Entry entry(trans_, | 479 syncable::Entry entry(trans_, |
| 472 syncable::GET_BY_HANDLE, | 480 syncable::GET_BY_HANDLE, |
| 473 metahandle); | 481 metahandle); |
| 474 if (!entry.GetIsDel()) { | 482 if (!entry.GetIsDel()) { |
| 475 // We only commit an item + its dependencies if it and all its | 483 if (SupportsHierarchy(entry)) { |
| 476 // dependencies are not in conflict. | 484 // We only commit an item + its dependencies if it and all its |
| 477 syncable::Directory::Metahandles item_dependencies; | 485 // dependencies are not in conflict. |
| 478 if (AddUncommittedParentsAndTheirPredecessors( | 486 syncable::Directory::Metahandles item_dependencies; |
| 479 ready_unsynced_set, | 487 if (AddUncommittedParentsAndTheirPredecessors(ready_unsynced_set, entry, |
| 480 entry, | 488 &item_dependencies)) { |
| 481 &item_dependencies)) { | 489 AddPredecessorsThenItem(ready_unsynced_set, entry, |
| 482 AddPredecessorsThenItem(ready_unsynced_set, | 490 &item_dependencies); |
| 483 entry, | 491 AppendManyToTraversal(item_dependencies); |
| 484 &item_dependencies); | 492 } |
| 485 AppendManyToTraversal(item_dependencies); | 493 } else { |
| 494 // No hierarchy dependencies, just commit the item itself. |
| 495 AppendToTraversal(metahandle); |
| 486 } | 496 } |
| 487 } | 497 } |
| 488 } | 498 } |
| 489 | 499 |
| 490 // It's possible that we overcommitted while trying to expand dependent | 500 // It's possible that we overcommitted while trying to expand dependent |
| 491 // items. If so, truncate the set down to the allowed size. | 501 // items. If so, truncate the set down to the allowed size. |
| 492 if (out_->size() > max_entries_) | 502 if (out_->size() > max_entries_) |
| 493 out_->resize(max_entries_); | 503 out_->resize(max_entries_); |
| 494 } | 504 } |
| 495 | 505 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 508 | 518 |
| 509 if (std::find(deletion_list.begin(), deletion_list.end(), metahandle) != | 519 if (std::find(deletion_list.begin(), deletion_list.end(), metahandle) != |
| 510 deletion_list.end()) { | 520 deletion_list.end()) { |
| 511 continue; | 521 continue; |
| 512 } | 522 } |
| 513 | 523 |
| 514 syncable::Entry entry(trans_, syncable::GET_BY_HANDLE, | 524 syncable::Entry entry(trans_, syncable::GET_BY_HANDLE, |
| 515 metahandle); | 525 metahandle); |
| 516 | 526 |
| 517 if (entry.GetIsDel()) { | 527 if (entry.GetIsDel()) { |
| 518 syncable::Directory::Metahandles parents; | 528 if (SupportsHierarchy(entry)) { |
| 519 if (AddDeletedParents( | 529 syncable::Directory::Metahandles parents; |
| 520 ready_unsynced_set, entry, deletion_list, &parents)) { | 530 if (AddDeletedParents(ready_unsynced_set, entry, deletion_list, |
| 521 // Append parents and chilren in top to bottom order. | 531 &parents)) { |
| 522 deletion_list.insert(deletion_list.end(), | 532 // Append parents and chilren in top to bottom order. |
| 523 parents.begin(), | 533 deletion_list.insert(deletion_list.end(), parents.begin(), |
| 524 parents.end()); | 534 parents.end()); |
| 535 deletion_list.push_back(metahandle); |
| 536 } |
| 537 } else { |
| 525 deletion_list.push_back(metahandle); | 538 deletion_list.push_back(metahandle); |
| 526 } | 539 } |
| 527 } | 540 } |
| 528 } | 541 } |
| 529 | 542 |
| 530 // We've been gathering deletions in top to bottom order. Now we reverse the | 543 // We've been gathering deletions in top to bottom order. Now we reverse the |
| 531 // order as we prepare the list. | 544 // order as we prepare the list. |
| 532 std::reverse(deletion_list.begin(), deletion_list.end()); | 545 std::reverse(deletion_list.begin(), deletion_list.end()); |
| 533 AppendManyToTraversal(deletion_list); | 546 AppendManyToTraversal(deletion_list); |
| 534 | 547 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 557 // Add moves and creates, and prepend their uncommitted parents. | 570 // Add moves and creates, and prepend their uncommitted parents. |
| 558 traversal.AddCreatesAndMoves(ready_unsynced_set); | 571 traversal.AddCreatesAndMoves(ready_unsynced_set); |
| 559 | 572 |
| 560 // Add all deletes. | 573 // Add all deletes. |
| 561 traversal.AddDeletes(ready_unsynced_set); | 574 traversal.AddDeletes(ready_unsynced_set); |
| 562 } | 575 } |
| 563 | 576 |
| 564 } // namespace | 577 } // namespace |
| 565 | 578 |
| 566 } // namespace syncer | 579 } // namespace syncer |
| OLD | NEW |