OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <bitset> | 9 #include <bitset> |
10 #include <iosfwd> | 10 #include <iosfwd> |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 BIT_FIELDS_END | 125 BIT_FIELDS_END |
126 }; | 126 }; |
127 | 127 |
128 enum { | 128 enum { |
129 BIT_FIELDS_COUNT = BIT_FIELDS_END - BIT_FIELDS_BEGIN, | 129 BIT_FIELDS_COUNT = BIT_FIELDS_END - BIT_FIELDS_BEGIN, |
130 STRING_FIELDS_BEGIN = BIT_FIELDS_END | 130 STRING_FIELDS_BEGIN = BIT_FIELDS_END |
131 }; | 131 }; |
132 | 132 |
133 enum StringField { | 133 enum StringField { |
134 // The name, transformed so as to be suitable for use as a path-element. It | 134 // Name, will be truncated by server. Can be duplicated in a folder. |
135 // is unique, and legal for this client. | 135 NON_UNIQUE_NAME = STRING_FIELDS_BEGIN, |
136 NAME = STRING_FIELDS_BEGIN, | 136 // The server version of |NON_UNIQUE_NAME|. |
137 // The local name, pre-sanitization. It is not necessarily unique. If this | |
138 // is empty, it means |NAME| did not require sanitization. | |
139 UNSANITIZED_NAME, | |
140 // If NAME/UNSANITIZED_NAME are "Foo (2)", then NON_UNIQUE_NAME may be "Foo". | |
141 NON_UNIQUE_NAME, | |
142 // The server version of |NAME|. It is uniquified, but not necessarily | |
143 // OS-legal. | |
144 SERVER_NAME, | |
145 // The server version of |NON_UNIQUE_NAME|. Again, if SERVER_NAME is | |
146 // like "Foo (2)" due to a commit-time name aside, SERVER_NON_UNIQUE_NAME | |
147 // may hold the value "Foo". | |
148 SERVER_NON_UNIQUE_NAME, | 137 SERVER_NON_UNIQUE_NAME, |
149 // For bookmark entries, the URL of the bookmark. | 138 // For bookmark entries, the URL of the bookmark. |
150 BOOKMARK_URL, | 139 BOOKMARK_URL, |
151 SERVER_BOOKMARK_URL, | 140 SERVER_BOOKMARK_URL, |
152 | 141 |
153 // A tag string which identifies this node as a particular top-level | 142 // A tag string which identifies this node as a particular top-level |
154 // permanent object. The tag can be thought of as a unique key that | 143 // permanent object. The tag can be thought of as a unique key that |
155 // identifies a singleton instance. | 144 // identifies a singleton instance. |
156 SINGLETON_TAG, | 145 SINGLETON_TAG, |
157 STRING_FIELDS_END, | 146 STRING_FIELDS_END, |
(...skipping 21 matching lines...) Expand all Loading... |
179 enum { | 168 enum { |
180 FIELD_COUNT = BLOB_FIELDS_END, | 169 FIELD_COUNT = BLOB_FIELDS_END, |
181 // Past this point we have temporaries, stored in memory only. | 170 // Past this point we have temporaries, stored in memory only. |
182 BEGIN_TEMPS = BLOB_FIELDS_END, | 171 BEGIN_TEMPS = BLOB_FIELDS_END, |
183 BIT_TEMPS_BEGIN = BEGIN_TEMPS, | 172 BIT_TEMPS_BEGIN = BEGIN_TEMPS, |
184 }; | 173 }; |
185 | 174 |
186 enum BitTemp { | 175 enum BitTemp { |
187 SYNCING = BIT_TEMPS_BEGIN, | 176 SYNCING = BIT_TEMPS_BEGIN, |
188 IS_NEW, // Means use INSERT instead of UPDATE to save to db. | 177 IS_NEW, // Means use INSERT instead of UPDATE to save to db. |
189 DEPRECATED_DELETE_ON_CLOSE, // Set by redirector, IS_OPEN must also be set. | |
190 DEPRECATED_CHANGED_SINCE_LAST_OPEN, // Have we been written to since we've | |
191 // been opened. | |
192 BIT_TEMPS_END, | 178 BIT_TEMPS_END, |
193 }; | 179 }; |
194 | 180 |
195 enum { | 181 enum { |
196 BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN | 182 BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN |
197 }; | 183 }; |
198 | 184 |
199 class BaseTransaction; | 185 class BaseTransaction; |
200 class WriteTransaction; | 186 class WriteTransaction; |
201 class ReadTransaction; | 187 class ReadTransaction; |
(...skipping 14 matching lines...) Expand all Loading... |
216 }; | 202 }; |
217 | 203 |
218 enum GetByTag { | 204 enum GetByTag { |
219 GET_BY_TAG | 205 GET_BY_TAG |
220 }; | 206 }; |
221 | 207 |
222 enum GetByHandle { | 208 enum GetByHandle { |
223 GET_BY_HANDLE | 209 GET_BY_HANDLE |
224 }; | 210 }; |
225 | 211 |
226 enum GetByPath { | |
227 GET_BY_PATH | |
228 }; | |
229 | |
230 enum GetByParentIdAndName { | |
231 GET_BY_PARENTID_AND_NAME | |
232 }; | |
233 | |
234 // DBName is the name stored in the database. | |
235 enum GetByParentIdAndDBName { | |
236 GET_BY_PARENTID_AND_DBNAME | |
237 }; | |
238 | |
239 enum Create { | 212 enum Create { |
240 CREATE | 213 CREATE |
241 }; | 214 }; |
242 | 215 |
243 enum CreateNewUpdateItem { | 216 enum CreateNewUpdateItem { |
244 CREATE_NEW_UPDATE_ITEM | 217 CREATE_NEW_UPDATE_ITEM |
245 }; | 218 }; |
246 | 219 |
247 typedef std::set<PathString> AttributeKeySet; | 220 typedef std::set<PathString> AttributeKeySet; |
248 | 221 |
249 // DBName is a PathString with additional transformation methods that are | |
250 // useful when trying to derive a unique and legal database name from an | |
251 // unsanitized sync name. | |
252 class DBName : public PathString { | |
253 public: | |
254 explicit DBName(const PathString& database_name) | |
255 : PathString(database_name) { } | |
256 | |
257 // TODO(ncarter): Remove these codepaths to maintain alternate titles which | |
258 // are OS legal filenames, Chrome doesn't depend on this like some other | |
259 // browsers do. | |
260 void MakeOSLegal() { | |
261 PathString new_value = MakePathComponentOSLegal(*this); | |
262 if (!new_value.empty()) | |
263 swap(new_value); | |
264 } | |
265 | |
266 // Modify the value of this DBName so that it is not in use by any entry | |
267 // inside |parent_id|, except maybe |e|. |e| may be NULL if you are trying | |
268 // to compute a name for an entry which has yet to be created. | |
269 void MakeNoncollidingForEntry(BaseTransaction* trans, | |
270 const Id& parent_id, | |
271 Entry* e); | |
272 }; | |
273 | |
274 // SyncName encapsulates a canonical server name. In general, when we need to | |
275 // muck around with a name that the server sends us (e.g. to make it OS legal), | |
276 // we try to preserve the original value in a SyncName, | |
277 // and distill the new local value into a DBName. | |
278 // At other times, we need to apply transforms in the | |
279 // other direction -- that is, to create a server-appropriate SyncName from a | |
280 // user-updated DBName (which is an OS legal name, but not necessarily in the | |
281 // format that the server wants it to be). For that sort of thing, you should | |
282 // initialize a SyncName from the DB name value, and use the methods of | |
283 // SyncName to canonicalize it. At other times, you have a pair of canonical | |
284 // server values -- one (the "value") which is unique in the parent, and another | |
285 // (the "non unique value") which is not unique in the parent -- and you | |
286 // simply want to create a SyncName to hold them as a pair. | |
287 class SyncName { | |
288 public: | |
289 // Create a SyncName with the initially specified value. | |
290 explicit SyncName(const PathString& sync_name) | |
291 : value_(sync_name), non_unique_value_(sync_name) { } | |
292 | |
293 // Create a SyncName by specifying a value and a non-unique value. If | |
294 // you use this constructor, the values you provide should already be | |
295 // acceptable server names. Don't use the mutation/sanitization methods | |
296 // on the resulting instance -- mutation won't work if you have distinct | |
297 // values for the unique and non-unique fields. | |
298 SyncName(const PathString& unique_sync_name, | |
299 const PathString& non_unique_sync_name) | |
300 : value_(unique_sync_name), non_unique_value_(non_unique_sync_name) { } | |
301 | |
302 // Transform |value_| so that it's a legal server name. | |
303 void MakeServerLegal() { | |
304 DCHECK_EQ(value_, non_unique_value_) | |
305 << "Deriving value_ will overwrite non_unique_value_."; | |
306 // Append a trailing space if the value is one of the server's three | |
307 // forbidden special cases. | |
308 if (value_.empty() || | |
309 value_ == PSTR(".") || | |
310 value_ == PSTR("..")) { | |
311 value_.append(PSTR(" ")); | |
312 non_unique_value_ = value_; | |
313 } | |
314 // TODO(ncarter): Handle server's other requirement: truncation to 256 | |
315 // bytes in Unicode NFC. | |
316 } | |
317 | |
318 const PathString& value() const { return value_; } | |
319 PathString& value() { return value_; } | |
320 const PathString& non_unique_value() const { return non_unique_value_; } | |
321 PathString& non_unique_value() { return non_unique_value_; } | |
322 void set_non_unique_value(const PathString& value) { | |
323 non_unique_value_ = value; | |
324 } | |
325 | |
326 inline bool operator==(const SyncName& right_hand_side) const { | |
327 return value_ == right_hand_side.value_ && | |
328 non_unique_value_ == right_hand_side.non_unique_value_; | |
329 } | |
330 inline bool operator!=(const SyncName& right_hand_side) const { | |
331 return !(*this == right_hand_side); | |
332 } | |
333 private: | |
334 PathString value_; | |
335 PathString non_unique_value_; | |
336 }; | |
337 | |
338 // Name is a SyncName which has an additional DBName that provides a way to | |
339 // interpolate the "unsanitized name" according to the syncable convention. | |
340 // | |
341 // A method might accept a Name as an parameter when the sync and database | |
342 // names need to be set simultaneously: | |
343 // | |
344 // void PutName(const Name& new_name) { | |
345 // Put(NAME, new_name.db_value()); | |
346 // Put(UNSANITIZED_NAME, new_name.GetUnsanitizedName()); | |
347 // } | |
348 // | |
349 // A code point that is trying to convert between local database names and | |
350 // server sync names can use Name to help with the conversion: | |
351 // | |
352 // SyncName server_name = entry->GetServerName(); | |
353 // Name name = Name::FromSyncName(server_name); // Initially, name.value() | |
354 // // and name.db_value() are | |
355 // // equal to | |
356 // // server_name.value(). | |
357 // name.db_value().MakeOSLegal(); // Updates name.db_value in-place, | |
358 // // leaving name.value() unchanged. | |
359 // foo->PutName(name); | |
360 // | |
361 class Name : public SyncName { | |
362 public: | |
363 // Create a Name with an initially specified db_value and value. | |
364 Name(const PathString& db_name, const PathString& sync_name) | |
365 : SyncName(sync_name), db_value_(db_name) { } | |
366 | |
367 // Create a Name by specifying the db name, sync name, and non-unique | |
368 // sync name values. | |
369 Name(const PathString& db_name, const PathString& sync_name, | |
370 const PathString& non_unique_sync_name) | |
371 : SyncName(sync_name, non_unique_sync_name), db_value_(db_name) { } | |
372 | |
373 // Create a Name with all name values initially equal to the the single | |
374 // specified argument. | |
375 explicit Name(const PathString& sync_and_db_name) | |
376 : SyncName(sync_and_db_name), db_value_(sync_and_db_name) { } | |
377 | |
378 // Create a Name using the local (non-SERVER) fields of an EntryKernel. | |
379 static Name FromEntryKernel(struct EntryKernel*); | |
380 | |
381 // Create a Name from a SyncName. db_value is initially sync_name.value(). | |
382 // non_unique_value() and value() are copied from |sync_name|. | |
383 static Name FromSyncName(const SyncName& sync_name) { | |
384 return Name(sync_name.value(), sync_name.value(), | |
385 sync_name.non_unique_value()); | |
386 } | |
387 | |
388 static Name FromDBNameAndSyncName(const PathString& db_name, | |
389 const SyncName& sync_name) { | |
390 return Name(db_name, sync_name.value(), sync_name.non_unique_value()); | |
391 } | |
392 | |
393 // Get the database name. The non-const version is useful for in-place | |
394 // mutation. | |
395 const DBName& db_value() const { return db_value_; } | |
396 DBName& db_value() { return db_value_; } | |
397 | |
398 // Do the sync names and database names differ? This indicates that | |
399 // the sync name has been sanitized, and that GetUnsanitizedName() will | |
400 // be non-empty. | |
401 bool HasBeenSanitized() const { return db_value_ != value(); } | |
402 | |
403 // Compute the value of the unsanitized name from the current sync and db | |
404 // name values. The unsanitized name is the sync name value, unless the sync | |
405 // name is the same as the db name value, in which case the unsanitized name | |
406 // is empty. | |
407 PathString GetUnsanitizedName() const { | |
408 return HasBeenSanitized() ? value() : PathString(); | |
409 } | |
410 | |
411 inline bool operator==(const Name& right_hand_side) const { | |
412 return this->SyncName::operator==(right_hand_side) && | |
413 db_value_ == right_hand_side.db_value_; | |
414 } | |
415 inline bool operator!=(const Name& right_hand_side) const { | |
416 return !(*this == right_hand_side); | |
417 } | |
418 | |
419 private: | |
420 // The database name, which is maintained to be a legal and unique-in-parent | |
421 // name. | |
422 DBName db_value_; | |
423 }; | |
424 | |
425 // Why the singular enums? So the code compile-time dispatches instead of | 222 // Why the singular enums? So the code compile-time dispatches instead of |
426 // runtime dispatches as it would with a single enum and an if() statement. | 223 // runtime dispatches as it would with a single enum and an if() statement. |
427 | 224 |
428 // The EntryKernel class contains the actual data for an entry. It | 225 // The EntryKernel class contains the actual data for an entry. It |
429 // would be a private class, except the number of required friend | 226 // would be a private class, except the number of required friend |
430 // declarations would bloat the code. | 227 // declarations would bloat the code. |
431 struct EntryKernel { | 228 struct EntryKernel { |
432 protected: | 229 protected: |
433 PathString string_fields[STRING_FIELDS_COUNT]; | 230 PathString string_fields[STRING_FIELDS_COUNT]; |
434 Blob blob_fields[BLOB_FIELDS_COUNT]; | 231 Blob blob_fields[BLOB_FIELDS_COUNT]; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 class Entry { | 305 class Entry { |
509 friend class Directory; | 306 friend class Directory; |
510 friend std::ostream& ::operator << (std::ostream& s, const Entry& e); | 307 friend std::ostream& ::operator << (std::ostream& s, const Entry& e); |
511 | 308 |
512 public: | 309 public: |
513 // After constructing, you must check good() to test whether the Get | 310 // After constructing, you must check good() to test whether the Get |
514 // succeeded. | 311 // succeeded. |
515 Entry(BaseTransaction* trans, GetByHandle, int64 handle); | 312 Entry(BaseTransaction* trans, GetByHandle, int64 handle); |
516 Entry(BaseTransaction* trans, GetById, const Id& id); | 313 Entry(BaseTransaction* trans, GetById, const Id& id); |
517 Entry(BaseTransaction* trans, GetByTag, const PathString& tag); | 314 Entry(BaseTransaction* trans, GetByTag, const PathString& tag); |
518 Entry(BaseTransaction* trans, GetByPath, const PathString& path); | |
519 Entry(BaseTransaction* trans, GetByParentIdAndName, const Id& id, | |
520 const PathString& name); | |
521 Entry(BaseTransaction* trans, GetByParentIdAndDBName, const Id& id, | |
522 const PathString& name); | |
523 | 315 |
524 bool good() const { return 0 != kernel_; } | 316 bool good() const { return 0 != kernel_; } |
525 | 317 |
526 BaseTransaction* trans() const { return basetrans_; } | 318 BaseTransaction* trans() const { return basetrans_; } |
527 | 319 |
528 // Field accessors. | 320 // Field accessors. |
529 inline int64 Get(MetahandleField field) const { | 321 inline int64 Get(MetahandleField field) const { |
530 DCHECK(kernel_); | 322 DCHECK(kernel_); |
531 return kernel_->ref(field); | 323 return kernel_->ref(field); |
532 } | 324 } |
(...skipping 23 matching lines...) Expand all Loading... |
556 } | 348 } |
557 PathString Get(StringField field) const; | 349 PathString Get(StringField field) const; |
558 inline Blob Get(BlobField field) const { | 350 inline Blob Get(BlobField field) const { |
559 DCHECK(kernel_); | 351 DCHECK(kernel_); |
560 return kernel_->ref(field); | 352 return kernel_->ref(field); |
561 } | 353 } |
562 inline bool Get(BitTemp field) const { | 354 inline bool Get(BitTemp field) const { |
563 DCHECK(kernel_); | 355 DCHECK(kernel_); |
564 return kernel_->ref(field); | 356 return kernel_->ref(field); |
565 } | 357 } |
566 inline Name GetName() const { | 358 |
| 359 inline bool ExistsOnClientBecauseNameIsNonEmpty() const { |
567 DCHECK(kernel_); | 360 DCHECK(kernel_); |
568 return Name::FromEntryKernel(kernel_); | 361 return !kernel_->ref(NON_UNIQUE_NAME).empty(); |
569 } | 362 } |
570 inline SyncName GetServerName() const { | 363 |
571 DCHECK(kernel_); | |
572 return SyncName(kernel_->ref(SERVER_NAME), | |
573 kernel_->ref(SERVER_NON_UNIQUE_NAME)); | |
574 } | |
575 inline bool SyncNameMatchesServerName() const { | |
576 DCHECK(kernel_); | |
577 SyncName sync_name(GetName()); | |
578 return sync_name == GetServerName(); | |
579 } | |
580 inline PathString GetSyncNameValue() const { | |
581 DCHECK(kernel_); | |
582 // This should always be equal to GetName().sync_name().value(), but may be | |
583 // faster. | |
584 return kernel_->ref(UNSANITIZED_NAME).empty() ? kernel_->ref(NAME) : | |
585 kernel_->ref(UNSANITIZED_NAME); | |
586 } | |
587 inline bool ExistsOnClientBecauseDatabaseNameIsNonEmpty() const { | |
588 DCHECK(kernel_); | |
589 return !kernel_->ref(NAME).empty(); | |
590 } | |
591 inline bool IsRoot() const { | 364 inline bool IsRoot() const { |
592 DCHECK(kernel_); | 365 DCHECK(kernel_); |
593 return kernel_->ref(ID).IsRoot(); | 366 return kernel_->ref(ID).IsRoot(); |
594 } | 367 } |
595 | 368 |
596 void GetAllExtendedAttributes(BaseTransaction* trans, | 369 void GetAllExtendedAttributes(BaseTransaction* trans, |
597 std::set<ExtendedAttribute>* result); | 370 std::set<ExtendedAttribute>* result); |
598 void GetExtendedAttributesList(BaseTransaction* trans, | 371 void GetExtendedAttributesList(BaseTransaction* trans, |
599 AttributeKeySet* result); | 372 AttributeKeySet* result); |
600 // Flags all extended attributes for deletion on the next SaveChanges. | 373 // Flags all extended attributes for deletion on the next SaveChanges. |
(...skipping 27 matching lines...) Expand all Loading... |
628 friend class WriteTransaction; | 401 friend class WriteTransaction; |
629 friend class Directory; | 402 friend class Directory; |
630 void Init(WriteTransaction* trans, const Id& parent_id, | 403 void Init(WriteTransaction* trans, const Id& parent_id, |
631 const PathString& name); | 404 const PathString& name); |
632 public: | 405 public: |
633 MutableEntry(WriteTransaction* trans, Create, const Id& parent_id, | 406 MutableEntry(WriteTransaction* trans, Create, const Id& parent_id, |
634 const PathString& name); | 407 const PathString& name); |
635 MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, const Id& id); | 408 MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, const Id& id); |
636 MutableEntry(WriteTransaction* trans, GetByHandle, int64); | 409 MutableEntry(WriteTransaction* trans, GetByHandle, int64); |
637 MutableEntry(WriteTransaction* trans, GetById, const Id&); | 410 MutableEntry(WriteTransaction* trans, GetById, const Id&); |
638 MutableEntry(WriteTransaction* trans, GetByPath, const PathString& path); | |
639 MutableEntry(WriteTransaction* trans, GetByParentIdAndName, const Id&, | |
640 const PathString& name); | |
641 MutableEntry(WriteTransaction* trans, GetByParentIdAndDBName, | |
642 const Id& parentid, const PathString& name); | |
643 | 411 |
644 inline WriteTransaction* write_transaction() const { | 412 inline WriteTransaction* write_transaction() const { |
645 return write_transaction_; | 413 return write_transaction_; |
646 } | 414 } |
647 | 415 |
648 // Field Accessors. Some of them trigger the re-indexing of the entry. | 416 // Field Accessors. Some of them trigger the re-indexing of the entry. |
649 // Return true on success, return false on failure, which means | 417 // Return true on success, return false on failure, which means |
650 // that putting the value would have caused a duplicate in the index. | 418 // that putting the value would have caused a duplicate in the index. |
| 419 // TODO(chron): Remove some of these unecessary return values. |
651 bool Put(Int64Field field, const int64& value); | 420 bool Put(Int64Field field, const int64& value); |
652 bool Put(IdField field, const Id& value); | 421 bool Put(IdField field, const Id& value); |
653 bool Put(StringField field, const PathString& value); | 422 bool Put(StringField field, const PathString& value); |
654 bool Put(BaseVersion field, int64 value); | 423 bool Put(BaseVersion field, int64 value); |
655 inline bool PutName(const Name& name) { | 424 |
656 return (Put(NAME, name.db_value()) && | |
657 Put(UNSANITIZED_NAME, name.GetUnsanitizedName()) && | |
658 Put(NON_UNIQUE_NAME, name.non_unique_value())); | |
659 } | |
660 inline bool PutServerName(const SyncName& server_name) { | |
661 return (Put(SERVER_NAME, server_name.value()) && | |
662 Put(SERVER_NON_UNIQUE_NAME, server_name.non_unique_value())); | |
663 } | |
664 inline bool Put(BlobField field, const Blob& value) { | 425 inline bool Put(BlobField field, const Blob& value) { |
665 return PutField(field, value); | 426 return PutField(field, value); |
666 } | 427 } |
667 inline bool Put(BitField field, bool value) { | 428 inline bool Put(BitField field, bool value) { |
668 return PutField(field, value); | 429 return PutField(field, value); |
669 } | 430 } |
670 inline bool Put(IsDelField field, bool value) { | 431 inline bool Put(IsDelField field, bool value) { |
671 return PutIsDel(value); | 432 return PutIsDel(value); |
672 } | 433 } |
673 bool Put(IndexedBitField field, bool value); | 434 bool Put(IndexedBitField field, bool value); |
674 | 435 |
675 // Avoids temporary collision in index when renaming a bookmark into another | |
676 // folder. | |
677 bool PutParentIdAndName(const Id& parent_id, const Name& name); | |
678 | |
679 // Sets the position of this item, and updates the entry kernels of the | 436 // Sets the position of this item, and updates the entry kernels of the |
680 // adjacent siblings so that list invariants are maintained. Returns false | 437 // adjacent siblings so that list invariants are maintained. Returns false |
681 // and fails if |predecessor_id| does not identify a sibling. Pass the root | 438 // and fails if |predecessor_id| does not identify a sibling. Pass the root |
682 // ID to put the node in first position. | 439 // ID to put the node in first position. |
683 bool PutPredecessor(const Id& predecessor_id); | 440 bool PutPredecessor(const Id& predecessor_id); |
684 | 441 |
685 inline bool Put(BitTemp field, bool value) { | 442 inline bool Put(BitTemp field, bool value) { |
686 return PutTemp(field, value); | 443 return PutTemp(field, value); |
687 } | 444 } |
688 | 445 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 protected: | 482 protected: |
726 MutableEntry(); | 483 MutableEntry(); |
727 | 484 |
728 DISALLOW_COPY_AND_ASSIGN(MutableEntry); | 485 DISALLOW_COPY_AND_ASSIGN(MutableEntry); |
729 }; | 486 }; |
730 | 487 |
731 template <Int64Field field_index> | 488 template <Int64Field field_index> |
732 class SameField; | 489 class SameField; |
733 template <Int64Field field_index> | 490 template <Int64Field field_index> |
734 class HashField; | 491 class HashField; |
735 class LessParentIdAndNames; | 492 class LessParentIdAndHandle; |
736 class LessMultiIncusionTargetAndMetahandle; | 493 class LessMultiIncusionTargetAndMetahandle; |
737 template <typename FieldType, FieldType field_index> | 494 template <typename FieldType, FieldType field_index> |
738 class LessField; | 495 class LessField; |
739 class LessEntryMetaHandles { | 496 class LessEntryMetaHandles { |
740 public: | 497 public: |
741 inline bool operator()(const syncable::EntryKernel& a, | 498 inline bool operator()(const syncable::EntryKernel& a, |
742 const syncable::EntryKernel& b) const { | 499 const syncable::EntryKernel& b) const { |
743 return a.ref(META_HANDLE) < b.ref(META_HANDLE); | 500 return a.ref(META_HANDLE) < b.ref(META_HANDLE); |
744 } | 501 } |
745 }; | 502 }; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 // (Account) Store birthday is opaque to the client, | 672 // (Account) Store birthday is opaque to the client, |
916 // so we keep it in the format it is in the proto buffer | 673 // so we keep it in the format it is in the proto buffer |
917 // in case we switch to a binary birthday later. | 674 // in case we switch to a binary birthday later. |
918 std::string store_birthday() const; | 675 std::string store_birthday() const; |
919 void set_store_birthday(std::string store_birthday); | 676 void set_store_birthday(std::string store_birthday); |
920 | 677 |
921 // Unique to each account / client pair. | 678 // Unique to each account / client pair. |
922 std::string cache_guid() const; | 679 std::string cache_guid() const; |
923 | 680 |
924 protected: // for friends, mainly used by Entry constructors | 681 protected: // for friends, mainly used by Entry constructors |
925 EntryKernel* GetChildWithName(const Id& parent_id, const PathString& name); | |
926 EntryKernel* GetChildWithDBName(const Id& parent_id, const PathString& name); | |
927 EntryKernel* GetEntryByHandle(const int64 handle); | 682 EntryKernel* GetEntryByHandle(const int64 handle); |
928 EntryKernel* GetEntryByHandle(const int64 metahandle, ScopedKernelLock* lock); | 683 EntryKernel* GetEntryByHandle(const int64 metahandle, ScopedKernelLock* lock); |
929 EntryKernel* GetEntryById(const Id& id); | 684 EntryKernel* GetEntryById(const Id& id); |
930 EntryKernel* GetEntryByTag(const PathString& tag); | 685 EntryKernel* GetEntryByTag(const PathString& tag); |
931 EntryKernel* GetRootEntry(); | 686 EntryKernel* GetRootEntry(); |
932 EntryKernel* GetEntryByPath(const PathString& path); | |
933 bool ReindexId(EntryKernel* const entry, const Id& new_id); | 687 bool ReindexId(EntryKernel* const entry, const Id& new_id); |
934 bool ReindexParentIdAndName(EntryKernel* const entry, const Id& new_parent_id, | 688 void ReindexParentId(EntryKernel* const entry, const Id& new_parent_id); |
935 const PathString& new_name); | 689 |
936 // These don't do the semantic checking that the redirector needs. | 690 // These don't do semantic checking. |
937 // The semantic checking is implemented higher up. | 691 // The semantic checking is implemented higher up. |
938 bool Undelete(EntryKernel* const entry); | 692 void Undelete(EntryKernel* const entry); |
939 bool Delete(EntryKernel* const entry); | 693 void Delete(EntryKernel* const entry); |
940 | 694 |
941 // Overridden by tests. | 695 // Overridden by tests. |
942 virtual DirectoryBackingStore* CreateBackingStore( | 696 virtual DirectoryBackingStore* CreateBackingStore( |
943 const PathString& dir_name, | 697 const PathString& dir_name, |
944 const FilePath& backing_filepath); | 698 const FilePath& backing_filepath); |
945 | 699 |
946 private: | 700 private: |
947 // These private versions expect the kernel lock to already be held | 701 // These private versions expect the kernel lock to already be held |
948 // before calling. | 702 // before calling. |
949 EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock); | 703 EntryKernel* GetEntryById(const Id& id, ScopedKernelLock* const lock); |
950 EntryKernel* GetChildWithName(const Id& parent_id, | |
951 const PathString& name, | |
952 ScopedKernelLock* const lock); | |
953 EntryKernel* GetChildWithNameImpl(const Id& parent_id, | |
954 const PathString& name, | |
955 ScopedKernelLock* const lock); | |
956 | 704 |
957 DirOpenResult OpenImpl(const FilePath& file_path, const PathString& name); | 705 DirOpenResult OpenImpl(const FilePath& file_path, const PathString& name); |
958 | 706 |
959 struct DirectoryEventTraits { | 707 struct DirectoryEventTraits { |
960 typedef DirectoryEvent EventType; | 708 typedef DirectoryEvent EventType; |
961 static inline bool IsChannelShutdownEvent(const DirectoryEvent& event) { | 709 static inline bool IsChannelShutdownEvent(const DirectoryEvent& event) { |
962 return DIRECTORY_DESTROYED == event; | 710 return DIRECTORY_DESTROYED == event; |
963 } | 711 } |
964 }; | 712 }; |
965 public: | 713 public: |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 // TODO(sync): If lookups and inserts in these sets become | 822 // TODO(sync): If lookups and inserts in these sets become |
1075 // the bottle-neck, then we can use hash-sets instead. But | 823 // the bottle-neck, then we can use hash-sets instead. But |
1076 // that will require using #ifdefs and compiler-specific code, | 824 // that will require using #ifdefs and compiler-specific code, |
1077 // so use standard sets for now. | 825 // so use standard sets for now. |
1078 public: | 826 public: |
1079 typedef std::set<EntryKernel*, LessField<MetahandleField, META_HANDLE> > | 827 typedef std::set<EntryKernel*, LessField<MetahandleField, META_HANDLE> > |
1080 MetahandlesIndex; | 828 MetahandlesIndex; |
1081 typedef std::set<EntryKernel*, LessField<IdField, ID> > IdsIndex; | 829 typedef std::set<EntryKernel*, LessField<IdField, ID> > IdsIndex; |
1082 // All entries in memory must be in both the MetahandlesIndex and | 830 // All entries in memory must be in both the MetahandlesIndex and |
1083 // the IdsIndex, but only non-deleted entries will be the | 831 // the IdsIndex, but only non-deleted entries will be the |
1084 // ParentIdAndNamesIndex, because there can be multiple deleted | 832 // ParentIdChildIndex. |
1085 // entries with the same parent id and name. | 833 // This index contains EntryKernels ordered by parent ID and metahandle. |
1086 typedef std::set<EntryKernel*, LessParentIdAndNames> ParentIdAndNamesIndex; | 834 // It allows efficient lookup of the children of a given parent. |
| 835 typedef std::set<EntryKernel*, LessParentIdAndHandle> ParentIdChildIndex; |
1087 typedef std::vector<int64> MetahandlesToPurge; | 836 typedef std::vector<int64> MetahandlesToPurge; |
1088 | 837 |
1089 private: | 838 private: |
1090 | 839 |
1091 struct Kernel { | 840 struct Kernel { |
1092 Kernel(const FilePath& db_path, const PathString& name, | 841 Kernel(const FilePath& db_path, const PathString& name, |
1093 const KernelLoadInfo& info); | 842 const KernelLoadInfo& info); |
1094 | 843 |
1095 ~Kernel(); | 844 ~Kernel(); |
1096 | 845 |
(...skipping 12 matching lines...) Expand all Loading... |
1109 // Protects all members below. | 858 // Protects all members below. |
1110 // The mutex effectively protects all the indices, but not the | 859 // The mutex effectively protects all the indices, but not the |
1111 // entries themselves. So once a pointer to an entry is pulled | 860 // entries themselves. So once a pointer to an entry is pulled |
1112 // from the index, the mutex can be unlocked and entry read or written. | 861 // from the index, the mutex can be unlocked and entry read or written. |
1113 // | 862 // |
1114 // Never hold the mutex and do anything with the database or any | 863 // Never hold the mutex and do anything with the database or any |
1115 // other buffered IO. Violating this rule will result in deadlock. | 864 // other buffered IO. Violating this rule will result in deadlock. |
1116 Lock mutex; | 865 Lock mutex; |
1117 MetahandlesIndex* metahandles_index; // Entries indexed by metahandle | 866 MetahandlesIndex* metahandles_index; // Entries indexed by metahandle |
1118 IdsIndex* ids_index; // Entries indexed by id | 867 IdsIndex* ids_index; // Entries indexed by id |
1119 ParentIdAndNamesIndex* parent_id_and_names_index; | 868 ParentIdChildIndex* parent_id_child_index; |
1120 // So we don't have to create an EntryKernel every time we want to | 869 // So we don't have to create an EntryKernel every time we want to |
1121 // look something up in an index. Needle in haystack metaphore. | 870 // look something up in an index. Needle in haystack metaphore. |
1122 EntryKernel needle; | 871 EntryKernel needle; |
1123 ExtendedAttributes* const extended_attributes; | 872 ExtendedAttributes* const extended_attributes; |
1124 | 873 |
1125 // 2 in-memory indices on bits used extremely frequently by the syncer. | 874 // 2 in-memory indices on bits used extremely frequently by the syncer. |
1126 MetahandleSet* const unapplied_update_metahandles; | 875 MetahandleSet* const unapplied_update_metahandles; |
1127 MetahandleSet* const unsynced_metahandles; | 876 MetahandleSet* const unsynced_metahandles; |
1128 // TODO(timsteele): Add a dirty_metahandles index as we now may want to | 877 // TODO(timsteele): Add a dirty_metahandles index as we now may want to |
1129 // optimize the SaveChanges work of scanning all entries to find dirty ones | 878 // optimize the SaveChanges work of scanning all entries to find dirty ones |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 class ScopedKernelLock { | 921 class ScopedKernelLock { |
1173 public: | 922 public: |
1174 explicit ScopedKernelLock(const Directory*); | 923 explicit ScopedKernelLock(const Directory*); |
1175 ~ScopedKernelLock() {} | 924 ~ScopedKernelLock() {} |
1176 | 925 |
1177 AutoLock scoped_lock_; | 926 AutoLock scoped_lock_; |
1178 Directory* const dir_; | 927 Directory* const dir_; |
1179 DISALLOW_COPY_AND_ASSIGN(ScopedKernelLock); | 928 DISALLOW_COPY_AND_ASSIGN(ScopedKernelLock); |
1180 }; | 929 }; |
1181 | 930 |
1182 // Transactions are now processed FIFO (+overlapping reads). | 931 // Transactions are now processed FIFO with a straight lock |
1183 class BaseTransaction { | 932 class BaseTransaction { |
1184 friend class Entry; | 933 friend class Entry; |
1185 public: | 934 public: |
1186 inline Directory* directory() const { return directory_; } | 935 inline Directory* directory() const { return directory_; } |
1187 inline Id root_id() const { return Id(); } | 936 inline Id root_id() const { return Id(); } |
1188 | 937 |
1189 protected: | 938 protected: |
1190 BaseTransaction(Directory* directory, const char* name, | 939 BaseTransaction(Directory* directory, const char* name, |
1191 const char* source_file, int line, WriterTag writer); | 940 const char* source_file, int line, WriterTag writer); |
1192 | 941 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 | 996 |
1248 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid); | 997 bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid); |
1249 int ComparePathNames(const PathString& a, const PathString& b); | 998 int ComparePathNames(const PathString& a, const PathString& b); |
1250 | 999 |
1251 // Exposed in header as this is used as a sqlite3 callback. | 1000 // Exposed in header as this is used as a sqlite3 callback. |
1252 int ComparePathNames16(void*, int a_bytes, const void* a, int b_bytes, | 1001 int ComparePathNames16(void*, int a_bytes, const void* a, int b_bytes, |
1253 const void* b); | 1002 const void* b); |
1254 | 1003 |
1255 int64 Now(); | 1004 int64 Now(); |
1256 | 1005 |
1257 // Does wildcard processing. | |
1258 BOOL PathNameMatch(const PathString& pathname, const PathString& pathspec); | |
1259 | |
1260 class ExtendedAttribute { | 1006 class ExtendedAttribute { |
1261 public: | 1007 public: |
1262 ExtendedAttribute(BaseTransaction* trans, GetByHandle, | 1008 ExtendedAttribute(BaseTransaction* trans, GetByHandle, |
1263 const ExtendedAttributeKey& key); | 1009 const ExtendedAttributeKey& key); |
1264 int64 metahandle() const { return i_->first.metahandle; } | 1010 int64 metahandle() const { return i_->first.metahandle; } |
1265 const PathString& key() const { return i_->first.key; } | 1011 const PathString& key() const { return i_->first.key; } |
1266 const Blob& value() const { return i_->second.value; } | 1012 const Blob& value() const { return i_->second.value; } |
1267 bool is_deleted() const { return i_->second.is_deleted; } | 1013 bool is_deleted() const { return i_->second.is_deleted; } |
1268 bool good() const { return good_; } | 1014 bool good() const { return good_; } |
1269 bool operator < (const ExtendedAttribute& x) const { | 1015 bool operator < (const ExtendedAttribute& x) const { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 void ZeroFields(EntryKernel* entry, int first_field); | 1059 void ZeroFields(EntryKernel* entry, int first_field); |
1314 | 1060 |
1315 } // namespace syncable | 1061 } // namespace syncable |
1316 | 1062 |
1317 std::ostream& operator <<(std::ostream&, const syncable::Blob&); | 1063 std::ostream& operator <<(std::ostream&, const syncable::Blob&); |
1318 | 1064 |
1319 browser_sync::FastDump& operator << | 1065 browser_sync::FastDump& operator << |
1320 (browser_sync::FastDump&, const syncable::Blob&); | 1066 (browser_sync::FastDump&, const syncable::Blob&); |
1321 | 1067 |
1322 #endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ | 1068 #endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_H_ |
OLD | NEW |