1 // Copyright 2012 The Chromium Authors 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_BLOCKFILE_ENTRY_IMPL_H_ 6 #define NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <string> 12 13 #include "net/base/net_export.h" 14 #include "net/disk_cache/blockfile/disk_format.h" 15 #include "net/disk_cache/blockfile/storage_block-inl.h" 16 #include "net/disk_cache/blockfile/storage_block.h" 17 #include "net/disk_cache/disk_cache.h" 18 #include "net/log/net_log_with_source.h" 19 20 namespace net { 21 class NetLog; 22 } 23 24 namespace disk_cache { 25 26 class BackendImpl; 27 class InFlightBackendIO; 28 class SparseControl; 29 typedef StorageBlock<EntryStore> CacheEntryBlock; 30 typedef StorageBlock<RankingsNode> CacheRankingsBlock; 31 32 // This class implements the Entry interface. An object of this 33 // class represents a single entry on the cache. 34 class NET_EXPORT_PRIVATE EntryImpl 35 : public Entry, 36 public base::RefCounted<EntryImpl> { 37 friend class base::RefCounted<EntryImpl>; 38 friend class SparseControl; 39 public: 40 enum Operation { 41 kRead, 42 kWrite, 43 kSparseRead, 44 kSparseWrite, 45 kAsyncIO, 46 kReadAsync1, 47 kWriteAsync1 48 }; 49 50 EntryImpl(BackendImpl* backend, Addr address, bool read_only); 51 52 EntryImpl(const EntryImpl&) = delete; 53 EntryImpl& operator=(const EntryImpl&) = delete; 54 55 // Background implementation of the Entry interface. 56 void DoomImpl(); 57 int ReadDataImpl(int index, 58 int offset, 59 IOBuffer* buf, 60 int buf_len, 61 CompletionOnceCallback callback); 62 int WriteDataImpl(int index, 63 int offset, 64 IOBuffer* buf, 65 int buf_len, 66 CompletionOnceCallback callback, 67 bool truncate); 68 int ReadSparseDataImpl(int64_t offset, 69 IOBuffer* buf, 70 int buf_len, 71 CompletionOnceCallback callback); 72 int WriteSparseDataImpl(int64_t offset, 73 IOBuffer* buf, 74 int buf_len, 75 CompletionOnceCallback callback); 76 RangeResult GetAvailableRangeImpl(int64_t offset, int len); 77 void CancelSparseIOImpl(); 78 int ReadyForSparseIOImpl(CompletionOnceCallback callback); 79 entry()80 inline CacheEntryBlock* entry() { 81 return &entry_; 82 } 83 rankings()84 inline CacheRankingsBlock* rankings() { 85 return &node_; 86 } 87 88 uint32_t GetHash(); 89 90 // Performs the initialization of a EntryImpl that will be added to the 91 // cache. 92 bool CreateEntry(Addr node_address, const std::string& key, uint32_t hash); 93 94 // Returns true if this entry matches the lookup arguments. 95 bool IsSameEntry(const std::string& key, uint32_t hash); 96 97 // Permamently destroys this entry. 98 void InternalDoom(); 99 100 // Deletes this entry from disk. If |everything| is false, only the user data 101 // will be removed, leaving the key and control data intact. 102 void DeleteEntryData(bool everything); 103 104 // Returns the address of the next entry on the list of entries with the same 105 // hash. 106 CacheAddr GetNextAddress(); 107 108 // Sets the address of the next entry on the list of entries with the same 109 // hash. 110 void SetNextAddress(Addr address); 111 112 // Reloads the rankings node information. 113 bool LoadNodeAddress(); 114 115 // Updates the stored data to reflect the run-time information for this entry. 116 // Returns false if the data could not be updated. The purpose of this method 117 // is to be able to detect entries that are currently in use. 118 bool Update(); 119 dirty()120 bool dirty() { 121 return dirty_; 122 } 123 doomed()124 bool doomed() { 125 return doomed_; 126 } 127 128 // Marks this entry as dirty (in memory) if needed. This is intended only for 129 // entries that are being read from disk, to be called during loading. 130 void SetDirtyFlag(int32_t current_id); 131 132 // Fixes this entry so it can be treated as valid (to delete it). 133 void SetPointerForInvalidEntry(int32_t new_id); 134 135 // Returns true if this entry is so meesed up that not everything is going to 136 // be removed. 137 bool LeaveRankingsBehind(); 138 139 // Returns false if the entry is clearly invalid. 140 bool SanityCheck(); 141 bool DataSanityCheck(); 142 143 // Attempts to make this entry reachable though the key. 144 void FixForDelete(); 145 146 // Handle the pending asynchronous IO count. 147 void IncrementIoCount(); 148 void DecrementIoCount(); 149 150 // This entry is being returned to the user. It is always called from the 151 // primary thread (not the dedicated cache thread). 152 void OnEntryCreated(BackendImpl* backend); 153 154 // Set the access times for this entry. This method provides support for 155 // the upgrade tool. 156 void SetTimes(base::Time last_used, base::Time last_modified); 157 158 // Generates a histogram for the time spent working on this operation. 159 void ReportIOTime(Operation op, const base::TimeTicks& start); 160 161 // Logs a begin event and enables logging for the EntryImpl. Will also cause 162 // an end event to be logged on destruction. The EntryImpl must have its key 163 // initialized before this is called. |created| is true if the Entry was 164 // created rather than opened. 165 void BeginLogging(net::NetLog* net_log, bool created); 166 167 const net::NetLogWithSource& net_log() const; 168 169 // Returns the number of blocks needed to store an EntryStore. 170 static int NumBlocksForEntry(int key_size); 171 172 // Entry interface. 173 void Doom() override; 174 void Close() override; 175 std::string GetKey() const override; 176 base::Time GetLastUsed() const override; 177 base::Time GetLastModified() const override; 178 int32_t GetDataSize(int index) const override; 179 int ReadData(int index, 180 int offset, 181 IOBuffer* buf, 182 int buf_len, 183 CompletionOnceCallback callback) override; 184 int WriteData(int index, 185 int offset, 186 IOBuffer* buf, 187 int buf_len, 188 CompletionOnceCallback callback, 189 bool truncate) override; 190 int ReadSparseData(int64_t offset, 191 IOBuffer* buf, 192 int buf_len, 193 CompletionOnceCallback callback) override; 194 int WriteSparseData(int64_t offset, 195 IOBuffer* buf, 196 int buf_len, 197 CompletionOnceCallback callback) override; 198 RangeResult GetAvailableRange(int64_t offset, 199 int len, 200 RangeResultCallback callback) override; 201 bool CouldBeSparse() const override; 202 void CancelSparseIO() override; 203 net::Error ReadyForSparseIO(CompletionOnceCallback callback) override; 204 void SetLastUsedTimeForTest(base::Time time) override; 205 206 private: 207 enum { 208 kNumStreams = 3 209 }; 210 class UserBuffer; 211 212 ~EntryImpl() override; 213 214 // Do all the work for ReadDataImpl and WriteDataImpl. Implemented as 215 // separate functions to make logging of results simpler. 216 int InternalReadData(int index, 217 int offset, 218 IOBuffer* buf, 219 int buf_len, 220 CompletionOnceCallback callback); 221 int InternalWriteData(int index, 222 int offset, 223 IOBuffer* buf, 224 int buf_len, 225 CompletionOnceCallback callback, 226 bool truncate); 227 228 // Initializes the storage for an internal or external data block. 229 bool CreateDataBlock(int index, int size); 230 231 // Initializes the storage for an internal or external generic block. 232 bool CreateBlock(int size, Addr* address); 233 234 // Deletes the data pointed by address, maybe backed by files_[index]. 235 // Note that most likely the caller should delete (and store) the reference to 236 // |address| *before* calling this method because we don't want to have an 237 // entry using an address that is already free. 238 void DeleteData(Addr address, int index); 239 240 // Updates ranking information. 241 void UpdateRank(bool modified); 242 243 // Returns a pointer to the file that stores the given address. 244 File* GetBackingFile(Addr address, int index); 245 246 // Returns a pointer to the file that stores external data. 247 File* GetExternalFile(Addr address, int index); 248 249 // Prepares the target file or buffer for a write of buf_len bytes at the 250 // given offset. 251 bool PrepareTarget(int index, int offset, int buf_len, bool truncate); 252 253 // Adjusts the internal buffer and file handle for a write that truncates this 254 // stream. 255 bool HandleTruncation(int index, int offset, int buf_len); 256 257 // Copies data from disk to the internal buffer. 258 bool CopyToLocalBuffer(int index); 259 260 // Reads from a block data file to this object's memory buffer. 261 bool MoveToLocalBuffer(int index); 262 263 // Loads the external file to this object's memory buffer. 264 bool ImportSeparateFile(int index, int new_size); 265 266 // Makes sure that the internal buffer can handle the a write of |buf_len| 267 // bytes to |offset|. 268 bool PrepareBuffer(int index, int offset, int buf_len); 269 270 // Flushes the in-memory data to the backing storage. The data destination 271 // is determined based on the current data length and |min_len|. 272 bool Flush(int index, int min_len); 273 274 // Updates the size of a given data stream. 275 void UpdateSize(int index, int old_size, int new_size); 276 277 // Initializes the sparse control object. Returns a net error code. 278 int InitSparseData(); 279 280 // Adds the provided |flags| to the current EntryFlags for this entry. 281 void SetEntryFlags(uint32_t flags); 282 283 // Returns the current EntryFlags for this entry. 284 uint32_t GetEntryFlags(); 285 286 // Gets the data stored at the given index. If the information is in memory, 287 // a buffer will be allocated and the data will be copied to it (the caller 288 // can find out the size of the buffer before making this call). Otherwise, 289 // the cache address of the data will be returned, and that address will be 290 // removed from the regular book keeping of this entry so the caller is 291 // responsible for deleting the block (or file) from the backing store at some 292 // point; there is no need to report any storage-size change, only to do the 293 // actual cleanup. 294 void GetData(int index, std::unique_ptr<char[]>* buffer, Addr* address); 295 296 // |net_log_| should be early since some field destructors (at least 297 // ~SparseControl) can touch it. 298 net::NetLogWithSource net_log_; 299 CacheEntryBlock entry_; // Key related information for this entry. 300 CacheRankingsBlock node_; // Rankings related information for this entry. 301 base::WeakPtr<BackendImpl> backend_; // Back pointer to the cache. 302 base::WeakPtr<InFlightBackendIO> background_queue_; // In-progress queue. 303 std::unique_ptr<UserBuffer> user_buffers_[kNumStreams]; // Stores user data. 304 // Files to store external user data and key. 305 scoped_refptr<File> files_[kNumStreams + 1]; 306 mutable std::string key_; // Copy of the key. 307 // Bytes not reported yet to the backend. 308 int unreported_size_[kNumStreams] = {}; 309 bool doomed_ = false; // True if this entry was removed from the cache. 310 bool read_only_; // True if not yet writing. 311 bool dirty_ = false; // True if we detected that this is a dirty entry. 312 std::unique_ptr<SparseControl> sparse_; // Support for sparse entries. 313 }; 314 315 } // namespace disk_cache 316 317 #endif // NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_H_ 318