OLD | NEW |
1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/disk_cache/mem_backend_impl.h" | 5 #include "net/disk_cache/mem_backend_impl.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/sys_info.h" | 8 #include "base/sys_info.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/disk_cache/cache_util.h" | 10 #include "net/disk_cache/cache_util.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 if (high_water < kCleanUpMargin) | 21 if (high_water < kCleanUpMargin) |
22 return 0; | 22 return 0; |
23 | 23 |
24 return high_water - kCleanUpMargin; | 24 return high_water - kCleanUpMargin; |
25 } | 25 } |
26 | 26 |
27 } // namespace | 27 } // namespace |
28 | 28 |
29 namespace disk_cache { | 29 namespace disk_cache { |
30 | 30 |
| 31 MemBackendImpl::MemBackendImpl() : max_size_(0), current_size_(0) {} |
| 32 |
| 33 MemBackendImpl::~MemBackendImpl() { |
| 34 EntryMap::iterator it = entries_.begin(); |
| 35 while (it != entries_.end()) { |
| 36 it->second->Doom(); |
| 37 it = entries_.begin(); |
| 38 } |
| 39 DCHECK(!current_size_); |
| 40 } |
| 41 |
31 // Static. | 42 // Static. |
32 Backend* MemBackendImpl::CreateBackend(int max_bytes) { | 43 Backend* MemBackendImpl::CreateBackend(int max_bytes) { |
33 MemBackendImpl* cache = new MemBackendImpl(); | 44 MemBackendImpl* cache = new MemBackendImpl(); |
34 cache->SetMaxSize(max_bytes); | 45 cache->SetMaxSize(max_bytes); |
35 if (cache->Init()) | 46 if (cache->Init()) |
36 return cache; | 47 return cache; |
37 | 48 |
38 delete cache; | 49 delete cache; |
39 LOG(ERROR) << "Unable to create cache"; | 50 LOG(ERROR) << "Unable to create cache"; |
40 return NULL; | 51 return NULL; |
(...skipping 14 matching lines...) Expand all Loading... |
55 // reached on systemd with more than 2.5 GB of RAM. | 66 // reached on systemd with more than 2.5 GB of RAM. |
56 total_memory = total_memory * 2 / 100; | 67 total_memory = total_memory * 2 / 100; |
57 if (total_memory > kDefaultCacheSize * 5) | 68 if (total_memory > kDefaultCacheSize * 5) |
58 max_size_ = kDefaultCacheSize * 5; | 69 max_size_ = kDefaultCacheSize * 5; |
59 else | 70 else |
60 max_size_ = static_cast<int32>(total_memory); | 71 max_size_ = static_cast<int32>(total_memory); |
61 | 72 |
62 return true; | 73 return true; |
63 } | 74 } |
64 | 75 |
65 MemBackendImpl::MemBackendImpl() : max_size_(0), current_size_(0) {} | |
66 | |
67 MemBackendImpl::~MemBackendImpl() { | |
68 EntryMap::iterator it = entries_.begin(); | |
69 while (it != entries_.end()) { | |
70 it->second->Doom(); | |
71 it = entries_.begin(); | |
72 } | |
73 DCHECK(!current_size_); | |
74 } | |
75 | |
76 bool MemBackendImpl::SetMaxSize(int max_bytes) { | 76 bool MemBackendImpl::SetMaxSize(int max_bytes) { |
77 COMPILE_ASSERT(sizeof(max_bytes) == sizeof(max_size_), unsupported_int_model); | 77 COMPILE_ASSERT(sizeof(max_bytes) == sizeof(max_size_), unsupported_int_model); |
78 if (max_bytes < 0) | 78 if (max_bytes < 0) |
79 return false; | 79 return false; |
80 | 80 |
81 // Zero size means use the default. | 81 // Zero size means use the default. |
82 if (!max_bytes) | 82 if (!max_bytes) |
83 return true; | 83 return true; |
84 | 84 |
85 max_size_ = max_bytes; | 85 max_size_ = max_bytes; |
86 return true; | 86 return true; |
87 } | 87 } |
88 | 88 |
| 89 void MemBackendImpl::InternalDoomEntry(MemEntryImpl* entry) { |
| 90 // Only parent entries can be passed into this method. |
| 91 DCHECK(entry->type() == MemEntryImpl::kParentEntry); |
| 92 |
| 93 rankings_.Remove(entry); |
| 94 EntryMap::iterator it = entries_.find(entry->GetKey()); |
| 95 if (it != entries_.end()) |
| 96 entries_.erase(it); |
| 97 else |
| 98 NOTREACHED(); |
| 99 |
| 100 entry->InternalDoom(); |
| 101 } |
| 102 |
| 103 void MemBackendImpl::UpdateRank(MemEntryImpl* node) { |
| 104 rankings_.UpdateRank(node); |
| 105 } |
| 106 |
| 107 void MemBackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) { |
| 108 if (old_size >= new_size) |
| 109 SubstractStorageSize(old_size - new_size); |
| 110 else |
| 111 AddStorageSize(new_size - old_size); |
| 112 } |
| 113 |
| 114 int MemBackendImpl::MaxFileSize() const { |
| 115 return max_size_ / 8; |
| 116 } |
| 117 |
| 118 void MemBackendImpl::InsertIntoRankingList(MemEntryImpl* entry) { |
| 119 rankings_.Insert(entry); |
| 120 } |
| 121 |
| 122 void MemBackendImpl::RemoveFromRankingList(MemEntryImpl* entry) { |
| 123 rankings_.Remove(entry); |
| 124 } |
| 125 |
89 int32 MemBackendImpl::GetEntryCount() const { | 126 int32 MemBackendImpl::GetEntryCount() const { |
90 return static_cast<int32>(entries_.size()); | 127 return static_cast<int32>(entries_.size()); |
91 } | 128 } |
92 | 129 |
| 130 int MemBackendImpl::OpenEntry(const std::string& key, Entry** entry, |
| 131 CompletionCallback* callback) { |
| 132 if (OpenEntry(key, entry)) |
| 133 return net::OK; |
| 134 |
| 135 return net::ERR_FAILED; |
| 136 } |
| 137 |
| 138 int MemBackendImpl::CreateEntry(const std::string& key, Entry** entry, |
| 139 CompletionCallback* callback) { |
| 140 if (CreateEntry(key, entry)) |
| 141 return net::OK; |
| 142 |
| 143 return net::ERR_FAILED; |
| 144 } |
| 145 |
| 146 int MemBackendImpl::DoomEntry(const std::string& key, |
| 147 CompletionCallback* callback) { |
| 148 if (DoomEntry(key)) |
| 149 return net::OK; |
| 150 |
| 151 return net::ERR_FAILED; |
| 152 } |
| 153 |
| 154 int MemBackendImpl::DoomAllEntries(CompletionCallback* callback) { |
| 155 if (DoomAllEntries()) |
| 156 return net::OK; |
| 157 |
| 158 return net::ERR_FAILED; |
| 159 } |
| 160 |
| 161 int MemBackendImpl::DoomEntriesBetween(const base::Time initial_time, |
| 162 const base::Time end_time, |
| 163 CompletionCallback* callback) { |
| 164 if (DoomEntriesBetween(initial_time, end_time)) |
| 165 return net::OK; |
| 166 |
| 167 return net::ERR_FAILED; |
| 168 } |
| 169 |
| 170 int MemBackendImpl::DoomEntriesSince(const base::Time initial_time, |
| 171 CompletionCallback* callback) { |
| 172 if (DoomEntriesSince(initial_time)) |
| 173 return net::OK; |
| 174 |
| 175 return net::ERR_FAILED; |
| 176 } |
| 177 |
| 178 int MemBackendImpl::OpenNextEntry(void** iter, Entry** next_entry, |
| 179 CompletionCallback* callback) { |
| 180 if (OpenNextEntry(iter, next_entry)) |
| 181 return net::OK; |
| 182 |
| 183 return net::ERR_FAILED; |
| 184 } |
| 185 |
| 186 void MemBackendImpl::EndEnumeration(void** iter) { |
| 187 *iter = NULL; |
| 188 } |
| 189 |
93 bool MemBackendImpl::OpenEntry(const std::string& key, Entry** entry) { | 190 bool MemBackendImpl::OpenEntry(const std::string& key, Entry** entry) { |
94 EntryMap::iterator it = entries_.find(key); | 191 EntryMap::iterator it = entries_.find(key); |
95 if (it == entries_.end()) | 192 if (it == entries_.end()) |
96 return false; | 193 return false; |
97 | 194 |
98 it->second->Open(); | 195 it->second->Open(); |
99 | 196 |
100 *entry = it->second; | 197 *entry = it->second; |
101 return true; | 198 return true; |
102 } | 199 } |
103 | 200 |
104 int MemBackendImpl::OpenEntry(const std::string& key, Entry** entry, | |
105 CompletionCallback* callback) { | |
106 if (OpenEntry(key, entry)) | |
107 return net::OK; | |
108 | |
109 return net::ERR_FAILED; | |
110 } | |
111 | |
112 bool MemBackendImpl::CreateEntry(const std::string& key, Entry** entry) { | 201 bool MemBackendImpl::CreateEntry(const std::string& key, Entry** entry) { |
113 EntryMap::iterator it = entries_.find(key); | 202 EntryMap::iterator it = entries_.find(key); |
114 if (it != entries_.end()) | 203 if (it != entries_.end()) |
115 return false; | 204 return false; |
116 | 205 |
117 MemEntryImpl* cache_entry = new MemEntryImpl(this); | 206 MemEntryImpl* cache_entry = new MemEntryImpl(this); |
118 if (!cache_entry->CreateEntry(key)) { | 207 if (!cache_entry->CreateEntry(key)) { |
119 delete entry; | 208 delete entry; |
120 return false; | 209 return false; |
121 } | 210 } |
122 | 211 |
123 rankings_.Insert(cache_entry); | 212 rankings_.Insert(cache_entry); |
124 entries_[key] = cache_entry; | 213 entries_[key] = cache_entry; |
125 | 214 |
126 *entry = cache_entry; | 215 *entry = cache_entry; |
127 return true; | 216 return true; |
128 } | 217 } |
129 | 218 |
130 int MemBackendImpl::CreateEntry(const std::string& key, Entry** entry, | |
131 CompletionCallback* callback) { | |
132 if (CreateEntry(key, entry)) | |
133 return net::OK; | |
134 | |
135 return net::ERR_FAILED; | |
136 } | |
137 | |
138 bool MemBackendImpl::DoomEntry(const std::string& key) { | 219 bool MemBackendImpl::DoomEntry(const std::string& key) { |
139 Entry* entry; | 220 Entry* entry; |
140 if (!OpenEntry(key, &entry)) | 221 if (!OpenEntry(key, &entry)) |
141 return false; | 222 return false; |
142 | 223 |
143 entry->Doom(); | 224 entry->Doom(); |
144 entry->Close(); | 225 entry->Close(); |
145 return true; | 226 return true; |
146 } | 227 } |
147 | 228 |
148 int MemBackendImpl::DoomEntry(const std::string& key, | |
149 CompletionCallback* callback) { | |
150 if (DoomEntry(key)) | |
151 return net::OK; | |
152 | |
153 return net::ERR_FAILED; | |
154 } | |
155 | |
156 void MemBackendImpl::InternalDoomEntry(MemEntryImpl* entry) { | |
157 // Only parent entries can be passed into this method. | |
158 DCHECK(entry->type() == MemEntryImpl::kParentEntry); | |
159 | |
160 rankings_.Remove(entry); | |
161 EntryMap::iterator it = entries_.find(entry->GetKey()); | |
162 if (it != entries_.end()) | |
163 entries_.erase(it); | |
164 else | |
165 NOTREACHED(); | |
166 | |
167 entry->InternalDoom(); | |
168 } | |
169 | |
170 bool MemBackendImpl::DoomAllEntries() { | 229 bool MemBackendImpl::DoomAllEntries() { |
171 TrimCache(true); | 230 TrimCache(true); |
172 return true; | 231 return true; |
173 } | 232 } |
174 | 233 |
175 int MemBackendImpl::DoomAllEntries(CompletionCallback* callback) { | |
176 if (DoomAllEntries()) | |
177 return net::OK; | |
178 | |
179 return net::ERR_FAILED; | |
180 } | |
181 | |
182 bool MemBackendImpl::DoomEntriesBetween(const Time initial_time, | 234 bool MemBackendImpl::DoomEntriesBetween(const Time initial_time, |
183 const Time end_time) { | 235 const Time end_time) { |
184 if (end_time.is_null()) | 236 if (end_time.is_null()) |
185 return DoomEntriesSince(initial_time); | 237 return DoomEntriesSince(initial_time); |
186 | 238 |
187 DCHECK(end_time >= initial_time); | 239 DCHECK(end_time >= initial_time); |
188 | 240 |
189 MemEntryImpl* next = rankings_.GetNext(NULL); | 241 MemEntryImpl* next = rankings_.GetNext(NULL); |
190 | 242 |
191 // rankings_ is ordered by last used, this will descend through the cache | 243 // rankings_ is ordered by last used, this will descend through the cache |
192 // and start dooming items before the end_time, and will stop once it reaches | 244 // and start dooming items before the end_time, and will stop once it reaches |
193 // an item used before the initial time. | 245 // an item used before the initial time. |
194 while (next) { | 246 while (next) { |
195 MemEntryImpl* node = next; | 247 MemEntryImpl* node = next; |
196 next = rankings_.GetNext(next); | 248 next = rankings_.GetNext(next); |
197 | 249 |
198 if (node->GetLastUsed() < initial_time) | 250 if (node->GetLastUsed() < initial_time) |
199 break; | 251 break; |
200 | 252 |
201 if (node->GetLastUsed() < end_time) | 253 if (node->GetLastUsed() < end_time) |
202 node->Doom(); | 254 node->Doom(); |
203 } | 255 } |
204 | 256 |
205 return true; | 257 return true; |
206 } | 258 } |
207 | 259 |
208 int MemBackendImpl::DoomEntriesBetween(const base::Time initial_time, | |
209 const base::Time end_time, | |
210 CompletionCallback* callback) { | |
211 if (DoomEntriesBetween(initial_time, end_time)) | |
212 return net::OK; | |
213 | |
214 return net::ERR_FAILED; | |
215 } | |
216 | |
217 bool MemBackendImpl::DoomEntriesSince(const Time initial_time) { | 260 bool MemBackendImpl::DoomEntriesSince(const Time initial_time) { |
218 for (;;) { | 261 for (;;) { |
219 // Get the entry in the front. | 262 // Get the entry in the front. |
220 Entry* entry = rankings_.GetNext(NULL); | 263 Entry* entry = rankings_.GetNext(NULL); |
221 | 264 |
222 // Break the loop when there are no more entries or the entry is too old. | 265 // Break the loop when there are no more entries or the entry is too old. |
223 if (!entry || entry->GetLastUsed() < initial_time) | 266 if (!entry || entry->GetLastUsed() < initial_time) |
224 return true; | 267 return true; |
225 entry->Doom(); | 268 entry->Doom(); |
226 } | 269 } |
227 } | 270 } |
228 | 271 |
229 int MemBackendImpl::DoomEntriesSince(const base::Time initial_time, | |
230 CompletionCallback* callback) { | |
231 if (DoomEntriesSince(initial_time)) | |
232 return net::OK; | |
233 | |
234 return net::ERR_FAILED; | |
235 } | |
236 | |
237 bool MemBackendImpl::OpenNextEntry(void** iter, Entry** next_entry) { | 272 bool MemBackendImpl::OpenNextEntry(void** iter, Entry** next_entry) { |
238 MemEntryImpl* current = reinterpret_cast<MemEntryImpl*>(*iter); | 273 MemEntryImpl* current = reinterpret_cast<MemEntryImpl*>(*iter); |
239 MemEntryImpl* node = rankings_.GetNext(current); | 274 MemEntryImpl* node = rankings_.GetNext(current); |
240 // We should never return a child entry so iterate until we hit a parent | 275 // We should never return a child entry so iterate until we hit a parent |
241 // entry. | 276 // entry. |
242 while (node && node->type() != MemEntryImpl::kParentEntry) { | 277 while (node && node->type() != MemEntryImpl::kParentEntry) { |
243 node = rankings_.GetNext(node); | 278 node = rankings_.GetNext(node); |
244 } | 279 } |
245 *next_entry = node; | 280 *next_entry = node; |
246 *iter = node; | 281 *iter = node; |
247 | 282 |
248 if (node) | 283 if (node) |
249 node->Open(); | 284 node->Open(); |
250 | 285 |
251 return NULL != node; | 286 return NULL != node; |
252 } | 287 } |
253 | 288 |
254 int MemBackendImpl::OpenNextEntry(void** iter, Entry** next_entry, | |
255 CompletionCallback* callback) { | |
256 if (OpenNextEntry(iter, next_entry)) | |
257 return net::OK; | |
258 | |
259 return net::ERR_FAILED; | |
260 } | |
261 | |
262 void MemBackendImpl::EndEnumeration(void** iter) { | |
263 *iter = NULL; | |
264 } | |
265 | |
266 void MemBackendImpl::TrimCache(bool empty) { | 289 void MemBackendImpl::TrimCache(bool empty) { |
267 MemEntryImpl* next = rankings_.GetPrev(NULL); | 290 MemEntryImpl* next = rankings_.GetPrev(NULL); |
268 | 291 |
269 DCHECK(next); | 292 DCHECK(next); |
270 | 293 |
271 int target_size = empty ? 0 : LowWaterAdjust(max_size_); | 294 int target_size = empty ? 0 : LowWaterAdjust(max_size_); |
272 while (current_size_ > target_size && next) { | 295 while (current_size_ > target_size && next) { |
273 MemEntryImpl* node = next; | 296 MemEntryImpl* node = next; |
274 next = rankings_.GetPrev(next); | 297 next = rankings_.GetPrev(next); |
275 if (!node->InUse() || empty) { | 298 if (!node->InUse() || empty) { |
(...skipping 10 matching lines...) Expand all Loading... |
286 | 309 |
287 if (current_size_ > max_size_) | 310 if (current_size_ > max_size_) |
288 TrimCache(false); | 311 TrimCache(false); |
289 } | 312 } |
290 | 313 |
291 void MemBackendImpl::SubstractStorageSize(int32 bytes) { | 314 void MemBackendImpl::SubstractStorageSize(int32 bytes) { |
292 current_size_ -= bytes; | 315 current_size_ -= bytes; |
293 DCHECK(current_size_ >= 0); | 316 DCHECK(current_size_ >= 0); |
294 } | 317 } |
295 | 318 |
296 void MemBackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) { | |
297 if (old_size >= new_size) | |
298 SubstractStorageSize(old_size - new_size); | |
299 else | |
300 AddStorageSize(new_size - old_size); | |
301 } | |
302 | |
303 void MemBackendImpl::UpdateRank(MemEntryImpl* node) { | |
304 rankings_.UpdateRank(node); | |
305 } | |
306 | |
307 int MemBackendImpl::MaxFileSize() const { | |
308 return max_size_ / 8; | |
309 } | |
310 | |
311 void MemBackendImpl::InsertIntoRankingList(MemEntryImpl* entry) { | |
312 rankings_.Insert(entry); | |
313 } | |
314 | |
315 void MemBackendImpl::RemoveFromRankingList(MemEntryImpl* entry) { | |
316 rankings_.Remove(entry); | |
317 } | |
318 | |
319 } // namespace disk_cache | 319 } // namespace disk_cache |
OLD | NEW |