1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 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#ifndef NET_DISK_CACHE_MEM_ENTRY_IMPL_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_DISK_CACHE_MEM_ENTRY_IMPL_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/hash_tables.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/net_log.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest_prod.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemBackendImpl; 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class implements the Entry interface for the memory-only cache. An 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// object of this class represents a single entry on the cache. We use two 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// types of entries, parent and child to support sparse caching. 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A parent entry is non-sparse until a sparse method is invoked (i.e. 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ReadSparseData, WriteSparseData, GetAvailableRange) when sparse information 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is initialized. It then manages a list of child entries and delegates the 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// sparse API calls to the child entries. It creates and deletes child entries 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and updates the list when needed. 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A child entry is used to carry partial cache content, non-sparse methods like 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ReadData and WriteData cannot be applied to them. The lifetime of a child 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// entry is managed by the parent entry that created it except that the entry 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// can be evicted independently. A child entry does not have a key and it is not 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// registered in the backend's entry map. It is registered in the backend's 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ranking list to enable eviction of a partial content. 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A sparse entry has a fixed maximum size and can be partially filled. There 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// can only be one continous filled region in a sparse entry, as illustrated by 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the following example: 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// | xxx ooooo | 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// x = unfilled region 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// o = filled region 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// It is guranteed that there is at most one unfilled region and one filled 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// region, and the unfilled region (if there is one) is always before the filled 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// region. The book keeping for filled region in a sparse entry is done by using 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the variable |child_first_pos_| (inclusive). 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemEntryImpl : public Entry { 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum EntryType { 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kParentEntry, 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kChildEntry, 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit MemEntryImpl(MemBackendImpl* backend); 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Performs the initialization of a EntryImpl that will be added to the 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cache. 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool CreateEntry(const std::string& key, net::NetLog* net_log); 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Permanently destroys this entry. 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void InternalDoom(); 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Open(); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool InUse(); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemEntryImpl* next() const { 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return next_; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemEntryImpl* prev() const { 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return prev_; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_next(MemEntryImpl* next) { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_ = next; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_prev(MemEntryImpl* prev) { 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott prev_ = prev; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryType type() const { 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return parent_ ? kChildEntry : kParentEntry; 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string& key() { 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return key_; 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::BoundNetLog& net_log() { 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return net_log_; 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Entry interface. 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void Doom(); 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void Close(); 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual std::string GetKey() const; 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual base::Time GetLastUsed() const; 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual base::Time GetLastModified() const; 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int32 GetDataSize(int index) const; 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::CompletionCallback* completion_callback); 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::CompletionCallback* completion_callback, 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool truncate); 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::CompletionCallback* completion_callback); 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::CompletionCallback* completion_callback); 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int GetAvailableRange(int64 offset, int len, int64* start, 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CompletionCallback* callback); 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual bool CouldBeSparse() const; 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual void CancelSparseIO() {} 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual int ReadyForSparseIO(net::CompletionCallback* completion_callback); 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef base::hash_map<int, MemEntryImpl*> EntryMap; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NUM_STREAMS = 3 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~MemEntryImpl(); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Do all the work for corresponding public functions. Implemented as 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // separate functions to make logging of results simpler. 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int InternalReadData(int index, int offset, net::IOBuffer* buf, int buf_len); 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int InternalWriteData(int index, int offset, net::IOBuffer* buf, int buf_len, 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool truncate); 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int InternalReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len); 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int InternalWriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len); 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Old Entry interface. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int GetAvailableRange(int64 offset, int len, int64* start); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Grows and cleans up the data buffer. 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void PrepareTarget(int index, int offset, int buf_len); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Updates ranking information. 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void UpdateRank(bool modified); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Initializes the children map and sparse info. This method is only called 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // on a parent entry. 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool InitSparseInfo(); 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Performs the initialization of a MemEntryImpl as a child entry. 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |parent| is the pointer to the parent entry. |child_id| is the ID of 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the new child. 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool InitChildEntry(MemEntryImpl* parent, int child_id, net::NetLog* net_log); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns an entry responsible for |offset|. The returned entry can be a 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // child entry or this entry itself if |offset| points to the first range. 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If such entry does not exist and |create| is true, a new child entry is 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // created. 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemEntryImpl* OpenChild(int64 offset, bool create); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Finds the first child located within the range [|offset|, |offset + len|). 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns the number of bytes ahead of |offset| to reach the first available 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // bytes in the entry. The first child found is output to |child|. 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int FindNextChild(int64 offset, int len, MemEntryImpl** child); 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Removes child indexed by |child_id| from the children map. 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DetachChild(int child_id); 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string key_; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<char> data_[NUM_STREAMS]; // User data. 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 data_size_[NUM_STREAMS]; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ref_count_; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int child_id_; // The ID of a child entry. 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int child_first_pos_; // The position of the first byte in a child 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // entry. 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemEntryImpl* next_; // Pointers for the LRU list. 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemEntryImpl* prev_; 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemEntryImpl* parent_; // Pointer to the parent entry. 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<EntryMap> children_; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time last_modified_; // LRU information. 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time last_used_; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemBackendImpl* backend_; // Back pointer to the cache. 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool doomed_; // True if this entry was removed from the cache. 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::BoundNetLog net_log_; 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(MemEntryImpl); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace disk_cache 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_DISK_CACHE_MEM_ENTRY_IMPL_H_ 191