1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/mem_backend_impl.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/sys_info.h"
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h"
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/cache_util.h"
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/mem_entry_impl.h"
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::Time;
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace {
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kDefaultCacheSize = 10 * 1024 * 1024;
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kCleanUpMargin = 1024 * 1024;
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint LowWaterAdjust(int high_water) {
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (high_water < kCleanUpMargin)
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return 0;
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return high_water - kCleanUpMargin;
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache {
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenMemBackendImpl::MemBackendImpl(net::NetLog* net_log)
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : max_size_(0), current_size_(0), net_log_(net_log) {}
333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
343f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenMemBackendImpl::~MemBackendImpl() {
353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EntryMap::iterator it = entries_.begin();
363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  while (it != entries_.end()) {
373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    it->second->Doom();
383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    it = entries_.begin();
393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(!current_size_);
413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Static.
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBackend* MemBackendImpl::CreateBackend(int max_bytes, net::NetLog* net_log) {
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MemBackendImpl* cache = new MemBackendImpl(net_log);
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  cache->SetMaxSize(max_bytes);
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (cache->Init())
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return cache;
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  delete cache;
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  LOG(ERROR) << "Unable to create cache";
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return NULL;
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::Init() {
5600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#ifndef ANDROID
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (max_size_)
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int64 total_memory = base::SysInfo::AmountOfPhysicalMemory();
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (total_memory <= 0) {
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    max_size_ = kDefaultCacheSize;
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We want to use up to 2% of the computer's memory, with a limit of 50 MB,
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // reached on systemd with more than 2.5 GB of RAM.
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  total_memory = total_memory * 2 / 100;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (total_memory > kDefaultCacheSize * 5)
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    max_size_ = kDefaultCacheSize * 5;
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  else
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    max_size_ = static_cast<int32>(total_memory);
7400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#else
7500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch  max_size_ = kDefaultCacheSize*3;
7600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#endif
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::SetMaxSize(int max_bytes) {
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  COMPILE_ASSERT(sizeof(max_bytes) == sizeof(max_size_), unsupported_int_model);
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (max_bytes < 0)
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Zero size means use the default.
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!max_bytes)
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return true;
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  max_size_ = max_bytes;
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MemBackendImpl::InternalDoomEntry(MemEntryImpl* entry) {
943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Only parent entries can be passed into this method.
953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DCHECK(entry->type() == MemEntryImpl::kParentEntry);
963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  rankings_.Remove(entry);
983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  EntryMap::iterator it = entries_.find(entry->GetKey());
993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (it != entries_.end())
1003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    entries_.erase(it);
1013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  else
1023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    NOTREACHED();
1033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  entry->InternalDoom();
1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MemBackendImpl::UpdateRank(MemEntryImpl* node) {
1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  rankings_.UpdateRank(node);
1093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MemBackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) {
1123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (old_size >= new_size)
1133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    SubstractStorageSize(old_size - new_size);
1143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  else
1153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    AddStorageSize(new_size - old_size);
1163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::MaxFileSize() const {
1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return max_size_ / 8;
1203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MemBackendImpl::InsertIntoRankingList(MemEntryImpl* entry) {
1233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  rankings_.Insert(entry);
1243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MemBackendImpl::RemoveFromRankingList(MemEntryImpl* entry) {
1273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  rankings_.Remove(entry);
1283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32 MemBackendImpl::GetEntryCount() const {
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return static_cast<int32>(entries_.size());
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::OpenEntry(const std::string& key, Entry** entry,
1353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                              CompletionCallback* callback) {
1363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (OpenEntry(key, entry))
1373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::CreateEntry(const std::string& key, Entry** entry,
1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                CompletionCallback* callback) {
1443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (CreateEntry(key, entry))
1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::DoomEntry(const std::string& key,
1513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                              CompletionCallback* callback) {
1523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (DoomEntry(key))
1533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::DoomAllEntries(CompletionCallback* callback) {
1593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (DoomAllEntries())
1603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::DoomEntriesBetween(const base::Time initial_time,
1663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                       const base::Time end_time,
1673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                       CompletionCallback* callback) {
1683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (DoomEntriesBetween(initial_time, end_time))
1693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::DoomEntriesSince(const base::Time initial_time,
1753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                     CompletionCallback* callback) {
1763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (DoomEntriesSince(initial_time))
1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint MemBackendImpl::OpenNextEntry(void** iter, Entry** next_entry,
1833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                  CompletionCallback* callback) {
1843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (OpenNextEntry(iter, next_entry))
1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return net::OK;
1863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return net::ERR_FAILED;
1883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid MemBackendImpl::EndEnumeration(void** iter) {
1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  *iter = NULL;
1923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
1933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::OpenEntry(const std::string& key, Entry** entry) {
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EntryMap::iterator it = entries_.find(key);
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (it == entries_.end())
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  it->second->Open();
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *entry = it->second;
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::CreateEntry(const std::string& key, Entry** entry) {
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  EntryMap::iterator it = entries_.find(key);
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (it != entries_.end())
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemEntryImpl* cache_entry = new MemEntryImpl(this);
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!cache_entry->CreateEntry(key, net_log_)) {
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    delete entry;
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  rankings_.Insert(cache_entry);
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entries_[key] = cache_entry;
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *entry = cache_entry;
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::DoomEntry(const std::string& key) {
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Entry* entry;
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (!OpenEntry(key, &entry))
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return false;
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Doom();
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  entry->Close();
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::DoomAllEntries() {
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  TrimCache(true);
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::DoomEntriesBetween(const Time initial_time,
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                        const Time end_time) {
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (end_time.is_null())
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return DoomEntriesSince(initial_time);
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(end_time >= initial_time);
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemEntryImpl* next = rankings_.GetNext(NULL);
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // rankings_ is ordered by last used, this will descend through the cache
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // and start dooming items before the end_time, and will stop once it reaches
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // an item used before the initial time.
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (next) {
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MemEntryImpl* node = next;
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    next = rankings_.GetNext(next);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (node->GetLastUsed() < initial_time)
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      break;
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (node->GetLastUsed() < end_time)
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      node->Doom();
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::DoomEntriesSince(const Time initial_time) {
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (;;) {
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Get the entry in the front.
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Entry* entry = rankings_.GetNext(NULL);
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Break the loop when there are no more entries or the entry is too old.
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!entry || entry->GetLastUsed() < initial_time)
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      return true;
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    entry->Doom();
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MemBackendImpl::OpenNextEntry(void** iter, Entry** next_entry) {
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemEntryImpl* current = reinterpret_cast<MemEntryImpl*>(*iter);
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemEntryImpl* node = rankings_.GetNext(current);
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We should never return a child entry so iterate until we hit a parent
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // entry.
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (node && node->type() != MemEntryImpl::kParentEntry) {
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    node = rankings_.GetNext(node);
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *next_entry = node;
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *iter = node;
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (node)
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    node->Open();
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return NULL != node;
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MemBackendImpl::TrimCache(bool empty) {
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  MemEntryImpl* next = rankings_.GetPrev(NULL);
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(next);
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int target_size = empty ? 0 : LowWaterAdjust(max_size_);
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (current_size_ > target_size && next) {
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MemEntryImpl* node = next;
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    next = rankings_.GetPrev(next);
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!node->InUse() || empty) {
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      node->Doom();
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return;
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MemBackendImpl::AddStorageSize(int32 bytes) {
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  current_size_ += bytes;
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(current_size_ >= 0);
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (current_size_ > max_size_)
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    TrimCache(false);
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MemBackendImpl::SubstractStorageSize(int32 bytes) {
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  current_size_ -= bytes;
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(current_size_ >= 0);
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace disk_cache
324