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

Side by Side Diff: chrome/browser/sync/syncable/syncable.cc

Issue 8402014: [Sync] Make GetFirstChildId return a flag indicating success (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup comments Created 9 years, 1 month 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/syncable/syncable.h" 5 #include "chrome/browser/sync/syncable/syncable.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 #include <functional> 9 #include <functional>
10 #include <iomanip> 10 #include <iomanip>
(...skipping 1699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 LOG(ERROR) << "Predecessor is not good : " 1710 LOG(ERROR) << "Predecessor is not good : "
1711 << predecessor_id.GetServerId(); 1711 << predecessor_id.GetServerId();
1712 return false; 1712 return false;
1713 } 1713 }
1714 if (predecessor.Get(PARENT_ID) != Get(PARENT_ID)) 1714 if (predecessor.Get(PARENT_ID) != Get(PARENT_ID))
1715 return false; 1715 return false;
1716 successor_id = predecessor.Get(NEXT_ID); 1716 successor_id = predecessor.Get(NEXT_ID);
1717 predecessor.Put(NEXT_ID, Get(ID)); 1717 predecessor.Put(NEXT_ID, Get(ID));
1718 } else { 1718 } else {
1719 syncable::Directory* dir = trans()->directory(); 1719 syncable::Directory* dir = trans()->directory();
1720 successor_id = dir->GetFirstChildId(trans(), Get(PARENT_ID)); 1720 if (!dir->GetFirstChildId(trans(), Get(PARENT_ID), &successor_id)) {
1721 return false;
1722 }
1721 } 1723 }
1722 if (!successor_id.IsRoot()) { 1724 if (!successor_id.IsRoot()) {
1723 MutableEntry successor(write_transaction(), GET_BY_ID, successor_id); 1725 MutableEntry successor(write_transaction(), GET_BY_ID, successor_id);
1724 if (!successor.good()) { 1726 if (!successor.good()) {
1725 LOG(ERROR) << "Successor is not good: " 1727 LOG(ERROR) << "Successor is not good: "
1726 << successor_id.GetServerId(); 1728 << successor_id.GetServerId();
1727 return false; 1729 return false;
1728 } 1730 }
1729 if (successor.Get(PARENT_ID) != Get(PARENT_ID)) 1731 if (successor.Get(PARENT_ID) != Get(PARENT_ID))
1730 return false; 1732 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 } 1765 }
1764 DCHECK_LT(result, 0); 1766 DCHECK_LT(result, 0);
1765 return Id::CreateFromClientString(base::Int64ToString(result)); 1767 return Id::CreateFromClientString(base::Int64ToString(result));
1766 } 1768 }
1767 1769
1768 bool Directory::HasChildren(BaseTransaction* trans, const Id& id) { 1770 bool Directory::HasChildren(BaseTransaction* trans, const Id& id) {
1769 ScopedKernelLock lock(this); 1771 ScopedKernelLock lock(this);
1770 return (GetPossibleFirstChild(lock, id) != NULL); 1772 return (GetPossibleFirstChild(lock, id) != NULL);
1771 } 1773 }
1772 1774
1773 Id Directory::GetFirstChildId(BaseTransaction* trans, 1775 bool Directory::GetFirstChildId(BaseTransaction* trans,
1774 const Id& parent_id) { 1776 const Id& parent_id,
1777 Id* first_child_id) {
1775 ScopedKernelLock lock(this); 1778 ScopedKernelLock lock(this);
1776 EntryKernel* entry = GetPossibleFirstChild(lock, parent_id); 1779 EntryKernel* entry = GetPossibleFirstChild(lock, parent_id);
1777 if (!entry) 1780 if (!entry) {
1778 return Id(); 1781 *first_child_id = Id();
1782 return true;
1783 }
1779 1784
1780 // Walk to the front of the list; the server position ordering 1785 // Walk to the front of the list; the server position ordering
1781 // is commonly identical to the linked-list ordering, but pending 1786 // is commonly identical to the linked-list ordering, but pending
1782 // unsynced or unapplied items may diverge. 1787 // unsynced or unapplied items may diverge.
1783 while (!entry->ref(PREV_ID).IsRoot()) { 1788 while (!entry->ref(PREV_ID).IsRoot()) {
1784 // TODO(akalin): Gracefully handle GetEntryById returning NULL
1785 // (http://crbug.com/100907).
1786 entry = GetEntryById(entry->ref(PREV_ID), &lock); 1789 entry = GetEntryById(entry->ref(PREV_ID), &lock);
1790 if (!entry) {
rlarocque 2011/10/27 02:11:33 I'm not sure how I feel about this. We should nev
akalin 2011/10/27 02:22:18 What returned ID? If this function returns false,
1791 *first_child_id = Id();
1792 return false;
1793 }
1787 } 1794 }
1788 return entry->ref(ID); 1795 *first_child_id = entry->ref(ID);
1796 return true;
1789 } 1797 }
1790 1798
1791 Id Directory::GetLastChildId(BaseTransaction* trans, 1799 bool Directory::GetLastChildIdForTest(
1792 const Id& parent_id) { 1800 BaseTransaction* trans, const Id& parent_id, Id* last_child_id) {
1793 ScopedKernelLock lock(this); 1801 ScopedKernelLock lock(this);
1794 // We can use the server positional ordering as a hint because it's generally 1802 EntryKernel* entry = GetPossibleLastChildForTest(lock, parent_id);
1795 // in sync with the local (linked-list) positional ordering, and we have an 1803 if (!entry) {
1796 // index on it. 1804 *last_child_id = Id();
1797 ParentIdChildIndex::iterator begin_range = 1805 return true;
1798 GetParentChildIndexLowerBound(lock, parent_id); 1806 }
1799 ParentIdChildIndex::iterator candidate =
1800 GetParentChildIndexUpperBound(lock, parent_id);
1801 1807
1802 while (begin_range != candidate) { 1808 // Walk to the back of the list; the server position ordering
1803 --candidate; 1809 // is commonly identical to the linked-list ordering, but pending
1804 EntryKernel* entry = *candidate; 1810 // unsynced or unapplied items may diverge.
1805 1811 while (!entry->ref(NEXT_ID).IsRoot()) {
1806 // Filter out self-looped items, which are temporarily not in the child 1812 entry = GetEntryById(entry->ref(NEXT_ID), &lock);
1807 // ordering. 1813 if (!entry) {
1808 if (entry->ref(NEXT_ID).IsRoot() || 1814 *last_child_id = Id();
1809 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { 1815 return false;
1810 // Walk to the back of the list; the server position ordering
1811 // is commonly identical to the linked-list ordering, but pending
1812 // unsynced or unapplied items may diverge.
1813 while (!entry->ref(NEXT_ID).IsRoot())
1814 // TODO(akalin): Gracefully handle GetEntryById returning NULL
1815 // (http://crbug.com/100907).
1816 entry = GetEntryById(entry->ref(NEXT_ID), &lock);
1817 return entry->ref(ID);
1818 } 1816 }
1819 } 1817 }
1820 // There were no children in the linked list. 1818
1821 return Id(); 1819 *last_child_id = entry->ref(ID);
1820 return true;
1822 } 1821 }
1823 1822
1824 Id Directory::ComputePrevIdFromServerPosition( 1823 Id Directory::ComputePrevIdFromServerPosition(
1825 const EntryKernel* entry, 1824 const EntryKernel* entry,
1826 const syncable::Id& parent_id) { 1825 const syncable::Id& parent_id) {
1827 ScopedKernelLock lock(this); 1826 ScopedKernelLock lock(this);
1828 1827
1829 // Find the natural insertion point in the parent_id_child_index, and 1828 // Find the natural insertion point in the parent_id_child_index, and
1830 // work back from there, filtering out ineligible candidates. 1829 // work back from there, filtering out ineligible candidates.
1831 ParentIdChildIndex::iterator sibling = LocateInParentChildIndex(lock, 1830 ParentIdChildIndex::iterator sibling = LocateInParentChildIndex(lock,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 // ordering. 1993 // ordering.
1995 if (entry->ref(PREV_ID).IsRoot() || 1994 if (entry->ref(PREV_ID).IsRoot() ||
1996 entry->ref(PREV_ID) != entry->ref(NEXT_ID)) { 1995 entry->ref(PREV_ID) != entry->ref(NEXT_ID)) {
1997 return entry; 1996 return entry;
1998 } 1997 }
1999 } 1998 }
2000 // There were no children in the linked list. 1999 // There were no children in the linked list.
2001 return NULL; 2000 return NULL;
2002 } 2001 }
2003 2002
2003 EntryKernel* Directory::GetPossibleLastChildForTest(
2004 const ScopedKernelLock& lock, const Id& parent_id) {
2005 // We can use the server positional ordering as a hint because it's generally
2006 // in sync with the local (linked-list) positional ordering, and we have an
2007 // index on it.
2008 ParentIdChildIndex::iterator begin_range =
2009 GetParentChildIndexLowerBound(lock, parent_id);
2010 ParentIdChildIndex::iterator candidate =
2011 GetParentChildIndexUpperBound(lock, parent_id);
2012
2013 while (begin_range != candidate) {
2014 --candidate;
2015 EntryKernel* entry = *candidate;
2016
2017 // Filter out self-looped items, which are temporarily not in the child
2018 // ordering.
2019 if (entry->ref(NEXT_ID).IsRoot() ||
2020 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) {
2021 return entry;
2022 }
2023 }
2024 // There were no children in the linked list.
2025 return NULL;
2026 }
2027
2004 } // namespace syncable 2028 } // namespace syncable
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698