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