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.
4
5#ifndef COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_CONTENT_STORE_H_
6#define COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_CONTENT_STORE_H_
7
8#include <string>
9
10#include "base/bind.h"
11#include "base/containers/hash_tables.h"
12#include "base/containers/mru_cache.h"
13#include "components/dom_distiller/core/article_entry.h"
14#include "components/dom_distiller/core/proto/distilled_article.pb.h"
15
16namespace dom_distiller {
17
18// The maximum number of items to keep in the cache before deleting some.
19const int kDefaultMaxNumCachedEntries = 32;
20
21// This is a simple interface for saving and loading of distilled content for an
22// ArticleEntry.
23class DistilledContentStore {
24 public:
25  typedef base::Callback<
26      void(bool /* success */, scoped_ptr<DistilledArticleProto>)> LoadCallback;
27  typedef base::Callback<void(bool /* success */)> SaveCallback;
28
29  virtual void SaveContent(const ArticleEntry& entry,
30                           const DistilledArticleProto& proto,
31                           SaveCallback callback) = 0;
32  virtual void LoadContent(const ArticleEntry& entry,
33                           LoadCallback callback) = 0;
34
35  DistilledContentStore() {};
36  virtual ~DistilledContentStore() {};
37
38 private:
39  DISALLOW_COPY_AND_ASSIGN(DistilledContentStore);
40};
41
42// This content store keeps up to |max_num_entries| of the last accessed items
43// in its cache. Both loading and saving content is counted as access.
44// Lookup can be done based on entry ID or URL.
45class InMemoryContentStore : public DistilledContentStore {
46 public:
47  explicit InMemoryContentStore(const int max_num_entries);
48  virtual ~InMemoryContentStore();
49
50  // DistilledContentStore implementation
51  virtual void SaveContent(const ArticleEntry& entry,
52                           const DistilledArticleProto& proto,
53                           SaveCallback callback) OVERRIDE;
54  virtual void LoadContent(const ArticleEntry& entry,
55                           LoadCallback callback) OVERRIDE;
56
57  // Synchronously saves the content.
58  void InjectContent(const ArticleEntry& entry,
59                     const DistilledArticleProto& proto);
60
61 private:
62  // The CacheDeletor gets called when anything is removed from the ContentMap.
63  class CacheDeletor {
64   public:
65    explicit CacheDeletor(InMemoryContentStore* store);
66    ~CacheDeletor();
67    void operator()(const DistilledArticleProto& proto);
68
69   private:
70    InMemoryContentStore* store_;
71  };
72
73  void AddUrlToIdMapping(const ArticleEntry& entry,
74                         const DistilledArticleProto& proto);
75
76  void EraseUrlToIdMapping(const DistilledArticleProto& proto);
77
78  typedef base::MRUCacheBase<std::string,
79                             DistilledArticleProto,
80                             InMemoryContentStore::CacheDeletor> ContentMap;
81  typedef base::hash_map<std::string, std::string> UrlMap;
82
83  ContentMap cache_;
84  UrlMap url_to_id_;
85};
86
87}  // dom_distiller
88
89#endif  // COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_CONTENT_CACHE_H_
90