simple_index.h revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright (c) 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 NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
6#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
7
8#include <list>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/callback.h"
13#include "base/containers/hash_tables.h"
14#include "base/files/file_path.h"
15#include "base/gtest_prod_util.h"
16#include "base/memory/ref_counted.h"
17#include "base/memory/scoped_ptr.h"
18#include "base/memory/weak_ptr.h"
19#include "base/single_thread_task_runner.h"
20#include "base/threading/thread_checker.h"
21#include "base/time/time.h"
22#include "base/timer/timer.h"
23#include "net/base/completion_callback.h"
24#include "net/base/net_export.h"
25
26#if defined(OS_ANDROID)
27#include "base/android/activity_status.h"
28#endif
29
30class Pickle;
31class PickleIterator;
32
33namespace disk_cache {
34
35class SimpleIndexFile;
36struct SimpleIndexLoadResult;
37
38class NET_EXPORT_PRIVATE EntryMetadata {
39 public:
40  EntryMetadata();
41  EntryMetadata(base::Time last_used_time, uint64 entry_size);
42
43  base::Time GetLastUsedTime() const;
44  void SetLastUsedTime(const base::Time& last_used_time);
45
46  uint64 GetEntrySize() const { return entry_size_; }
47  void SetEntrySize(uint64 entry_size) { entry_size_ = entry_size; }
48
49  // Serialize the data into the provided pickle.
50  void Serialize(Pickle* pickle) const;
51  bool Deserialize(PickleIterator* it);
52
53 private:
54  friend class SimpleIndexFileTest;
55
56  // When adding new members here, you should update the Serialize() and
57  // Deserialize() methods.
58
59  // This is the serialized format from Time::ToInternalValue().
60  // If you want to make calculations/comparisons, you should use the
61  // base::Time() class. Use the GetLastUsedTime() method above.
62  // TODO(felipeg): Use Time() here.
63  int64 last_used_time_;
64
65  uint64 entry_size_;  // Storage size in bytes.
66};
67
68// This class is not Thread-safe.
69class NET_EXPORT_PRIVATE SimpleIndex
70    : public base::SupportsWeakPtr<SimpleIndex> {
71 public:
72  typedef std::vector<uint64> HashList;
73
74  SimpleIndex(base::SingleThreadTaskRunner* io_thread,
75              const base::FilePath& cache_directory,
76              scoped_ptr<SimpleIndexFile> simple_index_file);
77
78  virtual ~SimpleIndex();
79
80  void Initialize(base::Time cache_mtime);
81
82  bool SetMaxSize(int max_bytes);
83  int max_size() const { return max_size_; }
84
85  void Insert(uint64 entry_hash);
86  void Remove(uint64 entry_hash);
87
88  // Check whether the index has the entry given the hash of its key.
89  bool Has(uint64 entry_hash) const;
90
91  // Update the last used time of the entry with the given key and return true
92  // iff the entry exist in the index.
93  bool UseIfExists(uint64 entry_hash);
94
95  void WriteToDisk();
96
97  // Update the size (in bytes) of an entry, in the metadata stored in the
98  // index. This should be the total disk-file size including all streams of the
99  // entry.
100  bool UpdateEntrySize(uint64 entry_hash, uint64 entry_size);
101
102  typedef base::hash_map<uint64, EntryMetadata> EntrySet;
103
104  static void InsertInEntrySet(uint64 entry_hash,
105                               const EntryMetadata& entry_metadata,
106                               EntrySet* entry_set);
107
108  // Executes the |callback| when the index is ready. Allows multiple callbacks.
109  int ExecuteWhenReady(const net::CompletionCallback& callback);
110
111  // Takes out entries from the index that have last accessed time matching the
112  // range between |initial_time| and |end_time| where open intervals are
113  // possible according to the definition given in |DoomEntriesBetween()| in the
114  // disk cache backend interface. Returns the set of hashes taken out.
115  scoped_ptr<HashList> RemoveEntriesBetween(const base::Time initial_time,
116                                            const base::Time end_time);
117
118  // Returns the list of all entries key hash.
119  scoped_ptr<HashList> GetAllHashes();
120
121  // Returns number of indexed entries.
122  int32 GetEntryCount() const;
123
124  // Returns whether the index has been initialized yet.
125  bool initialized() const { return initialized_; }
126
127 private:
128  friend class SimpleIndexTest;
129  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge);
130  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteQueued);
131  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteExecuted);
132  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWritePostponed);
133
134  void StartEvictionIfNeeded();
135  void EvictionDone(int result);
136
137  void PostponeWritingToDisk();
138
139  void UpdateEntryIteratorSize(EntrySet::iterator* it, uint64 entry_size);
140
141  // Must run on IO Thread.
142  void MergeInitializingSet(scoped_ptr<SimpleIndexLoadResult> load_result);
143
144#if defined(OS_ANDROID)
145  void OnActivityStateChange(base::android::ActivityState state);
146
147  scoped_ptr<base::android::ActivityStatus::Listener> activity_status_listener_;
148#endif
149
150  scoped_ptr<HashList> ExtractEntriesBetween(const base::Time initial_time,
151                                             const base::Time end_time,
152                                             bool delete_entries);
153
154  EntrySet entries_set_;
155
156  uint64 cache_size_;  // Total cache storage size in bytes.
157  uint64 max_size_;
158  uint64 high_watermark_;
159  uint64 low_watermark_;
160  bool eviction_in_progress_;
161  base::TimeTicks eviction_start_time_;
162
163  // This stores all the entry_hash of entries that are removed during
164  // initialization.
165  base::hash_set<uint64> removed_entries_;
166  bool initialized_;
167
168  const base::FilePath& cache_directory_;
169  scoped_ptr<SimpleIndexFile> index_file_;
170
171  scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
172
173  // All nonstatic SimpleEntryImpl methods should always be called on the IO
174  // thread, in all cases. |io_thread_checker_| documents and enforces this.
175  base::ThreadChecker io_thread_checker_;
176
177  // Timestamp of the last time we wrote the index to disk.
178  // PostponeWritingToDisk() may give up postponing and allow the write if it
179  // has been a while since last time we wrote.
180  base::TimeTicks last_write_to_disk_;
181
182  base::OneShotTimer<SimpleIndex> write_to_disk_timer_;
183  base::Closure write_to_disk_cb_;
184
185  typedef std::list<net::CompletionCallback> CallbackList;
186  CallbackList to_run_when_initialized_;
187
188  // Set to true when the app is on the background. When the app is in the
189  // background we can write the index much more frequently, to insure fresh
190  // index on next startup.
191  bool app_on_background_;
192
193  // The time in milliseconds for the index to be idle before it gets flushed to
194  // the disk. When the app is on foreground the delay is different from the
195  // background state.
196  int foreground_flush_delay_;
197  int background_flush_delay_;
198};
199
200}  // namespace disk_cache
201
202#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
203