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.
5 #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
6 #define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
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"
27 #if defined(OS_ANDROID)
28 #include "base/android/application_status_listener.h"
36 namespace disk_cache
{
38 class SimpleIndexDelegate
;
39 class SimpleIndexFile
;
40 struct SimpleIndexLoadResult
;
42 class NET_EXPORT_PRIVATE EntryMetadata
{
45 EntryMetadata(base::Time last_used_time
, uint64 entry_size
);
47 base::Time
GetLastUsedTime() const;
48 void SetLastUsedTime(const base::Time
& last_used_time
);
50 uint64
GetEntrySize() const;
51 void SetEntrySize(uint64 entry_size
);
53 // Serialize the data into the provided pickle.
54 void Serialize(base::Pickle
* pickle
) const;
55 bool Deserialize(base::PickleIterator
* it
);
57 static base::TimeDelta
GetLowerEpsilonForTimeComparisons() {
58 return base::TimeDelta::FromSeconds(1);
60 static base::TimeDelta
GetUpperEpsilonForTimeComparisons() {
61 return base::TimeDelta();
65 friend class SimpleIndexFileTest
;
67 // There are tens of thousands of instances of EntryMetadata in memory, so the
68 // size of each entry matters. Even when the values used to set these members
69 // are originally calculated as >32-bit types, the actual necessary size for
70 // each shouldn't exceed 32 bits, so we use 32-bit types here.
71 uint32 last_used_time_seconds_since_epoch_
;
72 int32 entry_size_
; // Storage size in bytes.
74 static_assert(sizeof(EntryMetadata
) == 8, "incorrect metadata size");
76 // This class is not Thread-safe.
77 class NET_EXPORT_PRIVATE SimpleIndex
78 : public base::SupportsWeakPtr
<SimpleIndex
> {
80 typedef std::vector
<uint64
> HashList
;
82 SimpleIndex(const scoped_refptr
<base::SingleThreadTaskRunner
>& io_thread
,
83 SimpleIndexDelegate
* delegate
,
84 net::CacheType cache_type
,
85 scoped_ptr
<SimpleIndexFile
> simple_index_file
);
87 virtual ~SimpleIndex();
89 void Initialize(base::Time cache_mtime
);
91 void SetMaxSize(uint64 max_bytes
);
92 uint64
max_size() const { return max_size_
; }
94 void Insert(uint64 entry_hash
);
95 void Remove(uint64 entry_hash
);
97 // Check whether the index has the entry given the hash of its key.
98 bool Has(uint64 entry_hash
) const;
100 // Update the last used time of the entry with the given key and return true
101 // iff the entry exist in the index.
102 bool UseIfExists(uint64 entry_hash
);
106 // Update the size (in bytes) of an entry, in the metadata stored in the
107 // index. This should be the total disk-file size including all streams of the
109 bool UpdateEntrySize(uint64 entry_hash
, int64 entry_size
);
111 typedef base::hash_map
<uint64
, EntryMetadata
> EntrySet
;
113 static void InsertInEntrySet(uint64 entry_hash
,
114 const EntryMetadata
& entry_metadata
,
115 EntrySet
* entry_set
);
117 // Executes the |callback| when the index is ready. Allows multiple callbacks.
118 int ExecuteWhenReady(const net::CompletionCallback
& callback
);
120 // Returns entries from the index that have last accessed time matching the
121 // range between |initial_time| and |end_time| where open intervals are
122 // possible according to the definition given in |DoomEntriesBetween()| in the
123 // disk cache backend interface.
124 scoped_ptr
<HashList
> GetEntriesBetween(const base::Time initial_time
,
125 const base::Time end_time
);
127 // Returns the list of all entries key hash.
128 scoped_ptr
<HashList
> GetAllHashes();
130 // Returns number of indexed entries.
131 int32
GetEntryCount() const;
133 // Returns whether the index has been initialized yet.
134 bool initialized() const { return initialized_
; }
137 friend class SimpleIndexTest
;
138 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest
, IndexSizeCorrectOnMerge
);
139 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest
, DiskWriteQueued
);
140 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest
, DiskWriteExecuted
);
141 FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest
, DiskWritePostponed
);
143 void StartEvictionIfNeeded();
144 void EvictionDone(int result
);
146 void PostponeWritingToDisk();
148 void UpdateEntryIteratorSize(EntrySet::iterator
* it
, int64 entry_size
);
150 // Must run on IO Thread.
151 void MergeInitializingSet(scoped_ptr
<SimpleIndexLoadResult
> load_result
);
153 #if defined(OS_ANDROID)
154 void OnApplicationStateChange(base::android::ApplicationState state
);
156 scoped_ptr
<base::android::ApplicationStatusListener
> app_status_listener_
;
159 // The owner of |this| must ensure the |delegate_| outlives |this|.
160 SimpleIndexDelegate
* delegate_
;
162 EntrySet entries_set_
;
164 const net::CacheType cache_type_
;
165 uint64 cache_size_
; // Total cache storage size in bytes.
167 uint64 high_watermark_
;
168 uint64 low_watermark_
;
169 bool eviction_in_progress_
;
170 base::TimeTicks eviction_start_time_
;
172 // This stores all the entry_hash of entries that are removed during
174 base::hash_set
<uint64
> removed_entries_
;
177 scoped_ptr
<SimpleIndexFile
> index_file_
;
179 scoped_refptr
<base::SingleThreadTaskRunner
> io_thread_
;
181 // All nonstatic SimpleEntryImpl methods should always be called on the IO
182 // thread, in all cases. |io_thread_checker_| documents and enforces this.
183 base::ThreadChecker io_thread_checker_
;
185 // Timestamp of the last time we wrote the index to disk.
186 // PostponeWritingToDisk() may give up postponing and allow the write if it
187 // has been a while since last time we wrote.
188 base::TimeTicks last_write_to_disk_
;
190 base::OneShotTimer
<SimpleIndex
> write_to_disk_timer_
;
191 base::Closure write_to_disk_cb_
;
193 typedef std::list
<net::CompletionCallback
> CallbackList
;
194 CallbackList to_run_when_initialized_
;
196 // Set to true when the app is on the background. When the app is in the
197 // background we can write the index much more frequently, to insure fresh
198 // index on next startup.
199 bool app_on_background_
;
202 } // namespace disk_cache
204 #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_