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