Remove linux_chromium_gn_dbg from the chromium CQ.
[chromium-blink-merge.git] / sync / syncable / entry_kernel.h
blobc1fc5e548a145278d63e064bdbd0c7d04f459b8a
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/syncable/metahandle_set.h"
17 #include "sync/syncable/proto_value_ptr.h"
18 #include "sync/syncable/syncable_id.h"
19 #include "sync/util/time.h"
21 namespace syncer {
23 class Cryptographer;
25 namespace syncable {
27 // Things you need to update if you change any of the fields below:
28 // - EntryKernel struct in this file
29 // - syncable_columns.h
30 // - syncable_enum_conversions{.h,.cc,_unittest.cc}
31 // - EntryKernel::EntryKernel(), EntryKernel::ToValue() in entry_kernel.cc
32 // - operator<< in Entry.cc
33 // - BindFields() and UnpackEntry() in directory_backing_store.cc
34 // - kCurrentDBVersion, DirectoryBackingStore::InitializeTables in
35 // directory_backing_store.cc
36 // - TestSimpleFieldsPreservedDuringSaveChanges in syncable_unittest.cc
38 static const int64 kInvalidMetaHandle = 0;
40 enum {
41 BEGIN_FIELDS = 0,
42 INT64_FIELDS_BEGIN = BEGIN_FIELDS
45 enum MetahandleField {
46 // Primary key into the table. Keep this as a handle to the meta entry
47 // across transactions.
48 META_HANDLE = INT64_FIELDS_BEGIN
51 enum BaseVersion {
52 // After initial upload, the version is controlled by the server, and is
53 // increased whenever the data or metadata changes on the server.
54 BASE_VERSION = META_HANDLE + 1,
57 enum Int64Field {
58 SERVER_VERSION = BASE_VERSION + 1,
59 LOCAL_EXTERNAL_ID, // ID of an item in the external local storage that this
60 // entry is associated with. (such as bookmarks.js)
61 TRANSACTION_VERSION,
62 INT64_FIELDS_END
65 enum {
66 INT64_FIELDS_COUNT = INT64_FIELDS_END - INT64_FIELDS_BEGIN,
67 TIME_FIELDS_BEGIN = INT64_FIELDS_END,
70 enum TimeField {
71 MTIME = TIME_FIELDS_BEGIN,
72 SERVER_MTIME,
73 CTIME,
74 SERVER_CTIME,
75 TIME_FIELDS_END,
78 enum {
79 TIME_FIELDS_COUNT = TIME_FIELDS_END - TIME_FIELDS_BEGIN,
80 ID_FIELDS_BEGIN = TIME_FIELDS_END,
83 enum IdField {
84 // Code in InitializeTables relies on ID being the first IdField value.
85 ID = ID_FIELDS_BEGIN,
86 PARENT_ID,
87 SERVER_PARENT_ID,
88 ID_FIELDS_END
91 enum {
92 ID_FIELDS_COUNT = ID_FIELDS_END - ID_FIELDS_BEGIN,
93 BIT_FIELDS_BEGIN = ID_FIELDS_END
96 enum IndexedBitField {
97 IS_UNSYNCED = BIT_FIELDS_BEGIN,
98 IS_UNAPPLIED_UPDATE,
99 INDEXED_BIT_FIELDS_END,
102 enum IsDelField {
103 IS_DEL = INDEXED_BIT_FIELDS_END,
106 enum BitField {
107 IS_DIR = IS_DEL + 1,
108 SERVER_IS_DIR,
109 SERVER_IS_DEL,
110 BIT_FIELDS_END
113 enum {
114 BIT_FIELDS_COUNT = BIT_FIELDS_END - BIT_FIELDS_BEGIN,
115 STRING_FIELDS_BEGIN = BIT_FIELDS_END
118 enum StringField {
119 // Name, will be truncated by server. Can be duplicated in a folder.
120 NON_UNIQUE_NAME = STRING_FIELDS_BEGIN,
121 // The server version of |NON_UNIQUE_NAME|.
122 SERVER_NON_UNIQUE_NAME,
124 // A tag string which identifies this node as a particular top-level
125 // permanent object. The tag can be thought of as a unique key that
126 // identifies a singleton instance.
127 UNIQUE_SERVER_TAG, // Tagged by the server
128 UNIQUE_CLIENT_TAG, // Tagged by the client
129 UNIQUE_BOOKMARK_TAG, // Client tags for bookmark items
130 STRING_FIELDS_END,
133 enum {
134 STRING_FIELDS_COUNT = STRING_FIELDS_END - STRING_FIELDS_BEGIN,
135 PROTO_FIELDS_BEGIN = STRING_FIELDS_END
138 // From looking at the sqlite3 docs, it's not directly stated, but it
139 // seems the overhead for storing a NULL blob is very small.
140 enum ProtoField {
141 SPECIFICS = PROTO_FIELDS_BEGIN,
142 SERVER_SPECIFICS,
143 BASE_SERVER_SPECIFICS,
144 PROTO_FIELDS_END,
147 enum {
148 PROTO_FIELDS_COUNT = PROTO_FIELDS_END - PROTO_FIELDS_BEGIN,
149 UNIQUE_POSITION_FIELDS_BEGIN = PROTO_FIELDS_END
152 enum UniquePositionField {
153 SERVER_UNIQUE_POSITION = UNIQUE_POSITION_FIELDS_BEGIN,
154 UNIQUE_POSITION,
155 UNIQUE_POSITION_FIELDS_END
158 enum {
159 UNIQUE_POSITION_FIELDS_COUNT =
160 UNIQUE_POSITION_FIELDS_END - UNIQUE_POSITION_FIELDS_BEGIN,
161 ATTACHMENT_METADATA_FIELDS_BEGIN = UNIQUE_POSITION_FIELDS_END
164 enum AttachmentMetadataField {
165 ATTACHMENT_METADATA = ATTACHMENT_METADATA_FIELDS_BEGIN,
166 SERVER_ATTACHMENT_METADATA,
167 ATTACHMENT_METADATA_FIELDS_END
170 enum {
171 ATTACHMENT_METADATA_FIELDS_COUNT =
172 ATTACHMENT_METADATA_FIELDS_END - ATTACHMENT_METADATA_FIELDS_BEGIN,
173 FIELD_COUNT = ATTACHMENT_METADATA_FIELDS_END - BEGIN_FIELDS,
174 // Past this point we have temporaries, stored in memory only.
175 BEGIN_TEMPS = ATTACHMENT_METADATA_FIELDS_END,
176 BIT_TEMPS_BEGIN = BEGIN_TEMPS,
179 enum BitTemp {
180 // Whether a server commit operation was started and has not yet completed
181 // for this entity.
182 SYNCING = BIT_TEMPS_BEGIN,
183 // Whether a local change was made to an entity that had SYNCING set to true,
184 // and was therefore in the middle of a commit operation.
185 // Note: must only be set if SYNCING is true.
186 DIRTY_SYNC,
187 BIT_TEMPS_END,
190 enum {
191 BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN
194 struct SYNC_EXPORT_PRIVATE EntryKernel {
195 private:
196 std::string string_fields[STRING_FIELDS_COUNT];
197 EntitySpecificsPtr specifics_fields[PROTO_FIELDS_COUNT];
198 int64 int64_fields[INT64_FIELDS_COUNT];
199 base::Time time_fields[TIME_FIELDS_COUNT];
200 Id id_fields[ID_FIELDS_COUNT];
201 UniquePosition unique_position_fields[UNIQUE_POSITION_FIELDS_COUNT];
202 AttachmentMetadataPtr
203 attachment_metadata_fields[ATTACHMENT_METADATA_FIELDS_COUNT];
204 std::bitset<BIT_FIELDS_COUNT> bit_fields;
205 std::bitset<BIT_TEMPS_COUNT> bit_temps;
207 friend std::ostream& operator<<(std::ostream& s, const EntryKernel& e);
209 public:
210 EntryKernel();
211 ~EntryKernel();
213 // Set the dirty bit, and optionally add this entry's metahandle to
214 // a provided index on dirty bits in |dirty_index|. Parameter may be null,
215 // and will result only in setting the dirty bit of this entry.
216 inline void mark_dirty(syncable::MetahandleSet* dirty_index) {
217 if (!dirty_ && dirty_index) {
218 DCHECK_NE(0, ref(META_HANDLE));
219 dirty_index->insert(ref(META_HANDLE));
221 dirty_ = true;
224 // Clear the dirty bit, and optionally remove this entry's metahandle from
225 // a provided index on dirty bits in |dirty_index|. Parameter may be null,
226 // and will result only in clearing dirty bit of this entry.
227 inline void clear_dirty(syncable::MetahandleSet* dirty_index) {
228 if (dirty_ && dirty_index) {
229 DCHECK_NE(0, ref(META_HANDLE));
230 dirty_index->erase(ref(META_HANDLE));
232 dirty_ = false;
235 inline bool is_dirty() const {
236 return dirty_;
239 // Setters.
240 inline void put(MetahandleField field, int64 value) {
241 int64_fields[field - INT64_FIELDS_BEGIN] = value;
243 inline void put(Int64Field field, int64 value) {
244 int64_fields[field - INT64_FIELDS_BEGIN] = value;
246 inline void put(TimeField field, const base::Time& value) {
247 // Round-trip to proto time format and back so that we have
248 // consistent time resolutions (ms).
249 time_fields[field - TIME_FIELDS_BEGIN] =
250 ProtoTimeToTime(TimeToProtoTime(value));
252 inline void put(IdField field, const Id& value) {
253 id_fields[field - ID_FIELDS_BEGIN] = value;
255 inline void put(BaseVersion field, int64 value) {
256 int64_fields[field - INT64_FIELDS_BEGIN] = value;
258 inline void put(IndexedBitField field, bool value) {
259 bit_fields[field - BIT_FIELDS_BEGIN] = value;
261 inline void put(IsDelField field, bool value) {
262 bit_fields[field - BIT_FIELDS_BEGIN] = value;
264 inline void put(BitField field, bool value) {
265 bit_fields[field - BIT_FIELDS_BEGIN] = value;
267 inline void put(StringField field, const std::string& value) {
268 string_fields[field - STRING_FIELDS_BEGIN] = value;
270 inline void put(ProtoField field, const sync_pb::EntitySpecifics& value) {
271 specifics_fields[field - PROTO_FIELDS_BEGIN].set_value(value);
273 inline void put(UniquePositionField field, const UniquePosition& value) {
274 unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN] = value;
276 inline void put(AttachmentMetadataField field,
277 const sync_pb::AttachmentMetadata& value) {
278 attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN]
279 .set_value(value);
281 inline void put(BitTemp field, bool value) {
282 bit_temps[field - BIT_TEMPS_BEGIN] = value;
285 // Const ref getters.
286 inline int64 ref(MetahandleField field) const {
287 return int64_fields[field - INT64_FIELDS_BEGIN];
289 inline int64 ref(Int64Field field) const {
290 return int64_fields[field - INT64_FIELDS_BEGIN];
292 inline const base::Time& ref(TimeField field) const {
293 return time_fields[field - TIME_FIELDS_BEGIN];
295 inline const Id& ref(IdField field) const {
296 return id_fields[field - ID_FIELDS_BEGIN];
298 inline int64 ref(BaseVersion field) const {
299 return int64_fields[field - INT64_FIELDS_BEGIN];
301 inline bool ref(IndexedBitField field) const {
302 return bit_fields[field - BIT_FIELDS_BEGIN];
304 inline bool ref(IsDelField field) const {
305 return bit_fields[field - BIT_FIELDS_BEGIN];
307 inline bool ref(BitField field) const {
308 return bit_fields[field - BIT_FIELDS_BEGIN];
310 inline const std::string& ref(StringField field) const {
311 return string_fields[field - STRING_FIELDS_BEGIN];
313 inline const sync_pb::EntitySpecifics& ref(ProtoField field) const {
314 return specifics_fields[field - PROTO_FIELDS_BEGIN].value();
316 inline const UniquePosition& ref(UniquePositionField field) const {
317 return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
319 inline const sync_pb::AttachmentMetadata& ref(
320 AttachmentMetadataField field) const {
321 return attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN]
322 .value();
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 Id& mutable_ref(IdField field) {
333 return id_fields[field - ID_FIELDS_BEGIN];
335 inline UniquePosition& mutable_ref(UniquePositionField field) {
336 return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN];
339 // Deserialization methods for ::google::protobuf::MessageLite derived types.
340 inline void load(ProtoField field, const void* blob, int length) {
341 specifics_fields[field - PROTO_FIELDS_BEGIN].load(blob, length);
344 inline void load(AttachmentMetadataField field,
345 const void* blob,
346 int length) {
347 attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN].load(
348 blob, length);
351 // Sharing data methods for ::google::protobuf::MessageLite derived types.
352 inline void copy(ProtoField src, ProtoField dest) {
353 DCHECK_NE(src, dest);
354 specifics_fields[dest - PROTO_FIELDS_BEGIN] =
355 specifics_fields[src - PROTO_FIELDS_BEGIN];
358 inline void copy(AttachmentMetadataField src, AttachmentMetadataField dest) {
359 DCHECK_NE(src, dest);
360 attachment_metadata_fields[dest - ATTACHMENT_METADATA_FIELDS_BEGIN] =
361 attachment_metadata_fields[src - ATTACHMENT_METADATA_FIELDS_BEGIN];
364 ModelType GetModelType() const;
365 ModelType GetServerModelType() const;
366 bool ShouldMaintainPosition() const;
367 bool ShouldMaintainHierarchy() const;
369 // Dumps all kernel info into a DictionaryValue and returns it.
370 // Transfers ownership of the DictionaryValue to the caller.
371 // Note: |cryptographer| is an optional parameter for use in decrypting
372 // encrypted specifics. If it is NULL or the specifics are not decryptsble,
373 // they will be serialized as empty proto's.
374 base::DictionaryValue* ToValue(Cryptographer* cryptographer) const;
376 private:
377 // Tracks whether this entry needs to be saved to the database.
378 bool dirty_;
381 class EntryKernelLessByMetaHandle {
382 public:
383 inline bool operator()(const EntryKernel* a,
384 const EntryKernel* b) const {
385 return a->ref(META_HANDLE) < b->ref(META_HANDLE);
389 typedef std::set<const EntryKernel*, EntryKernelLessByMetaHandle>
390 EntryKernelSet;
392 struct EntryKernelMutation {
393 EntryKernel original, mutated;
396 typedef std::map<int64, EntryKernelMutation> EntryKernelMutationMap;
398 typedef Immutable<EntryKernelMutationMap> ImmutableEntryKernelMutationMap;
400 // Caller owns the return value.
401 base::DictionaryValue* EntryKernelMutationToValue(
402 const EntryKernelMutation& mutation);
404 // Caller owns the return value.
405 base::ListValue* EntryKernelMutationMapToValue(
406 const EntryKernelMutationMap& mutations);
408 std::ostream& operator<<(std::ostream& os, const EntryKernel& entry_kernel);
410 } // namespace syncable
411 } // namespace syncer
413 #endif // SYNC_SYNCABLE_ENTRY_KERNEL_H_