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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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, and strings |
585 // initialize to empty. | 560 // 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) | |
Nicolas Zea
2011/09/21 18:09:12
Any reason you don't zero out the time fields?
akalin
2011/09/21 19:37:35
ZeroFields is called immediately shortly construct
| |
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 |