1// Copyright 2013 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 CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_H_
6#define CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_H_
7
8#include <utility>
9
10#include "base/basictypes.h"
11#include "base/containers/mru_cache.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/time/time.h"
15#include "chrome/browser/ui/app_list/search/common/dictionary_data_store.h"
16#include "components/keyed_service/core/keyed_service.h"
17
18namespace base {
19class DictionaryValue;
20}
21
22namespace content {
23class BrowserContext;
24}
25
26namespace app_list {
27
28enum ResultStatus {
29  FRESH = 0,
30  STALE = 1
31};
32
33// Pair of values, first indicating whether this is a fresh result or stale,
34// the second holding the actual value.
35typedef std::pair<ResultStatus, const base::DictionaryValue*> CacheResult;
36
37// WebserviceCache manages a cache of search results which should be valid
38// during an input session. This will reduce unnecessary queries for typing
39// backspace or so on. This is not meant to hold cache entries across multiple
40// search sessions.
41class WebserviceCache : public KeyedService,
42                        public base::SupportsWeakPtr<WebserviceCache> {
43 public:
44  enum QueryType {
45    WEBSTORE = 0,
46    PEOPLE = 1
47  };
48
49  explicit WebserviceCache(content::BrowserContext* context);
50  virtual ~WebserviceCache();
51
52  // Checks the current cache and returns the value for the |query| if it's
53  // valid. Otherwise an CacheResult object with the result field set to NULL.
54  // A query consists of a query 'type' and the query itself. The two current
55  // types of queries supported are webstore queries and people search queries.
56  // The type silos the query into it's own separate domain, preventing any
57  // mixing of the queries.
58  const CacheResult Get(QueryType type, const std::string& query);
59
60  // Puts the new result to the query.
61  void Put(QueryType type,
62           const std::string& query,
63           scoped_ptr<base::DictionaryValue> result);
64
65 private:
66  struct Payload {
67    Payload(const base::Time& time,
68            const base::DictionaryValue* result)
69        : time(time), result(result) {}
70    Payload() {}
71
72    base::Time time;
73    const base::DictionaryValue* result;
74  };
75
76  class CacheDeletor {
77   public:
78    void operator()(Payload& payload);
79  };
80  typedef base::MRUCacheBase<std::string, Payload, CacheDeletor> Cache;
81
82  // Callback for when the cache is loaded from the dictionary data store.
83  void OnCacheLoaded(scoped_ptr<base::DictionaryValue>);
84
85  // Populates the payload parameter with the corresponding payload stored
86  // in the given dictionary. If the dictionary is invalid for any reason,
87  // this method will return false.
88  bool PayloadFromDict(const base::DictionaryValue* dict,
89                       Payload* payload);
90
91  // Returns a dictionary value for a given payload. The returned dictionary
92  // will be owned by the data_store_ cached_dict, and freed on the destruction
93  // of our dictionary datastore.
94  base::DictionaryValue* DictFromPayload(const Payload& payload);
95
96  // Trims our MRU cache, making sure that any element that is removed is also
97  // removed from the dictionary data store.
98  void TrimCache();
99
100  // Prepends a type string to the given query and returns a new query string.
101  std::string PrependType(QueryType type, const std::string& query);
102
103  Cache cache_;
104  scoped_refptr<DictionaryDataStore> data_store_;
105
106  bool cache_loaded_;
107
108  DISALLOW_COPY_AND_ASSIGN(WebserviceCache);
109};
110
111}  // namespace app_list
112
113#endif  // CHROME_BROWSER_UI_APP_LIST_SEARCH_COMMON_WEBSERVICE_CACHE_H_
114