Automated Commit: Committing new LKGM version 6953.0.0 for chromeos.
[chromium-blink-merge.git] / sync / syncable / entry_kernel.h
blob3e0d2c7a65d926f1528e3bf6f16c044a4f930b1b
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef SYNC_SYNCABLE_ENTRY_KERNEL_H_
6 #define SYNC_SYNCABLE_ENTRY_KERNEL_H_
8 #include <set>
10 #include "base/time/time.h"
11 #include "base/values.h"
12 #include "sync/base/sync_export.h"
13 #include "sync/internal_api/public/base/model_type.h"
14 #include "sync/internal_api/public/base/unique_position.h"
15 #include "sync/internal_api/public/util/immutable.h"
16 #include "sync/protocol/attachments.pb.h"
17 #include "sync/protocol/sync.pb.h"
18 #include "sync/syncable/metahandle_set.h"
19 #include "sync/syncable/syncable_id.h"
20 #include "sync/util/time.h"
22 namespace syncer {
24 class Cryptographer;
26 namespace syncable {
28 // Things you need to update if you change any of the fields below:
29 // - EntryKernel struct in this file
30 // - syncable_columns.h
31 // - syncable_enum_conversions{.h,.cc,_unittest.cc}
32 // - EntryKernel::EntryKernel(), EntryKernel::ToValue() in entry_kernel.cc
33 // - operator<< in Entry.cc
34 // - BindFields() and UnpackEntry() in directory_backing_store.cc
35 // - kCurrentDBVersion, DirectoryBackingStore::InitializeTables in
36 // directory_backing_store.cc
37 // - TestSimpleFieldsPreservedDuringSaveChanges in syncable_unittest.cc
39 static const int64 kInvalidMetaHandle = 0;
41 enum {
42 BEGIN_FIELDS = 0,
43 INT64_FIELDS_BEGIN = BEGIN_FIELDS
46 enum MetahandleField {
47 // Primary key into the table. Keep this as a handle to the meta entry
48 // across transactions.
49 META_HANDLE = INT64_FIELDS_BEGIN
52 enum BaseVersion {
53 // After initial upload, the version is controlled by the server, and is
54 // increased whenever the data or metadata changes on the server.
55 BASE_VERSION = META_HANDLE + 1,
58 enum Int64Field {
59 SERVER_VERSION = BASE_VERSION + 1,
60 LOCAL_EXTERNAL_ID, // ID of an item in the external local storage that this
61 // entry is associated with. (such as bookmarks.js)
62 TRANSACTION_VERSION,
63 INT64_FIELDS_END
66 enum {
67 INT64_FIELDS_COUNT = INT64_FIELDS_END - INT64_FIELDS_BEGIN,
68 TIME_FIELDS_BEGIN = INT64_FIELDS_END,
71 enum TimeField {
72 MTIME = TIME_FIELDS_BEGIN,
73 SERVER_MTIME,
74 CTIME,
75 SERVER_CTIME,
76 TIME_FIELDS_END,
79 enum {
80 TIME_FIELDS_COUNT = TIME_FIELDS_END - TIME_FIELDS_BEGIN,
81 ID_FIELDS_BEGIN = TIME_FIELDS_END,
84 enum IdField {
85 // Code in InitializeTables relies on ID being the first IdField value.
86 ID = ID_FIELDS_BEGIN,
87 PARENT_ID,
88 SERVER_PARENT_ID,
89 ID_FIELDS_END
92 enum {
93 ID_FIELDS_COUNT = ID_FIELDS_END - ID_FIELDS_BEGIN,
94 BIT_FIELDS_BEGIN = ID_FIELDS_END
97 enum IndexedBitField {
98 IS_UNSYNCED = BIT_FIELDS_BEGIN,
99 IS_UNAPPLIED_UPDATE,
100 INDEXED_BIT_FIELDS_END,
103 enum IsDelField {
104 IS_DEL = INDEXED_BIT_FIELDS_END,
107 enum BitField {
108 IS_DIR = IS_DEL + 1,
109 SERVER_IS_DIR,
110 SERVER_IS_DEL,
111 BIT_FIELDS_END
114 enum {
115 BIT_FIELDS_COUNT = BIT_FIELDS_END - BIT_FIELDS_BEGIN,
116 STRING_FIELDS_BEGIN = BIT_FIELDS_END
119 enum StringField {
120 // Name, will be truncated by server. Can be duplicated in a folder.
121 NON_UNIQUE_NAME = STRING_FIELDS_BEGIN,
122 // The server version of |NON_UNIQUE_NAME|.
123 SERVER_NON_UNIQUE_NAME,
125 // A tag string which identifies this node as a particular top-level
126 // permanent object. The tag can be thought of as a unique key that
127 // identifies a singleton instance.
128 UNIQUE_SERVER_TAG, // Tagged by the server
129 UNIQUE_CLIENT_TAG, // Tagged by the client
130 UNIQUE_BOOKMARK_TAG, // Client tags for bookmark items
131 STRING_FIELDS_END,
134 enum {
135 STRING_FIELDS_COUNT = STRING_FIELDS_END - STRING_FIELDS_BEGIN,
136 PROTO_FIELDS_BEGIN = STRING_FIELDS_END
139 // From looking at the sqlite3 docs, it's not directly stated, but it
140 // seems the overhead for storing a NULL blob is very small.
141 enum ProtoField {
142 SPECIFICS = PROTO_FIELDS_BEGIN,
143 SERVER_SPECIFICS,
144 BASE_SERVER_SPECIFICS,
145 PROTO_FIELDS_END,
148 enum {
149 PROTO_FIELDS_COUNT = PROTO_FIELDS_END - PROTO_FIELDS_BEGIN,
150 UNIQUE_POSITION_FIELDS_BEGIN = PROTO_FIELDS_END
153 enum UniquePositionField {
154 SERVER_UNIQUE_POSITION = UNIQUE_POSITION_FIELDS_BEGIN,
155 UNIQUE_POSITION,
156 UNIQUE_POSITION_FIELDS_END
159 enum {
160 UNIQUE_POSITION_FIELDS_COUNT =
161 UNIQUE_POSITION_FIELDS_END - UNIQUE_POSITION_FIELDS_BEGIN,
162 ATTACHMENT_METADATA_FIELDS_BEGIN = UNIQUE_POSITION_FIELDS_END
165 enum AttachmentMetadataField {
166 ATTACHMENT_METADATA = ATTACHMENT_METADATA_FIELDS_BEGIN,
167 SERVER_ATTACHMENT_METADATA,
168 ATTACHMENT_METADATA_FIELDS_END
171 enum {
172 ATTACHMENT_METADATA_FIELDS_COUNT =
173 ATTACHMENT_METADATA_FIELDS_END - ATTACHMENT_METADATA_FIELDS_BEGIN,
174 FIELD_COUNT = ATTACHMENT_METADATA_FIELDS_END - BEGIN_FIELDS,
175 // Past this point we have temporaries, stored in memory only.
176 BEGIN_TEMPS = ATTACHMENT_METADATA_FIELDS_END,
177 BIT_TEMPS_BEGIN = BEGIN_TEMPS,
180 enum BitTemp {
181 // Whether a server commit operation was started and has not yet completed
182 // for this entity.
183 SYNCING = BIT_TEMPS_BEGIN,
184 // Whether a local change was made to an entity that had SYNCING set to true,
185 // and was therefore in the middle of a commit operation.
186 // Note: must only be set if SYNCING is true.
187 DIRTY_SYNC,
188 BIT_TEMPS_END,
191 enum {
192 BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN
197 struct SYNC_EXPORT_PRIVATE EntryKernel {
198 private:
199 std::string string_fields[STRING_FIELDS_COUNT];
200 sync_pb::EntitySpecifics specifics_fields[PROTO_FIELDS_COUNT];
201 int64 int64_fields[INT64_FIELDS_COUNT];
202 base::Time time_fields[TIME_FIELDS_COUNT];
203 Id id_fields[ID_FIELDS_COUNT];
204 UniquePosition unique_position_fields[UNIQUE_POSITION_FIELDS_COUNT];
205 sync_pb::AttachmentMetadata
206 attachment_metadata_fields[ATTACHMENT_METADATA_FIELDS_COUNT];
207 std::bitset<BIT_FIELDS_COUNT> bit_fields;
208 std::bitset<BIT_TEMPS_COUNT> bit_temps;
210 public:
211 EntryKernel();
212 ~EntryKernel();
214 // Set the dirty bit, and optionally add this entry's metahandle to
215 // a provided index on dirty bits in |dirty_index|. Parameter may be null,
216 // and will result only in setting the dirty bit of this entry.
217 inline void mark_dirty(syncable::MetahandleSet* dirty_index) {
218 if (!dirty_ && dirty_index) {
219 DCHECK_NE(0, ref(META_HANDLE));
220 dirty_index->insert(ref(META_HANDLE));
222 dirty_ = true;
225 // Clear the dirty bit, and optionally remove this entry's metahandle from
226 // a provided index on dirty bits in |dirty_index|. Parameter may be null,
227 // and will result only in clearing dirty bit of this entry.
228 inline void clear_dirty(syncable::MetahandleSet* dirty_index) {
229 if (dirty_ && dirty_index) {
230 DCHECK_NE(0, ref(META_HANDLE));
231 dirty_index->erase(ref(META_HANDLE));
233 dirty_ = false;
236 inline bool is_dirty() const {
237 return dirty_;
240 // Setters.
241 inline void put(MetahandleField field, int64 value) {
242 int64_fields[field - INT64_FIELDS_BEGIN] = value;
244 inline void put(Int64Field field, int64 value) {
245 int64_fields[field - INT64_FIELDS_BEGIN] = value;
247 inline void put(TimeField field, const base::Time& value) {
248 // Round-trip to proto time format and back so that we have
249 // consistent time resolutions (ms).
250 time_fields[field - TIME_FIELDS_BEGIN] =
251 ProtoTimeToTime(TimeToProtoTime(value));
253 inline void put(IdField field, const Id& value) {
254 id_fields[field - ID_FIELDS_BEGIN] = value;
256 inline void put(BaseVersion field, int64 value) {
257 int64_fields[field - INT64_FIELDS_BEGIN] = value;
259 inline void put(IndexedBitField field, bool value) {
260 bit_fields[field - BIT_FIELDS_BEGIN] = value;
262 inline void put(IsDelField field, bool value) {
263 bit_fields[field - BIT_FIELDS_BEGIN] = value;
265 inline void put(BitField field, bool value) {
266 bit_fields[field - BIT_FIELDS_BEGIN] = value;
268 inline void put(StringField field, const std::string& value) {
269 string_fields[field - STRING_FIELDS_BEGIN] = value;
271 inline void put(ProtoField field, const sync_pb::EntitySpecifics& value) {
272 specifics_fields[field - PROTO_FIELDS_BEGIN].CopyFrom(value);
274 inline void put(UniquePositionField field, const UniquePosition& value) {
275 unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN] = value;
277 inline void put(AttachmentMetadataField field,
278 const sync_pb::AttachmentMetadata& value) {
279 attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN] =
280 value;
282 inline void put(BitTemp field, bool value) {
283 bit_temps[field - BIT_TEMPS_BEGIN] = value;
286 // Const ref getters.
287 inline int64 ref(MetahandleField field) const {
288 return int64_fields[field - INT64_FIELDS_BEGIN];
290 inline int64 ref(Int64Field field) const {
291 return int64_fields[field - INT64_FIELDS_BEGIN];
293 inline const base::Time& ref(TimeField field) const {
294 return time_fields[field - TIME_FIELDS_BEGIN];
296 inline const Id& ref(IdField field) const {
297 return id_fields[field - ID_FIELDS_BEGIN];
299 inline int64 ref(BaseVersion field) const {
300 return int64_fields[field - INT64_FIELDS_BEGIN];
302 inline bool ref(IndexedBitField field) const {
303 return bit_fields[field - BIT_FIELDS_BEGIN];
305 inline bool ref(IsDelField field) const {
306 return bit_fields[field - BIT_FIELDS_BEGIN];
308 inline bool ref(BitField field) const {
309 return bit_fields[field - BIT_FIELDS_BEGIN];
311 inline const std::string& ref(StringField field) const {
312 return string_fields[field - STRING_FIELDS_BEGIN];
314 inline const sync_pb::EntitySpecifics& ref(ProtoField field) const {
315 return specifics_fields[field - PROTO_FIELDS_BEGIN];
317 inline const UniquePosition& ref(UniquePositionField field) const {
318 return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
320 inline const sync_pb::AttachmentMetadata& ref(
321 AttachmentMetadataField field) const {
322 return attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN];
324 inline bool ref(BitTemp field) const {
325 return bit_temps[field - BIT_TEMPS_BEGIN];
328 // Non-const, mutable ref getters for object types only.
329 inline std::string& mutable_ref(StringField field) {
330 return string_fields[field - STRING_FIELDS_BEGIN];
332 inline sync_pb::EntitySpecifics& mutable_ref(ProtoField field) {
333 return specifics_fields[field - PROTO_FIELDS_BEGIN];
335 inline Id& mutable_ref(IdField field) {
336 return id_fields[field - ID_FIELDS_BEGIN];
338 inline UniquePosition& mutable_ref(UniquePositionField field) {
339 return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
341 inline sync_pb::AttachmentMetadata& mutable_ref(
342 AttachmentMetadataField field) {
343 return attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN];
346 ModelType GetModelType() const;
347 ModelType GetServerModelType() const;
348 bool ShouldMaintainPosition() const;
349 bool ShouldMaintainHierarchy() const;
351 // Dumps all kernel info into a DictionaryValue and returns it.
352 // Transfers ownership of the DictionaryValue to the caller.
353 // Note: |cryptographer| is an optional parameter for use in decrypting
354 // encrypted specifics. If it is NULL or the specifics are not decryptsble,
355 // they will be serialized as empty proto's.
356 base::DictionaryValue* ToValue(Cryptographer* cryptographer) const;
358 private:
359 // Tracks whether this entry needs to be saved to the database.
360 bool dirty_;
363 class EntryKernelLessByMetaHandle {
364 public:
365 inline bool operator()(const EntryKernel* a,
366 const EntryKernel* b) const {
367 return a->ref(META_HANDLE) < b->ref(META_HANDLE);
371 typedef std::set<const EntryKernel*, EntryKernelLessByMetaHandle>
372 EntryKernelSet;
374 struct EntryKernelMutation {
375 EntryKernel original, mutated;
378 typedef std::map<int64, EntryKernelMutation> EntryKernelMutationMap;
380 typedef Immutable<EntryKernelMutationMap> ImmutableEntryKernelMutationMap;
382 // Caller owns the return value.
383 base::DictionaryValue* EntryKernelMutationToValue(
384 const EntryKernelMutation& mutation);
386 // Caller owns the return value.
387 base::ListValue* EntryKernelMutationMapToValue(
388 const EntryKernelMutationMap& mutations);
390 } // namespace syncable
391 } // namespace syncer
393 #endif // SYNC_SYNCABLE_ENTRY_KERNEL_H_