1 // Copyright 2014 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 #include "sync/internal_api/public/attachments/in_memory_attachment_store.h"
8 #include "base/callback.h"
9 #include "base/location.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/sequenced_task_runner.h"
17 void AppendMetadata(AttachmentMetadataList
* list
,
18 const Attachment
& attachment
) {
20 AttachmentMetadata(attachment
.GetId(), attachment
.GetData()->size()));
25 InMemoryAttachmentStore::InMemoryAttachmentStore(
26 const scoped_refptr
<base::SequencedTaskRunner
>& callback_task_runner
)
27 : AttachmentStoreBackend(callback_task_runner
) {
28 // Object is created on one thread but used on another.
32 InMemoryAttachmentStore::~InMemoryAttachmentStore() {
35 void InMemoryAttachmentStore::Init(
36 const AttachmentStore::InitCallback
& callback
) {
37 DCHECK(CalledOnValidThread());
38 PostCallback(base::Bind(callback
, AttachmentStore::SUCCESS
));
41 void InMemoryAttachmentStore::Read(
42 const AttachmentIdList
& ids
,
43 const AttachmentStore::ReadCallback
& callback
) {
44 DCHECK(CalledOnValidThread());
45 AttachmentStore::Result result_code
= AttachmentStore::SUCCESS
;
46 scoped_ptr
<AttachmentMap
> result_map(new AttachmentMap
);
47 scoped_ptr
<AttachmentIdList
> unavailable_attachments(new AttachmentIdList
);
49 for (const auto& id
: ids
) {
50 AttachmentEntryMap::iterator attachment_iter
= attachments_
.find(id
);
51 if (attachment_iter
!= attachments_
.end()) {
52 const Attachment
& attachment
= attachment_iter
->second
.attachment
;
53 result_map
->insert(std::make_pair(id
, attachment
));
55 unavailable_attachments
->push_back(id
);
58 if (!unavailable_attachments
->empty()) {
59 result_code
= AttachmentStore::UNSPECIFIED_ERROR
;
61 PostCallback(base::Bind(callback
, result_code
, base::Passed(&result_map
),
62 base::Passed(&unavailable_attachments
)));
65 void InMemoryAttachmentStore::Write(
66 AttachmentStore::Component component
,
67 const AttachmentList
& attachments
,
68 const AttachmentStore::WriteCallback
& callback
) {
69 DCHECK(CalledOnValidThread());
70 for (const auto& attachment
: attachments
) {
71 attachments_
.insert(std::make_pair(attachment
.GetId(),
72 AttachmentEntry(attachment
, component
)));
74 PostCallback(base::Bind(callback
, AttachmentStore::SUCCESS
));
77 void InMemoryAttachmentStore::SetReference(AttachmentStore::Component component
,
78 const AttachmentIdList
& ids
) {
79 DCHECK(CalledOnValidThread());
80 for (const auto& id
: ids
) {
81 AttachmentEntryMap::iterator attachments_iter
= attachments_
.find(id
);
82 if (attachments_iter
!= attachments_
.end()) {
83 attachments_iter
->second
.components
.insert(component
);
88 void InMemoryAttachmentStore::DropReference(
89 AttachmentStore::Component component
,
90 const AttachmentIdList
& ids
,
91 const AttachmentStore::DropCallback
& callback
) {
92 DCHECK(CalledOnValidThread());
93 AttachmentStore::Result result
= AttachmentStore::SUCCESS
;
94 for (const auto& id
: ids
) {
95 AttachmentEntryMap::iterator attachments_iter
= attachments_
.find(id
);
96 if (attachments_iter
== attachments_
.end()) {
99 attachments_iter
->second
.components
.erase(component
);
100 if (attachments_iter
->second
.components
.empty()) {
101 attachments_
.erase(attachments_iter
);
104 PostCallback(base::Bind(callback
, result
));
107 void InMemoryAttachmentStore::ReadMetadata(
108 const AttachmentIdList
& ids
,
109 const AttachmentStore::ReadMetadataCallback
& callback
) {
110 DCHECK(CalledOnValidThread());
111 AttachmentStore::Result result_code
= AttachmentStore::SUCCESS
;
112 scoped_ptr
<AttachmentMetadataList
> metadata_list(
113 new AttachmentMetadataList());
115 for (const auto& id
: ids
) {
116 // TODO(pavely): ReadMetadata should only return attachments with component
117 // reference similarly to ReadAllMetadata behavior.
118 AttachmentEntryMap::iterator attachments_iter
= attachments_
.find(id
);
119 if (attachments_iter
!= attachments_
.end()) {
120 AppendMetadata(metadata_list
.get(), attachments_iter
->second
.attachment
);
122 result_code
= AttachmentStore::UNSPECIFIED_ERROR
;
125 PostCallback(base::Bind(callback
, result_code
, base::Passed(&metadata_list
)));
128 void InMemoryAttachmentStore::ReadAllMetadata(
129 AttachmentStore::Component component
,
130 const AttachmentStore::ReadMetadataCallback
& callback
) {
131 DCHECK(CalledOnValidThread());
132 AttachmentStore::Result result_code
= AttachmentStore::SUCCESS
;
133 scoped_ptr
<AttachmentMetadataList
> metadata_list(
134 new AttachmentMetadataList());
136 for (AttachmentEntryMap::const_iterator iter
= attachments_
.begin();
137 iter
!= attachments_
.end(); ++iter
) {
138 if (iter
->second
.components
.count(component
) > 0) {
139 AppendMetadata(metadata_list
.get(), iter
->second
.attachment
);
142 PostCallback(base::Bind(callback
, result_code
, base::Passed(&metadata_list
)));
145 InMemoryAttachmentStore::AttachmentEntry::AttachmentEntry(
146 const Attachment
& attachment
,
147 AttachmentStore::Component initial_reference_component
)
148 : attachment(attachment
) {
149 components
.insert(initial_reference_component
);
152 InMemoryAttachmentStore::AttachmentEntry::~AttachmentEntry() {
155 } // namespace syncer