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 "components/dom_distiller/core/distilled_content_store.h"
7 #include "base/thread_task_runner_handle.h"
9 namespace dom_distiller
{
11 InMemoryContentStore::InMemoryContentStore(const int max_num_entries
)
12 : cache_(max_num_entries
, CacheDeletor(this)) {
15 InMemoryContentStore::~InMemoryContentStore() {
16 // Clear the cache before destruction to ensure the CacheDeletor is not called
17 // after InMemoryContentStore has been destroyed.
21 void InMemoryContentStore::SaveContent(
22 const ArticleEntry
& entry
,
23 const DistilledArticleProto
& proto
,
24 InMemoryContentStore::SaveCallback callback
) {
25 InjectContent(entry
, proto
);
26 if (!callback
.is_null()) {
27 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
28 base::Bind(callback
, true));
32 void InMemoryContentStore::LoadContent(
33 const ArticleEntry
& entry
,
34 InMemoryContentStore::LoadCallback callback
) {
35 if (callback
.is_null())
38 ContentMap::const_iterator it
= cache_
.Get(entry
.entry_id());
39 bool success
= it
!= cache_
.end();
41 // Could not find article by entry ID, so try looking it up by URL.
42 for (int i
= 0; i
< entry
.pages_size(); ++i
) {
43 UrlMap::const_iterator url_it
= url_to_id_
.find(entry
.pages(i
).url());
44 if (url_it
!= url_to_id_
.end()) {
45 it
= cache_
.Get(url_it
->second
);
46 success
= it
!= cache_
.end();
53 scoped_ptr
<DistilledArticleProto
> distilled_article
;
55 distilled_article
.reset(new DistilledArticleProto(it
->second
));
57 distilled_article
.reset(new DistilledArticleProto());
59 base::ThreadTaskRunnerHandle::Get()->PostTask(
61 base::Bind(callback
, success
, base::Passed(&distilled_article
)));
64 void InMemoryContentStore::InjectContent(const ArticleEntry
& entry
,
65 const DistilledArticleProto
& proto
) {
66 cache_
.Put(entry
.entry_id(), proto
);
67 AddUrlToIdMapping(entry
, proto
);
70 void InMemoryContentStore::AddUrlToIdMapping(
71 const ArticleEntry
& entry
,
72 const DistilledArticleProto
& proto
) {
73 for (int i
= 0; i
< proto
.pages_size(); i
++) {
74 const DistilledPageProto
& page
= proto
.pages(i
);
76 url_to_id_
[page
.url()] = entry
.entry_id();
81 void InMemoryContentStore::EraseUrlToIdMapping(
82 const DistilledArticleProto
& proto
) {
83 for (int i
= 0; i
< proto
.pages_size(); i
++) {
84 const DistilledPageProto
& page
= proto
.pages(i
);
86 url_to_id_
.erase(page
.url());
91 InMemoryContentStore::CacheDeletor::CacheDeletor(InMemoryContentStore
* store
)
95 InMemoryContentStore::CacheDeletor::~CacheDeletor() {
98 void InMemoryContentStore::CacheDeletor::operator()(
99 const DistilledArticleProto
& proto
) {
100 // When InMemoryContentStore is deleted, the |store_| pointer becomes invalid,
101 // but since the ContentMap is cleared in the InMemoryContentStore destructor,
102 // this should never be called after the destructor.
103 store_
->EraseUrlToIdMapping(proto
);
106 } // namespace dom_distiller