summaryrefslogtreecommitdiffstats
path: root/sync/syncable/directory.cc
diff options
context:
space:
mode:
authormaniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-02 19:00:11 +0000
committermaniscalco@chromium.org <maniscalco@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-02 19:00:11 +0000
commit706d41dd9014de4a25e20069d8b607f291874fc1 (patch)
tree324309d4b9f7194d25a77036d7a2b1fa60eac6f4 /sync/syncable/directory.cc
parent92c7f876ef1041d01dc37750420513e19391874c (diff)
downloadchromium_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.cc70
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);