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

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

Issue 8396022: [Sync] Add HasChildren() function and use it instead of GetFirstChildId() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address 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 1747 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 int64 result; 1758 int64 result;
1759 { 1759 {
1760 ScopedKernelLock lock(this); 1760 ScopedKernelLock lock(this);
1761 result = (kernel_->persisted_info.next_id)--; 1761 result = (kernel_->persisted_info.next_id)--;
1762 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; 1762 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY;
1763 } 1763 }
1764 DCHECK_LT(result, 0); 1764 DCHECK_LT(result, 0);
1765 return Id::CreateFromClientString(base::Int64ToString(result)); 1765 return Id::CreateFromClientString(base::Int64ToString(result));
1766 } 1766 }
1767 1767
1768 bool Directory::HasChildren(BaseTransaction* trans, const Id& id) {
1769 ScopedKernelLock lock(this);
1770 return (GetPossibleFirstChild(lock, id) != NULL);
1771 }
1772
1768 Id Directory::GetFirstChildId(BaseTransaction* trans, 1773 Id Directory::GetFirstChildId(BaseTransaction* trans,
1769 const Id& parent_id) { 1774 const Id& parent_id) {
1770 ScopedKernelLock lock(this); 1775 ScopedKernelLock lock(this);
1771 // We can use the server positional ordering as a hint because it's generally 1776 EntryKernel* entry = GetPossibleFirstChild(lock, parent_id);
1772 // in sync with the local (linked-list) positional ordering, and we have an 1777 if (!entry)
1773 // index on it. 1778 return Id();
1774 ParentIdChildIndex::iterator candidate = 1779
1775 GetParentChildIndexLowerBound(lock, parent_id); 1780 // Walk to the front of the list; the server position ordering
1776 ParentIdChildIndex::iterator end_range = 1781 // is commonly identical to the linked-list ordering, but pending
1777 GetParentChildIndexUpperBound(lock, parent_id); 1782 // unsynced or unapplied items may diverge.
1778 for (; candidate != end_range; ++candidate) { 1783 while (!entry->ref(PREV_ID).IsRoot()) {
1779 EntryKernel* entry = *candidate; 1784 // TODO(akalin): Gracefully handle GetEntryById returning NULL
1780 // Filter out self-looped items, which are temporarily not in the child 1785 // (http://crbug.com/100907).
1781 // ordering. 1786 entry = GetEntryById(entry->ref(PREV_ID), &lock);
1782 if (entry->ref(PREV_ID).IsRoot() ||
1783 entry->ref(PREV_ID) != entry->ref(NEXT_ID)) {
1784 // Walk to the front of the list; the server position ordering
1785 // is commonly identical to the linked-list ordering, but pending
1786 // unsynced or unapplied items may diverge.
1787 while (!entry->ref(PREV_ID).IsRoot()) {
1788 entry = GetEntryById(entry->ref(PREV_ID), &lock);
1789 }
1790 return entry->ref(ID);
1791 }
1792 } 1787 }
1793 // There were no children in the linked list. 1788 return entry->ref(ID);
1794 return Id();
1795 } 1789 }
1796 1790
1797 Id Directory::GetLastChildId(BaseTransaction* trans, 1791 Id Directory::GetLastChildId(BaseTransaction* trans,
1798 const Id& parent_id) { 1792 const Id& parent_id) {
1799 ScopedKernelLock lock(this); 1793 ScopedKernelLock lock(this);
1800 // We can use the server positional ordering as a hint because it's generally 1794 // We can use the server positional ordering as a hint because it's generally
1801 // in sync with the local (linked-list) positional ordering, and we have an 1795 // in sync with the local (linked-list) positional ordering, and we have an
1802 // index on it. 1796 // index on it.
1803 ParentIdChildIndex::iterator begin_range = 1797 ParentIdChildIndex::iterator begin_range =
1804 GetParentChildIndexLowerBound(lock, parent_id); 1798 GetParentChildIndexLowerBound(lock, parent_id);
1805 ParentIdChildIndex::iterator candidate = 1799 ParentIdChildIndex::iterator candidate =
1806 GetParentChildIndexUpperBound(lock, parent_id); 1800 GetParentChildIndexUpperBound(lock, parent_id);
1807 1801
1808 while (begin_range != candidate) { 1802 while (begin_range != candidate) {
1809 --candidate; 1803 --candidate;
1810 EntryKernel* entry = *candidate; 1804 EntryKernel* entry = *candidate;
1811 1805
1812 // Filter out self-looped items, which are temporarily not in the child 1806 // Filter out self-looped items, which are temporarily not in the child
1813 // ordering. 1807 // ordering.
1814 if (entry->ref(NEXT_ID).IsRoot() || 1808 if (entry->ref(NEXT_ID).IsRoot() ||
1815 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { 1809 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) {
1816 // Walk to the back of the list; the server position ordering 1810 // Walk to the back of the list; the server position ordering
1817 // is commonly identical to the linked-list ordering, but pending 1811 // is commonly identical to the linked-list ordering, but pending
1818 // unsynced or unapplied items may diverge. 1812 // unsynced or unapplied items may diverge.
1819 while (!entry->ref(NEXT_ID).IsRoot()) 1813 while (!entry->ref(NEXT_ID).IsRoot())
1814 // TODO(akalin): Gracefully handle GetEntryById returning NULL
1815 // (http://crbug.com/100907).
1820 entry = GetEntryById(entry->ref(NEXT_ID), &lock); 1816 entry = GetEntryById(entry->ref(NEXT_ID), &lock);
1821 return entry->ref(ID); 1817 return entry->ref(ID);
1822 } 1818 }
1823 } 1819 }
1824 // There were no children in the linked list. 1820 // There were no children in the linked list.
1825 return Id(); 1821 return Id();
1826 } 1822 }
1827 1823
1828 Id Directory::ComputePrevIdFromServerPosition( 1824 Id Directory::ComputePrevIdFromServerPosition(
1829 const EntryKernel* entry, 1825 const EntryKernel* entry,
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 Directory::ParentIdChildIndex::iterator 1950 Directory::ParentIdChildIndex::iterator
1955 Directory::GetParentChildIndexLowerBound(const ScopedKernelLock& lock, 1951 Directory::GetParentChildIndexLowerBound(const ScopedKernelLock& lock,
1956 const Id& parent_id) { 1952 const Id& parent_id) {
1957 // Peg the parent ID, and use the least values for the remaining 1953 // Peg the parent ID, and use the least values for the remaining
1958 // index variables. 1954 // index variables.
1959 return LocateInParentChildIndex(lock, parent_id, 1955 return LocateInParentChildIndex(lock, parent_id,
1960 std::numeric_limits<int64>::min(), 1956 std::numeric_limits<int64>::min(),
1961 Id::GetLeastIdForLexicographicComparison()); 1957 Id::GetLeastIdForLexicographicComparison());
1962 } 1958 }
1963 1959
1964
1965 Directory::ParentIdChildIndex::iterator 1960 Directory::ParentIdChildIndex::iterator
1966 Directory::GetParentChildIndexUpperBound(const ScopedKernelLock& lock, 1961 Directory::GetParentChildIndexUpperBound(const ScopedKernelLock& lock,
1967 const Id& parent_id) { 1962 const Id& parent_id) {
1968 // The upper bound of |parent_id|'s range is the lower 1963 // The upper bound of |parent_id|'s range is the lower
1969 // bound of |++parent_id|'s range. 1964 // bound of |++parent_id|'s range.
1970 return GetParentChildIndexLowerBound(lock, 1965 return GetParentChildIndexLowerBound(lock,
1971 parent_id.GetLexicographicSuccessor()); 1966 parent_id.GetLexicographicSuccessor());
1972 } 1967 }
1973 1968
1974 void Directory::AppendChildHandles(const ScopedKernelLock& lock, 1969 void Directory::AppendChildHandles(const ScopedKernelLock& lock,
1975 const Id& parent_id, 1970 const Id& parent_id,
1976 Directory::ChildHandles* result) { 1971 Directory::ChildHandles* result) {
1977 typedef ParentIdChildIndex::iterator iterator; 1972 typedef ParentIdChildIndex::iterator iterator;
1978 CHECK(result); 1973 CHECK(result);
1979 for (iterator i = GetParentChildIndexLowerBound(lock, parent_id), 1974 for (iterator i = GetParentChildIndexLowerBound(lock, parent_id),
1980 end = GetParentChildIndexUpperBound(lock, parent_id); 1975 end = GetParentChildIndexUpperBound(lock, parent_id);
1981 i != end; ++i) { 1976 i != end; ++i) {
1982 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID)); 1977 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID));
1983 result->push_back((*i)->ref(META_HANDLE)); 1978 result->push_back((*i)->ref(META_HANDLE));
1984 } 1979 }
1985 } 1980 }
1986 1981
1982 EntryKernel* Directory::GetPossibleFirstChild(
1983 const ScopedKernelLock& lock, const Id& parent_id) {
1984 // We can use the server positional ordering as a hint because it's generally
1985 // in sync with the local (linked-list) positional ordering, and we have an
1986 // index on it.
1987 ParentIdChildIndex::iterator candidate =
1988 GetParentChildIndexLowerBound(lock, parent_id);
1989 ParentIdChildIndex::iterator end_range =
1990 GetParentChildIndexUpperBound(lock, parent_id);
1991 for (; candidate != end_range; ++candidate) {
1992 EntryKernel* entry = *candidate;
1993 // Filter out self-looped items, which are temporarily not in the child
1994 // ordering.
1995 if (entry->ref(PREV_ID).IsRoot() ||
1996 entry->ref(PREV_ID) != entry->ref(NEXT_ID)) {
1997 return entry;
1998 }
1999 }
2000 // There were no children in the linked list.
2001 return NULL;
2002 }
2003
1987 } // namespace syncable 2004 } // namespace syncable
OLDNEW
« no previous file with comments | « chrome/browser/sync/syncable/syncable.h ('k') | chrome/browser/sync/syncable/syncable_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698