OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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/simple/simple_backend_impl.h" | 5 #include "net/disk_cache/simple/simple_backend_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstdlib> | 8 #include <cstdlib> |
9 | 9 |
10 #if defined(OS_POSIX) | 10 #if defined(OS_POSIX) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 // Cache size when all other size heuristics failed. | 53 // Cache size when all other size heuristics failed. |
54 const uint64 kDefaultCacheSize = 80 * 1024 * 1024; | 54 const uint64 kDefaultCacheSize = 80 * 1024 * 1024; |
55 | 55 |
56 // Maximum fraction of the cache that one entry can consume. | 56 // Maximum fraction of the cache that one entry can consume. |
57 const int kMaxFileRatio = 8; | 57 const int kMaxFileRatio = 8; |
58 | 58 |
59 // A global sequenced worker pool to use for launching all tasks. | 59 // A global sequenced worker pool to use for launching all tasks. |
60 SequencedWorkerPool* g_sequenced_worker_pool = NULL; | 60 SequencedWorkerPool* g_sequenced_worker_pool = NULL; |
61 | 61 |
| 62 class DoomEntrySetContext : public base::RefCounted<DoomEntrySetContext> { |
| 63 public: |
| 64 DoomEntrySetContext() : entries_left(0), error_happened(false) {} |
| 65 |
| 66 int entries_left; // Number of entries that remain to be doomed. |
| 67 bool error_happened; |
| 68 |
| 69 private: |
| 70 friend class base::RefCounted<DoomEntrySetContext>; |
| 71 |
| 72 ~DoomEntrySetContext() {} |
| 73 }; |
| 74 |
62 void MaybeCreateSequencedWorkerPool() { | 75 void MaybeCreateSequencedWorkerPool() { |
63 if (!g_sequenced_worker_pool) { | 76 if (!g_sequenced_worker_pool) { |
64 int max_worker_threads = kDefaultMaxWorkerThreads; | 77 int max_worker_threads = kDefaultMaxWorkerThreads; |
65 | 78 |
66 const std::string thread_count_field_trial = | 79 const std::string thread_count_field_trial = |
67 base::FieldTrialList::FindFullName("SimpleCacheMaxThreads"); | 80 base::FieldTrialList::FindFullName("SimpleCacheMaxThreads"); |
68 if (!thread_count_field_trial.empty()) { | 81 if (!thread_count_field_trial.empty()) { |
69 max_worker_threads = | 82 max_worker_threads = |
70 std::max(1, std::atoi(thread_count_field_trial.c_str())); | 83 std::max(1, std::atoi(thread_count_field_trial.c_str())); |
71 } | 84 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 211 |
199 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { | 212 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { |
200 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - | 213 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - |
201 constructed_since; | 214 constructed_since; |
202 if (result == net::OK) | 215 if (result == net::OK) |
203 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); | 216 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); |
204 else | 217 else |
205 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); | 218 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); |
206 } | 219 } |
207 | 220 |
| 221 // Used only by mass dooming to execute the client-provided callback once all |
| 222 // the entries are doomed. Note that this is called multiple times during a mass |
| 223 // doom operation (until the number of left entries in the context reaches 0). |
| 224 void OnDoomEntriesCompleted( |
| 225 DoomEntrySetContext* context, |
| 226 const net::CompletionCallback& all_entries_doomed_callback, |
| 227 int doomed_entries_count, |
| 228 int net_error) { |
| 229 context->entries_left -= doomed_entries_count; |
| 230 if (net_error == net::ERR_FAILED) |
| 231 context->error_happened = true; |
| 232 if (context->entries_left == 0 && !all_entries_doomed_callback.is_null()) { |
| 233 all_entries_doomed_callback.Run( |
| 234 context->error_happened ? net::ERR_FAILED : net::OK); |
| 235 } |
| 236 } |
| 237 |
208 } // namespace | 238 } // namespace |
209 | 239 |
210 namespace disk_cache { | 240 namespace disk_cache { |
211 | 241 |
212 SimpleBackendImpl::SimpleBackendImpl(const FilePath& path, | 242 SimpleBackendImpl::SimpleBackendImpl(const FilePath& path, |
213 int max_bytes, | 243 int max_bytes, |
214 net::CacheType type, | 244 net::CacheType type, |
215 base::SingleThreadTaskRunner* cache_thread, | 245 base::SingleThreadTaskRunner* cache_thread, |
216 net::NetLog* net_log) | 246 net::NetLog* net_log) |
217 : path_(path), | 247 : path_(path), |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, | 340 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, |
311 Time end_time, | 341 Time end_time, |
312 const CompletionCallback& callback, | 342 const CompletionCallback& callback, |
313 int result) { | 343 int result) { |
314 if (result != net::OK) { | 344 if (result != net::OK) { |
315 callback.Run(result); | 345 callback.Run(result); |
316 return; | 346 return; |
317 } | 347 } |
318 scoped_ptr<std::vector<uint64> > removed_key_hashes( | 348 scoped_ptr<std::vector<uint64> > removed_key_hashes( |
319 index_->RemoveEntriesBetween(initial_time, end_time).release()); | 349 index_->RemoveEntriesBetween(initial_time, end_time).release()); |
320 | 350 const scoped_refptr<DoomEntrySetContext> context(new DoomEntrySetContext()); |
| 351 const CompletionCallback on_entry_doomed_callback = base::Bind( |
| 352 &OnDoomEntriesCompleted, context, callback, 1 /* entry count */); |
| 353 int doomed_active_entries_count = 0; |
321 // If any of the entries we are dooming are currently open, we need to remove | 354 // If any of the entries we are dooming are currently open, we need to remove |
322 // them from |active_entries_|, so that attempts to create new entries will | 355 // them from |active_entries_|, so that attempts to create new entries will |
323 // succeed and attempts to open them will fail. | 356 // succeed and attempts to open them will fail. |
324 for (int i = removed_key_hashes->size() - 1; i >= 0; --i) { | 357 for (int i = removed_key_hashes->size() - 1; i >= 0; --i) { |
325 const uint64 entry_hash = (*removed_key_hashes)[i]; | 358 const uint64 entry_hash = (*removed_key_hashes)[i]; |
326 EntryMap::iterator it = active_entries_.find(entry_hash); | 359 EntryMap::iterator it = active_entries_.find(entry_hash); |
327 if (it == active_entries_.end()) | 360 if (it == active_entries_.end()) |
328 continue; | 361 continue; |
| 362 ++doomed_active_entries_count; |
329 SimpleEntryImpl* entry = it->second.get(); | 363 SimpleEntryImpl* entry = it->second.get(); |
330 entry->Doom(); | 364 entry->DoomEntry(on_entry_doomed_callback); |
331 | 365 |
332 (*removed_key_hashes)[i] = removed_key_hashes->back(); | 366 (*removed_key_hashes)[i] = removed_key_hashes->back(); |
333 removed_key_hashes->resize(removed_key_hashes->size() - 1); | 367 removed_key_hashes->resize(removed_key_hashes->size() - 1); |
334 } | 368 } |
| 369 const size_t removed_key_hashes_size = removed_key_hashes->size(); |
| 370 context->entries_left += doomed_active_entries_count; |
| 371 context->entries_left += removed_key_hashes_size; |
335 | 372 |
336 PostTaskAndReplyWithResult( | 373 PostTaskAndReplyWithResult( |
337 worker_pool_, FROM_HERE, | 374 worker_pool_, FROM_HERE, |
338 base::Bind(&SimpleSynchronousEntry::DoomEntrySet, | 375 base::Bind(&SimpleSynchronousEntry::DoomEntrySet, |
339 base::Passed(&removed_key_hashes), path_), | 376 base::Passed(&removed_key_hashes), path_), |
340 base::Bind(&CallCompletionCallback, callback)); | 377 base::Bind(&OnDoomEntriesCompleted, context, callback, |
| 378 removed_key_hashes_size)); |
341 } | 379 } |
342 | 380 |
343 int SimpleBackendImpl::DoomEntriesBetween( | 381 int SimpleBackendImpl::DoomEntriesBetween( |
344 const Time initial_time, | 382 const Time initial_time, |
345 const Time end_time, | 383 const Time end_time, |
346 const CompletionCallback& callback) { | 384 const CompletionCallback& callback) { |
347 return index_->ExecuteWhenReady( | 385 return index_->ExecuteWhenReady( |
348 base::Bind(&SimpleBackendImpl::IndexReadyForDoom, AsWeakPtr(), | 386 base::Bind(&SimpleBackendImpl::IndexReadyForDoom, AsWeakPtr(), |
349 initial_time, end_time, callback)); | 387 initial_time, end_time, callback)); |
350 } | 388 } |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 const CompletionCallback& callback, | 599 const CompletionCallback& callback, |
562 int error_code) { | 600 int error_code) { |
563 if (error_code == net::ERR_FAILED) { | 601 if (error_code == net::ERR_FAILED) { |
564 OpenNextEntry(iter, entry, callback); | 602 OpenNextEntry(iter, entry, callback); |
565 return; | 603 return; |
566 } | 604 } |
567 CallCompletionCallback(callback, error_code); | 605 CallCompletionCallback(callback, error_code); |
568 } | 606 } |
569 | 607 |
570 } // namespace disk_cache | 608 } // namespace disk_cache |
OLD | NEW |