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 15 matching lines...) Expand all Loading... | |
26 #include "base/time/time.h" | 26 #include "base/time/time.h" |
27 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" |
28 #include "net/disk_cache/backend_impl.h" | 28 #include "net/disk_cache/backend_impl.h" |
29 #include "net/disk_cache/simple/simple_entry_format.h" | 29 #include "net/disk_cache/simple/simple_entry_format.h" |
30 #include "net/disk_cache/simple/simple_entry_impl.h" | 30 #include "net/disk_cache/simple/simple_entry_impl.h" |
31 #include "net/disk_cache/simple/simple_index.h" | 31 #include "net/disk_cache/simple/simple_index.h" |
32 #include "net/disk_cache/simple/simple_index_file.h" | 32 #include "net/disk_cache/simple/simple_index_file.h" |
33 #include "net/disk_cache/simple/simple_synchronous_entry.h" | 33 #include "net/disk_cache/simple/simple_synchronous_entry.h" |
34 #include "net/disk_cache/simple/simple_util.h" | 34 #include "net/disk_cache/simple/simple_util.h" |
35 | 35 |
36 using base::Callback; | |
36 using base::Closure; | 37 using base::Closure; |
37 using base::FilePath; | 38 using base::FilePath; |
38 using base::MessageLoopProxy; | 39 using base::MessageLoopProxy; |
39 using base::SequencedWorkerPool; | 40 using base::SequencedWorkerPool; |
40 using base::SingleThreadTaskRunner; | 41 using base::SingleThreadTaskRunner; |
41 using base::Time; | 42 using base::Time; |
42 using base::DirectoryExists; | 43 using base::DirectoryExists; |
43 using file_util::CreateDirectory; | 44 using file_util::CreateDirectory; |
44 | 45 |
45 namespace { | 46 namespace { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 return true; | 190 return true; |
190 } | 191 } |
191 } | 192 } |
192 | 193 |
193 void CallCompletionCallback(const net::CompletionCallback& callback, | 194 void CallCompletionCallback(const net::CompletionCallback& callback, |
194 int error_code) { | 195 int error_code) { |
195 DCHECK(!callback.is_null()); | 196 DCHECK(!callback.is_null()); |
196 callback.Run(error_code); | 197 callback.Run(error_code); |
197 } | 198 } |
198 | 199 |
200 // See ChainOperationIntoClosure, below. | |
201 void ChainOperationIntoClosureImpl( | |
202 const Callback<int(const net::CompletionCallback&)>& to_chain_operation, | |
203 const net::CompletionCallback& operation_callback, | |
204 const Closure& closure) { | |
205 const int operation_result = to_chain_operation.Run(operation_callback); | |
206 if (operation_result != net::ERR_IO_PENDING) | |
207 operation_callback.Run(operation_result); | |
208 if (!closure.is_null()) | |
209 closure.Run(); | |
210 } | |
211 | |
212 // Returns a Closure that will first run |to_chain_operation|, returning its | |
213 // result to |operation_callback|, and finally run |closure| if it is not null. | |
214 Closure ChainOperationIntoClosure( | |
215 const Callback<int(const net::CompletionCallback&)>& to_chain_operation, | |
216 const net::CompletionCallback& operation_callback, | |
217 const Closure& closure) { | |
218 return base::Bind(&ChainOperationIntoClosureImpl, to_chain_operation, | |
219 operation_callback, closure); | |
220 } | |
221 | |
199 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { | 222 void RecordIndexLoad(base::TimeTicks constructed_since, int result) { |
200 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - | 223 const base::TimeDelta creation_to_index = base::TimeTicks::Now() - |
201 constructed_since; | 224 constructed_since; |
202 if (result == net::OK) | 225 if (result == net::OK) |
203 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); | 226 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndex", creation_to_index); |
204 else | 227 else |
205 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); | 228 UMA_HISTOGRAM_TIMES("SimpleCache.CreationToIndexFail", creation_to_index); |
206 } | 229 } |
207 | 230 |
208 } // namespace | 231 } // namespace |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 } | 282 } |
260 | 283 |
261 int SimpleBackendImpl::GetMaxFileSize() const { | 284 int SimpleBackendImpl::GetMaxFileSize() const { |
262 return index_->max_size() / kMaxFileRatio; | 285 return index_->max_size() / kMaxFileRatio; |
263 } | 286 } |
264 | 287 |
265 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { | 288 void SimpleBackendImpl::OnDeactivated(const SimpleEntryImpl* entry) { |
266 active_entries_.erase(entry->entry_hash()); | 289 active_entries_.erase(entry->entry_hash()); |
267 } | 290 } |
268 | 291 |
292 void SimpleBackendImpl::OnDoomStart(uint64 entry_hash) { | |
293 DCHECK_EQ(0u, entries_pending_doom_.count(entry_hash)); | |
294 entries_pending_doom_.insert(std::make_pair(entry_hash, Closure())); | |
295 } | |
296 | |
297 void SimpleBackendImpl::OnDoomComplete(uint64 entry_hash) { | |
298 DCHECK_EQ(1u, entries_pending_doom_.count(entry_hash)); | |
299 base::hash_map<uint64, base::Closure>::iterator it = | |
300 entries_pending_doom_.find(entry_hash); | |
301 Closure to_run_closure = it->second; | |
302 entries_pending_doom_.erase(it); | |
303 | |
304 if (!to_run_closure.is_null()) | |
305 to_run_closure.Run(); | |
306 } | |
307 | |
269 net::CacheType SimpleBackendImpl::GetCacheType() const { | 308 net::CacheType SimpleBackendImpl::GetCacheType() const { |
270 return net::DISK_CACHE; | 309 return net::DISK_CACHE; |
271 } | 310 } |
272 | 311 |
273 int32 SimpleBackendImpl::GetEntryCount() const { | 312 int32 SimpleBackendImpl::GetEntryCount() const { |
274 // TODO(pasko): Use directory file count when index is not ready. | 313 // TODO(pasko): Use directory file count when index is not ready. |
275 return index_->GetEntryCount(); | 314 return index_->GetEntryCount(); |
276 } | 315 } |
277 | 316 |
278 int SimpleBackendImpl::OpenEntry(const std::string& key, | 317 int SimpleBackendImpl::OpenEntry(const std::string& key, |
279 Entry** entry, | 318 Entry** entry, |
280 const CompletionCallback& callback) { | 319 const CompletionCallback& callback) { |
281 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 320 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
321 | |
322 base::hash_map<uint64, base::Closure>::iterator it = | |
323 entries_pending_doom_.find(entry_hash); | |
324 if (it != entries_pending_doom_.end()) { | |
325 Callback<int(const net::CompletionCallback&)> operation = | |
326 base::Bind(&SimpleBackendImpl::OpenEntry, | |
327 base::Unretained(this), key, entry); | |
328 it->second = ChainOperationIntoClosure(operation, callback, it->second); | |
Deprecated (see juliatuttle)
2013/09/03 16:15:11
This is really clever, but I think it's less clear
Philippe
2013/09/03 16:24:33
I agree at a glance that a map/multimap would look
Philippe
2013/09/03 16:25:58
s/how this/what this :)
Randy Smith (Not in Mondays)
2013/09/03 19:04:19
I think I'd prefer a map to a vector as Thomas sug
Philippe
2013/09/04 08:55:49
Right, this should work actually thanks to the ope
gavinp
2013/09/11 15:25:58
The latest upload uses a vector, and the code is v
| |
329 return net::ERR_IO_PENDING; | |
330 } | |
331 scoped_refptr<SimpleEntryImpl> simple_entry = | |
332 CreateOrFindActiveEntry(entry_hash, key); | |
282 CompletionCallback backend_callback = | 333 CompletionCallback backend_callback = |
283 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, | 334 base::Bind(&SimpleBackendImpl::OnEntryOpenedFromKey, |
284 AsWeakPtr(), | 335 AsWeakPtr(), |
285 key, | 336 key, |
286 entry, | 337 entry, |
287 simple_entry, | 338 simple_entry, |
288 callback); | 339 callback); |
289 return simple_entry->OpenEntry(entry, backend_callback); | 340 return simple_entry->OpenEntry(entry, backend_callback); |
290 } | 341 } |
291 | 342 |
292 int SimpleBackendImpl::CreateEntry(const std::string& key, | 343 int SimpleBackendImpl::CreateEntry(const std::string& key, |
293 Entry** entry, | 344 Entry** entry, |
294 const CompletionCallback& callback) { | 345 const CompletionCallback& callback) { |
295 DCHECK(key.size() > 0); | 346 DCHECK_GT(key.size(), 0u); |
296 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 347 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
348 | |
349 base::hash_map<uint64, base::Closure>::iterator it = | |
350 entries_pending_doom_.find(entry_hash); | |
351 if (it != entries_pending_doom_.end()) { | |
352 Callback<int(const net::CompletionCallback&)> operation = | |
353 base::Bind(&SimpleBackendImpl::CreateEntry, | |
354 base::Unretained(this), key, entry); | |
355 it->second = ChainOperationIntoClosure(operation, callback, it->second); | |
356 return net::ERR_IO_PENDING; | |
357 } | |
358 scoped_refptr<SimpleEntryImpl> simple_entry = | |
359 CreateOrFindActiveEntry(entry_hash, key); | |
297 return simple_entry->CreateEntry(entry, callback); | 360 return simple_entry->CreateEntry(entry, callback); |
298 } | 361 } |
299 | 362 |
300 int SimpleBackendImpl::DoomEntry(const std::string& key, | 363 int SimpleBackendImpl::DoomEntry(const std::string& key, |
301 const net::CompletionCallback& callback) { | 364 const net::CompletionCallback& callback) { |
302 scoped_refptr<SimpleEntryImpl> simple_entry = CreateOrFindActiveEntry(key); | 365 const uint64 entry_hash = simple_util::GetEntryHashKey(key); |
366 | |
367 base::hash_map<uint64, base::Closure>::iterator it = | |
368 entries_pending_doom_.find(entry_hash); | |
369 if (it != entries_pending_doom_.end()) { | |
370 Callback<int(const net::CompletionCallback&)> operation = | |
371 base::Bind(&SimpleBackendImpl::DoomEntry, base::Unretained(this), key); | |
372 it->second = ChainOperationIntoClosure(operation, callback, it->second); | |
373 return net::ERR_IO_PENDING; | |
374 } | |
375 scoped_refptr<SimpleEntryImpl> simple_entry = | |
376 CreateOrFindActiveEntry(entry_hash, key); | |
303 return simple_entry->DoomEntry(callback); | 377 return simple_entry->DoomEntry(callback); |
304 } | 378 } |
305 | 379 |
306 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { | 380 int SimpleBackendImpl::DoomAllEntries(const CompletionCallback& callback) { |
307 return DoomEntriesBetween(Time(), Time(), callback); | 381 return DoomEntriesBetween(Time(), Time(), callback); |
308 } | 382 } |
309 | 383 |
310 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, | 384 void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, |
311 Time end_time, | 385 Time end_time, |
312 const CompletionCallback& callback, | 386 const CompletionCallback& callback, |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
415 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the | 489 // TODO(pasko): Move PreferedCacheSize() to cache_util.h. Also fix the |
416 // spelling. | 490 // spelling. |
417 result.max_size = disk_cache::PreferedCacheSize(available); | 491 result.max_size = disk_cache::PreferedCacheSize(available); |
418 } | 492 } |
419 DCHECK(result.max_size); | 493 DCHECK(result.max_size); |
420 } | 494 } |
421 return result; | 495 return result; |
422 } | 496 } |
423 | 497 |
424 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( | 498 scoped_refptr<SimpleEntryImpl> SimpleBackendImpl::CreateOrFindActiveEntry( |
499 const uint64 entry_hash, | |
425 const std::string& key) { | 500 const std::string& key) { |
Randy Smith (Not in Mondays)
2013/09/03 19:04:19
Suggestion: DCHECK(entry_hash, simple_util::GetEnt
gavinp
2013/09/11 15:25:58
Done.
| |
426 const uint64 entry_hash = simple_util::GetEntryHashKey(key); | |
427 | |
428 std::pair<EntryMap::iterator, bool> insert_result = | 501 std::pair<EntryMap::iterator, bool> insert_result = |
429 active_entries_.insert(std::make_pair(entry_hash, | 502 active_entries_.insert(std::make_pair(entry_hash, |
430 base::WeakPtr<SimpleEntryImpl>())); | 503 base::WeakPtr<SimpleEntryImpl>())); |
431 EntryMap::iterator& it = insert_result.first; | 504 EntryMap::iterator& it = insert_result.first; |
432 if (insert_result.second) | 505 if (insert_result.second) |
433 DCHECK(!it->second.get()); | 506 DCHECK(!it->second.get()); |
434 if (!it->second.get()) { | 507 if (!it->second.get()) { |
435 SimpleEntryImpl* entry = new SimpleEntryImpl( | 508 SimpleEntryImpl* entry = new SimpleEntryImpl( |
436 path_, entry_hash, entry_operations_mode_, this, net_log_); | 509 path_, entry_hash, entry_operations_mode_, this, net_log_); |
437 entry->SetKey(key); | 510 entry->SetKey(key); |
438 it->second = entry->AsWeakPtr(); | 511 it->second = entry->AsWeakPtr(); |
439 } | 512 } |
440 DCHECK(it->second.get()); | 513 DCHECK(it->second.get()); |
441 // It's possible, but unlikely, that we have an entry hash collision with a | 514 // It's possible, but unlikely, that we have an entry hash collision with a |
442 // currently active entry. | 515 // currently active entry. |
443 if (key != it->second->key()) { | 516 if (key != it->second->key()) { |
444 it->second->Doom(); | 517 it->second->Doom(); |
445 DCHECK_EQ(0U, active_entries_.count(entry_hash)); | 518 DCHECK_EQ(0U, active_entries_.count(entry_hash)); |
446 return CreateOrFindActiveEntry(key); | 519 return CreateOrFindActiveEntry(entry_hash, key); |
447 } | 520 } |
448 return make_scoped_refptr(it->second.get()); | 521 return make_scoped_refptr(it->second.get()); |
449 } | 522 } |
450 | 523 |
451 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, | 524 int SimpleBackendImpl::OpenEntryFromHash(uint64 hash, |
452 Entry** entry, | 525 Entry** entry, |
453 const CompletionCallback& callback) { | 526 const CompletionCallback& callback) { |
454 EntryMap::iterator has_active = active_entries_.find(hash); | 527 EntryMap::iterator has_active = active_entries_.find(hash); |
455 if (has_active != active_entries_.end()) | 528 if (has_active != active_entries_.end()) |
456 return OpenEntry(has_active->second->key(), entry, callback); | 529 return OpenEntry(has_active->second->key(), entry, callback); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
562 const CompletionCallback& callback, | 635 const CompletionCallback& callback, |
563 int error_code) { | 636 int error_code) { |
564 if (error_code == net::ERR_FAILED) { | 637 if (error_code == net::ERR_FAILED) { |
565 OpenNextEntry(iter, entry, callback); | 638 OpenNextEntry(iter, entry, callback); |
566 return; | 639 return; |
567 } | 640 } |
568 CallCompletionCallback(callback, error_code); | 641 CallCompletionCallback(callback, error_code); |
569 } | 642 } |
570 | 643 |
571 } // namespace disk_cache | 644 } // namespace disk_cache |
OLD | NEW |