diff options
author | maniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-02 19:00:11 +0000 |
---|---|---|
committer | maniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-02 19:00:11 +0000 |
commit | 706d41dd9014de4a25e20069d8b607f291874fc1 (patch) | |
tree | 324309d4b9f7194d25a77036d7a2b1fa60eac6f4 /sync/syncable/directory.cc | |
parent | 92c7f876ef1041d01dc37750420513e19391874c (diff) | |
download | chromium_src-706d41dd9014de4a25e20069d8b607f291874fc1.zip chromium_src-706d41dd9014de4a25e20069d8b607f291874fc1.tar.gz chromium_src-706d41dd9014de4a25e20069d8b607f291874fc1.tar.bz2 |
Keep track of which attachments are referenced by which sync entries.
Relanding https://codereview.chromium.org/247983002/ after fixing
memory leak.
PutAttachmentMetadata on MutableEntry now notifies the Directory when
the attachments associated with an entry change.
Give Directory::InitializeIndices a ScopedKernelLock to be consistent
and make it easier to ensure we are locking when we need to.
GenericChangeProcess passes new attachments to AttachmentService for
storage and upload.
Add an output parameter to GenericChangeProcessor's HandleActionAdd and
HandleActionUpdate methods so they can keep track of potentially new
attachments and pass them to AttachmentService for storage/upload.
Convert AttachmentService's OnSyncDataAdd to StoreAttachments.
Implement HasAttachmentNotOnServer.
BUG=348625,353303,354530,356266
Review URL: https://codereview.chromium.org/264793007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267887 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/syncable/directory.cc')
-rw-r--r-- | sync/syncable/directory.cc | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/sync/syncable/directory.cc b/sync/syncable/directory.cc index 75c1bec..cebb2d4 100644 --- a/sync/syncable/directory.cc +++ b/sync/syncable/directory.cc @@ -10,6 +10,7 @@ #include "base/debug/trace_event.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" +#include "sync/internal_api/public/base/attachment_id_proto.h" #include "sync/internal_api/public/base/unique_position.h" #include "sync/internal_api/public/util/unrecoverable_error_handler.h" #include "sync/syncable/entry.h" @@ -123,6 +124,7 @@ DirOpenResult Directory::Open( } void Directory::InitializeIndices(MetahandlesMap* handles_map) { + ScopedKernelLock lock(this); kernel_->metahandles_map.swap(*handles_map); for (MetahandlesMap::const_iterator it = kernel_->metahandles_map.begin(); it != kernel_->metahandles_map.end(); ++it) { @@ -152,6 +154,7 @@ void Directory::InitializeIndices(MetahandlesMap* handles_map) { kernel_->ids_map.end()) << "Unexpected duplicate use of ID"; kernel_->ids_map[entry->ref(ID).value()] = entry; DCHECK(!entry->is_dirty()); + AddToAttachmentIndex(metahandle, entry->ref(ATTACHMENT_METADATA), lock); } } @@ -362,6 +365,8 @@ bool Directory::InsertEntry(BaseWriteTransaction* trans, return false; } } + AddToAttachmentIndex( + entry->ref(META_HANDLE), entry->ref(ATTACHMENT_METADATA), *lock); // Should NEVER be created with a client tag or server tag. if (!SyncAssert(entry->ref(UNIQUE_SERVER_TAG).empty(), FROM_HERE, @@ -408,6 +413,51 @@ bool Directory::ReindexParentId(BaseWriteTransaction* trans, return true; } +void Directory::RemoveFromAttachmentIndex( + const int64 metahandle, + const sync_pb::AttachmentMetadata& attachment_metadata, + const ScopedKernelLock& lock) { + for (int i = 0; i < attachment_metadata.record_size(); ++i) { + AttachmentIdUniqueId unique_id = + attachment_metadata.record(i).id().unique_id(); + IndexByAttachmentId::iterator iter = + kernel_->index_by_attachment_id.find(unique_id); + if (iter != kernel_->index_by_attachment_id.end()) { + iter->second.erase(metahandle); + if (iter->second.empty()) { + kernel_->index_by_attachment_id.erase(iter); + } + } + } +} + +void Directory::AddToAttachmentIndex( + const int64 metahandle, + const sync_pb::AttachmentMetadata& attachment_metadata, + const ScopedKernelLock& lock) { + for (int i = 0; i < attachment_metadata.record_size(); ++i) { + AttachmentIdUniqueId unique_id = + attachment_metadata.record(i).id().unique_id(); + IndexByAttachmentId::iterator iter = + kernel_->index_by_attachment_id.find(unique_id); + if (iter == kernel_->index_by_attachment_id.end()) { + iter = kernel_->index_by_attachment_id.insert(std::make_pair( + unique_id, + MetahandleSet())).first; + } + iter->second.insert(metahandle); + } +} + +void Directory::UpdateAttachmentIndex( + const int64 metahandle, + const sync_pb::AttachmentMetadata& old_metadata, + const sync_pb::AttachmentMetadata& new_metadata) { + ScopedKernelLock lock(this); + RemoveFromAttachmentIndex(metahandle, old_metadata, lock); + AddToAttachmentIndex(metahandle, new_metadata, lock); +} + bool Directory::unrecoverable_error_set(const BaseTransaction* trans) const { DCHECK(trans != NULL); return unrecoverable_error_set_; @@ -548,6 +598,9 @@ bool Directory::VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot) { "Deleted entry still present", (&trans))) return false; + RemoveFromAttachmentIndex( + entry->ref(META_HANDLE), entry->ref(ATTACHMENT_METADATA), lock); + delete entry; } if (trans.unrecoverable_error_set()) @@ -607,7 +660,8 @@ void Directory::UnapplyEntry(EntryKernel* entry) { void Directory::DeleteEntry(bool save_to_journal, EntryKernel* entry, - EntryKernelSet* entries_to_journal) { + EntryKernelSet* entries_to_journal, + const ScopedKernelLock& lock) { int64 handle = entry->ref(META_HANDLE); ModelType server_type = GetModelTypeFromSpecifics( entry->ref(SERVER_SPECIFICS)); @@ -637,6 +691,7 @@ void Directory::DeleteEntry(bool save_to_journal, kernel_->server_tags_map.erase(entry->ref(UNIQUE_SERVER_TAG)); DCHECK_EQ(1u, num_erased); } + RemoveFromAttachmentIndex(handle, entry->ref(ATTACHMENT_METADATA), lock); if (save_to_journal) { entries_to_journal->insert(entry); @@ -704,7 +759,7 @@ bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet disabled_types, types_to_journal.Has(server_type)) && (delete_journal_->IsDeleteJournalEnabled(local_type) || delete_journal_->IsDeleteJournalEnabled(server_type)); - DeleteEntry(save_to_journal, entry, &entries_to_journal); + DeleteEntry(save_to_journal, entry, &entries_to_journal, lock); } } @@ -762,6 +817,17 @@ bool Directory::ResetVersionsForType(BaseWriteTransaction* trans, return true; } +bool Directory::IsAttachmentLinked( + const sync_pb::AttachmentIdProto& attachment_id_proto) const { + ScopedKernelLock lock(this); + IndexByAttachmentId::const_iterator iter = + kernel_->index_by_attachment_id.find(attachment_id_proto.unique_id()); + if (iter != kernel_->index_by_attachment_id.end() && !iter->second.empty()) { + return true; + } + return false; +} + void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) { WriteTransaction trans(FROM_HERE, HANDLE_SAVE_FAILURE, this); ScopedKernelLock lock(this); |