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 #ifndef CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ | 5 #ifndef CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ |
6 #define CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ | 6 #define CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <bitset> | 10 #include <bitset> |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "base/synchronization/lock.h" | 27 #include "base/synchronization/lock.h" |
28 #include "base/time.h" | 28 #include "base/time.h" |
29 #include "chrome/browser/sync/protocol/sync.pb.h" | 29 #include "chrome/browser/sync/protocol/sync.pb.h" |
30 #include "chrome/browser/sync/syncable/blob.h" | 30 #include "chrome/browser/sync/syncable/blob.h" |
31 #include "chrome/browser/sync/syncable/dir_open_result.h" | 31 #include "chrome/browser/sync/syncable/dir_open_result.h" |
32 #include "chrome/browser/sync/syncable/directory_event.h" | 32 #include "chrome/browser/sync/syncable/directory_event.h" |
33 #include "chrome/browser/sync/syncable/syncable_id.h" | 33 #include "chrome/browser/sync/syncable/syncable_id.h" |
34 #include "chrome/browser/sync/syncable/model_type.h" | 34 #include "chrome/browser/sync/syncable/model_type.h" |
35 #include "chrome/browser/sync/util/dbgq.h" | 35 #include "chrome/browser/sync/util/dbgq.h" |
36 #include "chrome/browser/sync/util/immutable.h" | 36 #include "chrome/browser/sync/util/immutable.h" |
| 37 #include "chrome/browser/sync/util/time.h" |
37 | 38 |
38 struct PurgeInfo; | 39 struct PurgeInfo; |
39 | 40 |
40 namespace base { | 41 namespace base { |
41 class DictionaryValue; | 42 class DictionaryValue; |
42 class ListValue; | 43 class ListValue; |
43 } | 44 } |
44 | 45 |
45 namespace sync_api { | 46 namespace sync_api { |
46 class ReadTransaction; | 47 class ReadTransaction; |
47 class WriteNode; | 48 class WriteNode; |
48 class ReadNode; | 49 class ReadNode; |
49 } // sync_api | 50 } // sync_api |
50 | 51 |
51 namespace syncable { | 52 namespace syncable { |
52 class DirectoryChangeDelegate; | 53 class DirectoryChangeDelegate; |
53 class TransactionObserver; | 54 class TransactionObserver; |
54 class Entry; | 55 class Entry; |
55 | 56 |
56 std::ostream& operator<<(std::ostream& s, const Entry& e); | 57 std::ostream& operator<<(std::ostream& s, const Entry& e); |
57 | 58 |
58 class DirectoryBackingStore; | 59 class DirectoryBackingStore; |
59 | 60 |
60 static const int64 kInvalidMetaHandle = 0; | 61 static const int64 kInvalidMetaHandle = 0; |
61 | 62 |
62 // Update syncable_enum_conversions{.h,.cc,_unittest.cc} if you change | 63 // Things you need to update if you change any of the fields below: |
63 // any fields in this file. | 64 // - EntryKernel struct in syncable.h (this file) |
| 65 // - syncable_columns.h |
| 66 // - syncable_enum_conversions{.h,.cc,_unittest.cc} |
| 67 // - EntryKernel::EntryKernel(), EntryKernel::ToValue(), operator<< |
| 68 // for Entry in syncable.cc |
| 69 // - BindFields() and UnpackEntry() in directory_backing_store.cc |
| 70 // - TestSimpleFieldsPreservedDuringSaveChanges in syncable_unittest.cc |
64 | 71 |
65 enum { | 72 enum { |
66 BEGIN_FIELDS = 0, | 73 BEGIN_FIELDS = 0, |
67 INT64_FIELDS_BEGIN = BEGIN_FIELDS | 74 INT64_FIELDS_BEGIN = BEGIN_FIELDS |
68 }; | 75 }; |
69 | 76 |
70 enum MetahandleField { | 77 enum MetahandleField { |
71 // Primary key into the table. Keep this as a handle to the meta entry | 78 // Primary key into the table. Keep this as a handle to the meta entry |
72 // across transactions. | 79 // across transactions. |
73 META_HANDLE = INT64_FIELDS_BEGIN | 80 META_HANDLE = INT64_FIELDS_BEGIN |
74 }; | 81 }; |
75 | 82 |
76 enum BaseVersion { | 83 enum BaseVersion { |
77 // After initial upload, the version is controlled by the server, and is | 84 // After initial upload, the version is controlled by the server, and is |
78 // increased whenever the data or metadata changes on the server. | 85 // increased whenever the data or metadata changes on the server. |
79 BASE_VERSION = META_HANDLE + 1, | 86 BASE_VERSION = META_HANDLE + 1, |
80 }; | 87 }; |
81 | 88 |
82 enum Int64Field { | 89 enum Int64Field { |
83 SERVER_VERSION = BASE_VERSION + 1, | 90 SERVER_VERSION = BASE_VERSION + 1, |
84 MTIME, | |
85 SERVER_MTIME, | |
86 CTIME, | |
87 SERVER_CTIME, | |
88 | 91 |
89 // A numeric position value that indicates the relative ordering of | 92 // A numeric position value that indicates the relative ordering of |
90 // this object among its siblings. | 93 // this object among its siblings. |
91 SERVER_POSITION_IN_PARENT, | 94 SERVER_POSITION_IN_PARENT, |
92 | 95 |
93 LOCAL_EXTERNAL_ID, // ID of an item in the external local storage that this | 96 LOCAL_EXTERNAL_ID, // ID of an item in the external local storage that this |
94 // entry is associated with. (such as bookmarks.js) | 97 // entry is associated with. (such as bookmarks.js) |
95 | 98 |
96 INT64_FIELDS_END | 99 INT64_FIELDS_END |
97 }; | 100 }; |
98 | 101 |
99 enum { | 102 enum { |
100 INT64_FIELDS_COUNT = INT64_FIELDS_END, | 103 INT64_FIELDS_COUNT = INT64_FIELDS_END - INT64_FIELDS_BEGIN, |
101 ID_FIELDS_BEGIN = INT64_FIELDS_END, | 104 TIME_FIELDS_BEGIN = INT64_FIELDS_END, |
| 105 }; |
| 106 |
| 107 enum TimeField { |
| 108 MTIME = TIME_FIELDS_BEGIN, |
| 109 SERVER_MTIME, |
| 110 CTIME, |
| 111 SERVER_CTIME, |
| 112 TIME_FIELDS_END, |
| 113 }; |
| 114 |
| 115 enum { |
| 116 TIME_FIELDS_COUNT = TIME_FIELDS_END - TIME_FIELDS_BEGIN, |
| 117 ID_FIELDS_BEGIN = TIME_FIELDS_END, |
102 }; | 118 }; |
103 | 119 |
104 enum IdField { | 120 enum IdField { |
105 // Code in InitializeTables relies on ID being the first IdField value. | 121 // Code in InitializeTables relies on ID being the first IdField value. |
106 ID = ID_FIELDS_BEGIN, | 122 ID = ID_FIELDS_BEGIN, |
107 PARENT_ID, | 123 PARENT_ID, |
108 SERVER_PARENT_ID, | 124 SERVER_PARENT_ID, |
109 | 125 |
110 PREV_ID, | 126 PREV_ID, |
111 NEXT_ID, | 127 NEXT_ID, |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 | 246 |
231 // Why the singular enums? So the code compile-time dispatches instead of | 247 // Why the singular enums? So the code compile-time dispatches instead of |
232 // runtime dispatches as it would with a single enum and an if() statement. | 248 // runtime dispatches as it would with a single enum and an if() statement. |
233 | 249 |
234 // The EntryKernel class contains the actual data for an entry. | 250 // The EntryKernel class contains the actual data for an entry. |
235 struct EntryKernel { | 251 struct EntryKernel { |
236 private: | 252 private: |
237 std::string string_fields[STRING_FIELDS_COUNT]; | 253 std::string string_fields[STRING_FIELDS_COUNT]; |
238 sync_pb::EntitySpecifics specifics_fields[PROTO_FIELDS_COUNT]; | 254 sync_pb::EntitySpecifics specifics_fields[PROTO_FIELDS_COUNT]; |
239 int64 int64_fields[INT64_FIELDS_COUNT]; | 255 int64 int64_fields[INT64_FIELDS_COUNT]; |
| 256 base::Time time_fields[TIME_FIELDS_COUNT]; |
240 Id id_fields[ID_FIELDS_COUNT]; | 257 Id id_fields[ID_FIELDS_COUNT]; |
241 std::bitset<BIT_FIELDS_COUNT> bit_fields; | 258 std::bitset<BIT_FIELDS_COUNT> bit_fields; |
242 std::bitset<BIT_TEMPS_COUNT> bit_temps; | 259 std::bitset<BIT_TEMPS_COUNT> bit_temps; |
243 | 260 |
244 public: | 261 public: |
245 EntryKernel(); | 262 EntryKernel(); |
246 ~EntryKernel(); | 263 ~EntryKernel(); |
247 | 264 |
248 // Set the dirty bit, and optionally add this entry's metahandle to | 265 // Set the dirty bit, and optionally add this entry's metahandle to |
249 // a provided index on dirty bits in |dirty_index|. Parameter may be null, | 266 // a provided index on dirty bits in |dirty_index|. Parameter may be null, |
(...skipping 21 matching lines...) Expand all Loading... |
271 return dirty_; | 288 return dirty_; |
272 } | 289 } |
273 | 290 |
274 // Setters. | 291 // Setters. |
275 inline void put(MetahandleField field, int64 value) { | 292 inline void put(MetahandleField field, int64 value) { |
276 int64_fields[field - INT64_FIELDS_BEGIN] = value; | 293 int64_fields[field - INT64_FIELDS_BEGIN] = value; |
277 } | 294 } |
278 inline void put(Int64Field field, int64 value) { | 295 inline void put(Int64Field field, int64 value) { |
279 int64_fields[field - INT64_FIELDS_BEGIN] = value; | 296 int64_fields[field - INT64_FIELDS_BEGIN] = value; |
280 } | 297 } |
| 298 inline void put(TimeField field, const base::Time& value) { |
| 299 // Round-trip to proto time format and back so that we have |
| 300 // consistent time resolutions (ms). |
| 301 time_fields[field - TIME_FIELDS_BEGIN] = |
| 302 browser_sync::ProtoTimeToTime( |
| 303 browser_sync::TimeToProtoTime(value)); |
| 304 } |
281 inline void put(IdField field, const Id& value) { | 305 inline void put(IdField field, const Id& value) { |
282 id_fields[field - ID_FIELDS_BEGIN] = value; | 306 id_fields[field - ID_FIELDS_BEGIN] = value; |
283 } | 307 } |
284 inline void put(BaseVersion field, int64 value) { | 308 inline void put(BaseVersion field, int64 value) { |
285 int64_fields[field - INT64_FIELDS_BEGIN] = value; | 309 int64_fields[field - INT64_FIELDS_BEGIN] = value; |
286 } | 310 } |
287 inline void put(IndexedBitField field, bool value) { | 311 inline void put(IndexedBitField field, bool value) { |
288 bit_fields[field - BIT_FIELDS_BEGIN] = value; | 312 bit_fields[field - BIT_FIELDS_BEGIN] = value; |
289 } | 313 } |
290 inline void put(IsDelField field, bool value) { | 314 inline void put(IsDelField field, bool value) { |
(...skipping 12 matching lines...) Expand all Loading... |
303 bit_temps[field - BIT_TEMPS_BEGIN] = value; | 327 bit_temps[field - BIT_TEMPS_BEGIN] = value; |
304 } | 328 } |
305 | 329 |
306 // Const ref getters. | 330 // Const ref getters. |
307 inline int64 ref(MetahandleField field) const { | 331 inline int64 ref(MetahandleField field) const { |
308 return int64_fields[field - INT64_FIELDS_BEGIN]; | 332 return int64_fields[field - INT64_FIELDS_BEGIN]; |
309 } | 333 } |
310 inline int64 ref(Int64Field field) const { | 334 inline int64 ref(Int64Field field) const { |
311 return int64_fields[field - INT64_FIELDS_BEGIN]; | 335 return int64_fields[field - INT64_FIELDS_BEGIN]; |
312 } | 336 } |
| 337 inline const base::Time& ref(TimeField field) const { |
| 338 return time_fields[field - TIME_FIELDS_BEGIN]; |
| 339 } |
313 inline const Id& ref(IdField field) const { | 340 inline const Id& ref(IdField field) const { |
314 return id_fields[field - ID_FIELDS_BEGIN]; | 341 return id_fields[field - ID_FIELDS_BEGIN]; |
315 } | 342 } |
316 inline int64 ref(BaseVersion field) const { | 343 inline int64 ref(BaseVersion field) const { |
317 return int64_fields[field - INT64_FIELDS_BEGIN]; | 344 return int64_fields[field - INT64_FIELDS_BEGIN]; |
318 } | 345 } |
319 inline bool ref(IndexedBitField field) const { | 346 inline bool ref(IndexedBitField field) const { |
320 return bit_fields[field - BIT_FIELDS_BEGIN]; | 347 return bit_fields[field - BIT_FIELDS_BEGIN]; |
321 } | 348 } |
322 inline bool ref(IsDelField field) const { | 349 inline bool ref(IsDelField field) const { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 return kernel_->ref(field); | 409 return kernel_->ref(field); |
383 } | 410 } |
384 inline Id Get(IdField field) const { | 411 inline Id Get(IdField field) const { |
385 DCHECK(kernel_); | 412 DCHECK(kernel_); |
386 return kernel_->ref(field); | 413 return kernel_->ref(field); |
387 } | 414 } |
388 inline int64 Get(Int64Field field) const { | 415 inline int64 Get(Int64Field field) const { |
389 DCHECK(kernel_); | 416 DCHECK(kernel_); |
390 return kernel_->ref(field); | 417 return kernel_->ref(field); |
391 } | 418 } |
| 419 inline const base::Time& Get(TimeField field) const { |
| 420 DCHECK(kernel_); |
| 421 return kernel_->ref(field); |
| 422 } |
392 inline int64 Get(BaseVersion field) const { | 423 inline int64 Get(BaseVersion field) const { |
393 DCHECK(kernel_); | 424 DCHECK(kernel_); |
394 return kernel_->ref(field); | 425 return kernel_->ref(field); |
395 } | 426 } |
396 inline bool Get(IndexedBitField field) const { | 427 inline bool Get(IndexedBitField field) const { |
397 DCHECK(kernel_); | 428 DCHECK(kernel_); |
398 return kernel_->ref(field); | 429 return kernel_->ref(field); |
399 } | 430 } |
400 inline bool Get(IsDelField field) const { | 431 inline bool Get(IsDelField field) const { |
401 DCHECK(kernel_); | 432 DCHECK(kernel_); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 | 514 |
484 inline WriteTransaction* write_transaction() const { | 515 inline WriteTransaction* write_transaction() const { |
485 return write_transaction_; | 516 return write_transaction_; |
486 } | 517 } |
487 | 518 |
488 // Field Accessors. Some of them trigger the re-indexing of the entry. | 519 // Field Accessors. Some of them trigger the re-indexing of the entry. |
489 // Return true on success, return false on failure, which means | 520 // Return true on success, return false on failure, which means |
490 // that putting the value would have caused a duplicate in the index. | 521 // that putting the value would have caused a duplicate in the index. |
491 // TODO(chron): Remove some of these unecessary return values. | 522 // TODO(chron): Remove some of these unecessary return values. |
492 bool Put(Int64Field field, const int64& value); | 523 bool Put(Int64Field field, const int64& value); |
| 524 bool Put(TimeField field, const base::Time& value); |
493 bool Put(IdField field, const Id& value); | 525 bool Put(IdField field, const Id& value); |
494 | 526 |
495 // Do a simple property-only update if the PARENT_ID field. Use with caution. | 527 // Do a simple property-only update if the PARENT_ID field. Use with caution. |
496 // | 528 // |
497 // The normal Put(IS_PARENT) call will move the item to the front of the | 529 // The normal Put(IS_PARENT) call will move the item to the front of the |
498 // sibling order to maintain the linked list invariants when the parent | 530 // sibling order to maintain the linked list invariants when the parent |
499 // changes. That's usually what you want to do, but it's inappropriate | 531 // changes. That's usually what you want to do, but it's inappropriate |
500 // when the caller is trying to change the parent ID of a the whole set | 532 // when the caller is trying to change the parent ID of a the whole set |
501 // of children (e.g. because the ID changed during a commit). For those | 533 // of children (e.g. because the ID changed during a commit). For those |
502 // cases, there's this function. It will corrupt the sibling ordering | 534 // cases, there's this function. It will corrupt the sibling ordering |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 | 1238 |
1207 // Only the original fields are filled in until |RecordMutations()|. | 1239 // Only the original fields are filled in until |RecordMutations()|. |
1208 // We use a mutation map instead of a kernel set to avoid copying. | 1240 // We use a mutation map instead of a kernel set to avoid copying. |
1209 EntryKernelMutationMap mutations_; | 1241 EntryKernelMutationMap mutations_; |
1210 | 1242 |
1211 DISALLOW_COPY_AND_ASSIGN(WriteTransaction); | 1243 DISALLOW_COPY_AND_ASSIGN(WriteTransaction); |
1212 }; | 1244 }; |
1213 | 1245 |
1214 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid); | 1246 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid); |
1215 | 1247 |
1216 int64 Now(); | |
1217 | |
1218 // This function sets only the flags needed to get this entry to sync. | 1248 // This function sets only the flags needed to get this entry to sync. |
1219 void MarkForSyncing(syncable::MutableEntry* e); | 1249 void MarkForSyncing(syncable::MutableEntry* e); |
1220 | 1250 |
1221 // This is not a reset. It just sets the numeric fields which are not | |
1222 // initialized by the constructor to zero. | |
1223 void ZeroFields(EntryKernel* entry, int first_field); | |
1224 | |
1225 } // namespace syncable | 1251 } // namespace syncable |
1226 | 1252 |
1227 std::ostream& operator <<(std::ostream&, const syncable::Blob&); | 1253 std::ostream& operator <<(std::ostream&, const syncable::Blob&); |
1228 | 1254 |
1229 #endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ | 1255 #endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ |
OLD | NEW |