| OLD | NEW |
| 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 "build/build_config.h" | |
| 8 | |
| 9 #include <sys/stat.h> | |
| 10 #if defined(OS_POSIX) | |
| 11 #include <sys/time.h> | |
| 12 #endif | |
| 13 #include <sys/types.h> | |
| 14 #include <time.h> | |
| 15 #if defined(OS_MACOSX) | |
| 16 #include <CoreFoundation/CoreFoundation.h> | |
| 17 #elif defined(OS_WIN) | |
| 18 #include <shlwapi.h> // for PathMatchSpec | |
| 19 #endif | |
| 20 | |
| 21 #include <algorithm> | 7 #include <algorithm> |
| 22 #include <cstring> | 8 #include <cstring> |
| 23 #include <functional> | 9 #include <functional> |
| 24 #include <iomanip> | 10 #include <iomanip> |
| 25 #include <iterator> | 11 #include <iterator> |
| 26 #include <limits> | 12 #include <limits> |
| 27 #include <set> | 13 #include <set> |
| 28 #include <string> | 14 #include <string> |
| 29 | 15 |
| 30 #include "base/compiler_specific.h" | 16 #include "base/compiler_specific.h" |
| 31 #include "base/file_util.h" | 17 #include "base/file_util.h" |
| 32 #include "base/hash_tables.h" | 18 #include "base/hash_tables.h" |
| 33 #include "base/logging.h" | 19 #include "base/logging.h" |
| 34 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
| 35 #include "base/perftimer.h" | 21 #include "base/perftimer.h" |
| 36 #include "base/stl_util.h" | 22 #include "base/stl_util.h" |
| 37 #include "base/string_number_conversions.h" | 23 #include "base/string_number_conversions.h" |
| 38 #include "base/string_util.h" | 24 #include "base/string_util.h" |
| 39 #include "base/time.h" | |
| 40 #include "base/tracked.h" | 25 #include "base/tracked.h" |
| 41 #include "base/utf_string_conversions.h" | 26 #include "base/utf_string_conversions.h" |
| 42 #include "base/values.h" | 27 #include "base/values.h" |
| 43 #include "chrome/browser/sync/protocol/proto_value_conversions.h" | 28 #include "chrome/browser/sync/protocol/proto_value_conversions.h" |
| 44 #include "chrome/browser/sync/protocol/service_constants.h" | 29 #include "chrome/browser/sync/protocol/service_constants.h" |
| 45 #include "chrome/browser/sync/syncable/directory_backing_store.h" | 30 #include "chrome/browser/sync/syncable/directory_backing_store.h" |
| 46 #include "chrome/browser/sync/syncable/directory_change_delegate.h" | 31 #include "chrome/browser/sync/syncable/directory_change_delegate.h" |
| 47 #include "chrome/browser/sync/syncable/directory_manager.h" | 32 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 48 #include "chrome/browser/sync/syncable/model_type.h" | 33 #include "chrome/browser/sync/syncable/model_type.h" |
| 49 #include "chrome/browser/sync/syncable/syncable_changes_version.h" | 34 #include "chrome/browser/sync/syncable/syncable_changes_version.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 ListValue* EntryKernelMutationMapToValue( | 90 ListValue* EntryKernelMutationMapToValue( |
| 106 const EntryKernelMutationMap& mutations) { | 91 const EntryKernelMutationMap& mutations) { |
| 107 ListValue* list = new ListValue(); | 92 ListValue* list = new ListValue(); |
| 108 for (EntryKernelMutationMap::const_iterator it = mutations.begin(); | 93 for (EntryKernelMutationMap::const_iterator it = mutations.begin(); |
| 109 it != mutations.end(); ++it) { | 94 it != mutations.end(); ++it) { |
| 110 list->Append(EntryKernelMutationToValue(it->second)); | 95 list->Append(EntryKernelMutationToValue(it->second)); |
| 111 } | 96 } |
| 112 return list; | 97 return list; |
| 113 } | 98 } |
| 114 | 99 |
| 115 int64 Now() { | |
| 116 #if defined(OS_WIN) | |
| 117 FILETIME filetime; | |
| 118 SYSTEMTIME systime; | |
| 119 GetSystemTime(&systime); | |
| 120 SystemTimeToFileTime(&systime, &filetime); | |
| 121 // MSDN recommends converting via memcpy like this. | |
| 122 LARGE_INTEGER n; | |
| 123 memcpy(&n, &filetime, sizeof(filetime)); | |
| 124 return n.QuadPart; | |
| 125 #elif defined(OS_POSIX) | |
| 126 struct timeval tv; | |
| 127 gettimeofday(&tv, NULL); | |
| 128 return static_cast<int64>(tv.tv_sec); | |
| 129 #else | |
| 130 #error NEED OS SPECIFIC Now() implementation | |
| 131 #endif | |
| 132 } | |
| 133 | |
| 134 namespace { | 100 namespace { |
| 135 | 101 |
| 136 // A ScopedIndexUpdater temporarily removes an entry from an index, | 102 // A ScopedIndexUpdater temporarily removes an entry from an index, |
| 137 // and restores it to the index when the scope exits. This simplifies | 103 // and restores it to the index when the scope exits. This simplifies |
| 138 // the common pattern where items need to be removed from an index | 104 // the common pattern where items need to be removed from an index |
| 139 // before updating the field. | 105 // before updating the field. |
| 140 // | 106 // |
| 141 // This class is parameterized on the Indexer traits type, which | 107 // This class is parameterized on the Indexer traits type, which |
| 142 // must define a Comparator and a static bool ShouldInclude | 108 // must define a Comparator and a static bool ShouldInclude |
| 143 // function for testing whether the item ought to be included | 109 // function for testing whether the item ought to be included |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 dictionary_value->Set(key, value); | 236 dictionary_value->Set(key, value); |
| 271 } | 237 } |
| 272 } | 238 } |
| 273 | 239 |
| 274 // Helper functions for SetFieldValues(). | 240 // Helper functions for SetFieldValues(). |
| 275 | 241 |
| 276 StringValue* Int64ToValue(int64 i) { | 242 StringValue* Int64ToValue(int64 i) { |
| 277 return Value::CreateStringValue(base::Int64ToString(i)); | 243 return Value::CreateStringValue(base::Int64ToString(i)); |
| 278 } | 244 } |
| 279 | 245 |
| 246 StringValue* TimeToValue(const base::Time& t) { |
| 247 return Value::CreateStringValue(browser_sync::GetTimeDebugString(t)); |
| 248 } |
| 249 |
| 280 StringValue* IdToValue(const Id& id) { | 250 StringValue* IdToValue(const Id& id) { |
| 281 return id.ToValue(); | 251 return id.ToValue(); |
| 282 } | 252 } |
| 283 | 253 |
| 284 } // namespace | 254 } // namespace |
| 285 | 255 |
| 286 DictionaryValue* EntryKernel::ToValue() const { | 256 DictionaryValue* EntryKernel::ToValue() const { |
| 287 DictionaryValue* kernel_info = new DictionaryValue(); | 257 DictionaryValue* kernel_info = new DictionaryValue(); |
| 288 kernel_info->SetBoolean("isDirty", is_dirty()); | 258 kernel_info->SetBoolean("isDirty", is_dirty()); |
| 289 | 259 |
| 290 // Int64 fields. | 260 // Int64 fields. |
| 291 SetFieldValues(*this, kernel_info, | 261 SetFieldValues(*this, kernel_info, |
| 292 &GetMetahandleFieldString, &Int64ToValue, | 262 &GetMetahandleFieldString, &Int64ToValue, |
| 293 INT64_FIELDS_BEGIN, META_HANDLE); | 263 INT64_FIELDS_BEGIN, META_HANDLE); |
| 294 SetFieldValues(*this, kernel_info, | 264 SetFieldValues(*this, kernel_info, |
| 295 &GetBaseVersionString, &Int64ToValue, | 265 &GetBaseVersionString, &Int64ToValue, |
| 296 META_HANDLE + 1, BASE_VERSION); | 266 META_HANDLE + 1, BASE_VERSION); |
| 297 SetFieldValues(*this, kernel_info, | 267 SetFieldValues(*this, kernel_info, |
| 298 &GetInt64FieldString, &Int64ToValue, | 268 &GetInt64FieldString, &Int64ToValue, |
| 299 BASE_VERSION + 1, INT64_FIELDS_END - 1); | 269 BASE_VERSION + 1, INT64_FIELDS_END - 1); |
| 300 | 270 |
| 271 // Time fields. |
| 272 SetFieldValues(*this, kernel_info, |
| 273 &GetTimeFieldString, &TimeToValue, |
| 274 TIME_FIELDS_BEGIN, TIME_FIELDS_END - 1); |
| 275 |
| 301 // ID fields. | 276 // ID fields. |
| 302 SetFieldValues(*this, kernel_info, | 277 SetFieldValues(*this, kernel_info, |
| 303 &GetIdFieldString, &IdToValue, | 278 &GetIdFieldString, &IdToValue, |
| 304 ID_FIELDS_BEGIN, ID_FIELDS_END - 1); | 279 ID_FIELDS_BEGIN, ID_FIELDS_END - 1); |
| 305 | 280 |
| 306 // Bit fields. | 281 // Bit fields. |
| 307 SetFieldValues(*this, kernel_info, | 282 SetFieldValues(*this, kernel_info, |
| 308 &GetIndexedBitFieldString, &Value::CreateBooleanValue, | 283 &GetIndexedBitFieldString, &Value::CreateBooleanValue, |
| 309 BIT_FIELDS_BEGIN, INDEXED_BIT_FIELDS_END - 1); | 284 BIT_FIELDS_BEGIN, INDEXED_BIT_FIELDS_END - 1); |
| 310 SetFieldValues(*this, kernel_info, | 285 SetFieldValues(*this, kernel_info, |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 | 549 |
| 575 AppendChildHandles(lock, kernel->ref(ID), result); | 550 AppendChildHandles(lock, kernel->ref(ID), result); |
| 576 } | 551 } |
| 577 | 552 |
| 578 EntryKernel* Directory::GetRootEntry() { | 553 EntryKernel* Directory::GetRootEntry() { |
| 579 return GetEntryById(Id()); | 554 return GetEntryById(Id()); |
| 580 } | 555 } |
| 581 | 556 |
| 582 void ZeroFields(EntryKernel* entry, int first_field) { | 557 void ZeroFields(EntryKernel* entry, int first_field) { |
| 583 int i = first_field; | 558 int i = first_field; |
| 584 // Note that bitset<> constructor sets all bits to zero, and strings | 559 // Note that bitset<> constructor sets all bits to zero, Time |
| 585 // initialize to empty. | 560 // objects initialize to 0, and strings initialize to empty. |
| 586 for ( ; i < INT64_FIELDS_END; ++i) | 561 for ( ; i < INT64_FIELDS_END; ++i) |
| 587 entry->put(static_cast<Int64Field>(i), 0); | 562 entry->put(static_cast<Int64Field>(i), 0); |
| 563 if (i < TIME_FIELDS_END) |
| 564 i = TIME_FIELDS_END; |
| 588 for ( ; i < ID_FIELDS_END; ++i) | 565 for ( ; i < ID_FIELDS_END; ++i) |
| 589 entry->mutable_ref(static_cast<IdField>(i)).Clear(); | 566 entry->mutable_ref(static_cast<IdField>(i)).Clear(); |
| 590 for ( ; i < BIT_FIELDS_END; ++i) | 567 for ( ; i < BIT_FIELDS_END; ++i) |
| 591 entry->put(static_cast<BitField>(i), false); | 568 entry->put(static_cast<BitField>(i), false); |
| 592 if (i < PROTO_FIELDS_END) | 569 if (i < PROTO_FIELDS_END) |
| 593 i = PROTO_FIELDS_END; | 570 i = PROTO_FIELDS_END; |
| 594 entry->clear_dirty(NULL); | 571 entry->clear_dirty(NULL); |
| 595 } | 572 } |
| 596 | 573 |
| 597 void Directory::InsertEntry(EntryKernel* entry) { | 574 void Directory::InsertEntry(EntryKernel* entry) { |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1401 | 1378 |
| 1402 void MutableEntry::Init(WriteTransaction* trans, const Id& parent_id, | 1379 void MutableEntry::Init(WriteTransaction* trans, const Id& parent_id, |
| 1403 const string& name) { | 1380 const string& name) { |
| 1404 kernel_ = new EntryKernel; | 1381 kernel_ = new EntryKernel; |
| 1405 ZeroFields(kernel_, BEGIN_FIELDS); | 1382 ZeroFields(kernel_, BEGIN_FIELDS); |
| 1406 kernel_->put(ID, trans->directory_->NextId()); | 1383 kernel_->put(ID, trans->directory_->NextId()); |
| 1407 kernel_->put(META_HANDLE, trans->directory_->NextMetahandle()); | 1384 kernel_->put(META_HANDLE, trans->directory_->NextMetahandle()); |
| 1408 kernel_->mark_dirty(trans->directory_->kernel_->dirty_metahandles); | 1385 kernel_->mark_dirty(trans->directory_->kernel_->dirty_metahandles); |
| 1409 kernel_->put(PARENT_ID, parent_id); | 1386 kernel_->put(PARENT_ID, parent_id); |
| 1410 kernel_->put(NON_UNIQUE_NAME, name); | 1387 kernel_->put(NON_UNIQUE_NAME, name); |
| 1411 const int64 now = Now(); | 1388 const base::Time& now = base::Time::Now(); |
| 1412 kernel_->put(CTIME, now); | 1389 kernel_->put(CTIME, now); |
| 1413 kernel_->put(MTIME, now); | 1390 kernel_->put(MTIME, now); |
| 1414 // We match the database defaults here | 1391 // We match the database defaults here |
| 1415 kernel_->put(BASE_VERSION, CHANGES_VERSION); | 1392 kernel_->put(BASE_VERSION, CHANGES_VERSION); |
| 1416 trans->directory()->InsertEntry(kernel_); | 1393 trans->directory()->InsertEntry(kernel_); |
| 1417 // Because this entry is new, it was originally deleted. | 1394 // Because this entry is new, it was originally deleted. |
| 1418 kernel_->put(IS_DEL, true); | 1395 kernel_->put(IS_DEL, true); |
| 1419 trans->SaveOriginal(kernel_); | 1396 trans->SaveOriginal(kernel_); |
| 1420 kernel_->put(IS_DEL, false); | 1397 kernel_->put(IS_DEL, false); |
| 1421 } | 1398 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 dir()->kernel_->parent_id_child_index); | 1474 dir()->kernel_->parent_id_child_index); |
| 1498 kernel_->put(field, value); | 1475 kernel_->put(field, value); |
| 1499 } else { | 1476 } else { |
| 1500 kernel_->put(field, value); | 1477 kernel_->put(field, value); |
| 1501 } | 1478 } |
| 1502 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); | 1479 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); |
| 1503 } | 1480 } |
| 1504 return true; | 1481 return true; |
| 1505 } | 1482 } |
| 1506 | 1483 |
| 1484 bool MutableEntry::Put(TimeField field, const base::Time& value) { |
| 1485 DCHECK(kernel_); |
| 1486 if (kernel_->ref(field) != value) { |
| 1487 kernel_->put(field, value); |
| 1488 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); |
| 1489 } |
| 1490 return true; |
| 1491 } |
| 1492 |
| 1507 bool MutableEntry::Put(IdField field, const Id& value) { | 1493 bool MutableEntry::Put(IdField field, const Id& value) { |
| 1508 DCHECK(kernel_); | 1494 DCHECK(kernel_); |
| 1509 if (kernel_->ref(field) != value) { | 1495 if (kernel_->ref(field) != value) { |
| 1510 if (ID == field) { | 1496 if (ID == field) { |
| 1511 if (!dir()->ReindexId(kernel_, value)) | 1497 if (!dir()->ReindexId(kernel_, value)) |
| 1512 return false; | 1498 return false; |
| 1513 } else if (PARENT_ID == field) { | 1499 } else if (PARENT_ID == field) { |
| 1514 PutParentIdPropertyOnly(value); // Makes sibling order inconsistent. | 1500 PutParentIdPropertyOnly(value); // Makes sibling order inconsistent. |
| 1515 PutPredecessor(Id()); // Fixes up the sibling order inconsistency. | 1501 PutPredecessor(Id()); // Fixes up the sibling order inconsistency. |
| 1516 } else { | 1502 } else { |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1869 e->Put(SYNCING, false); | 1855 e->Put(SYNCING, false); |
| 1870 } | 1856 } |
| 1871 | 1857 |
| 1872 std::ostream& operator<<(std::ostream& os, const Entry& entry) { | 1858 std::ostream& operator<<(std::ostream& os, const Entry& entry) { |
| 1873 int i; | 1859 int i; |
| 1874 EntryKernel* const kernel = entry.kernel_; | 1860 EntryKernel* const kernel = entry.kernel_; |
| 1875 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { | 1861 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { |
| 1876 os << g_metas_columns[i].name << ": " | 1862 os << g_metas_columns[i].name << ": " |
| 1877 << kernel->ref(static_cast<Int64Field>(i)) << ", "; | 1863 << kernel->ref(static_cast<Int64Field>(i)) << ", "; |
| 1878 } | 1864 } |
| 1865 for ( ; i < TIME_FIELDS_END; ++i) { |
| 1866 os << g_metas_columns[i].name << ": " |
| 1867 << browser_sync::GetTimeDebugString( |
| 1868 kernel->ref(static_cast<TimeField>(i))) << ", "; |
| 1869 } |
| 1879 for ( ; i < ID_FIELDS_END; ++i) { | 1870 for ( ; i < ID_FIELDS_END; ++i) { |
| 1880 os << g_metas_columns[i].name << ": " | 1871 os << g_metas_columns[i].name << ": " |
| 1881 << kernel->ref(static_cast<IdField>(i)) << ", "; | 1872 << kernel->ref(static_cast<IdField>(i)) << ", "; |
| 1882 } | 1873 } |
| 1883 os << "Flags: "; | 1874 os << "Flags: "; |
| 1884 for ( ; i < BIT_FIELDS_END; ++i) { | 1875 for ( ; i < BIT_FIELDS_END; ++i) { |
| 1885 if (kernel->ref(static_cast<BitField>(i))) | 1876 if (kernel->ref(static_cast<BitField>(i))) |
| 1886 os << g_metas_columns[i].name << ", "; | 1877 os << g_metas_columns[i].name << ", "; |
| 1887 } | 1878 } |
| 1888 for ( ; i < STRING_FIELDS_END; ++i) { | 1879 for ( ; i < STRING_FIELDS_END; ++i) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 CHECK(result); | 1939 CHECK(result); |
| 1949 for (iterator i = GetParentChildIndexLowerBound(lock, parent_id), | 1940 for (iterator i = GetParentChildIndexLowerBound(lock, parent_id), |
| 1950 end = GetParentChildIndexUpperBound(lock, parent_id); | 1941 end = GetParentChildIndexUpperBound(lock, parent_id); |
| 1951 i != end; ++i) { | 1942 i != end; ++i) { |
| 1952 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID)); | 1943 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID)); |
| 1953 result->push_back((*i)->ref(META_HANDLE)); | 1944 result->push_back((*i)->ref(META_HANDLE)); |
| 1954 } | 1945 } |
| 1955 } | 1946 } |
| 1956 | 1947 |
| 1957 } // namespace syncable | 1948 } // namespace syncable |
| OLD | NEW |