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 // Logs a begin event and enables logging for the EntryImpl. Will also cause 159 // an end event to be logged on destruction. The EntryImpl must have its key 160 // initialized before this is called. |created| is true if the Entry was 161 // created rather than opened. 162 void BeginLogging(net::NetLog* net_log, bool created); 163 164 const net::NetLogWithSource& net_log() const; 165 166 // Returns the number of blocks needed to store an EntryStore. 167 static int NumBlocksForEntry(int key_size); 168 169 // Entry interface. 170 void Doom() override; 171 void Close() override; 172 std::string GetKey() const override; 173 base::Time GetLastUsed() const override; 174 base::Time GetLastModified() const override; 175 int32_t GetDataSize(int index) const override; 176 int ReadData(int index, 177 int offset, 178 IOBuffer* buf, 179 int buf_len, 180 CompletionOnceCallback callback) override; 181 int WriteData(int index, 182 int offset, 183 IOBuffer* buf, 184 int buf_len, 185 CompletionOnceCallback callback, 186 bool truncate) override; 187 int ReadSparseData(int64_t offset, 188 IOBuffer* buf, 189 int buf_len, 190 CompletionOnceCallback callback) override; 191 int WriteSparseData(int64_t offset, 192 IOBuffer* buf, 193 int buf_len, 194 CompletionOnceCallback callback) override; 195 RangeResult GetAvailableRange(int64_t offset, 196 int len, 197 RangeResultCallback callback) override; 198 bool CouldBeSparse() const override; 199 void CancelSparseIO() override; 200 net::Error ReadyForSparseIO(CompletionOnceCallback callback) override; 201 void SetLastUsedTimeForTest(base::Time time) override; 202 203 private: 204 enum { 205 kNumStreams = 3 206 }; 207 class UserBuffer; 208 209 ~EntryImpl() override; 210 211 // Do all the work for ReadDataImpl and WriteDataImpl. Implemented as 212 // separate functions to make logging of results simpler. 213 int InternalReadData(int index, 214 int offset, 215 IOBuffer* buf, 216 int buf_len, 217 CompletionOnceCallback callback); 218 int InternalWriteData(int index, 219 int offset, 220 IOBuffer* buf, 221 int buf_len, 222 CompletionOnceCallback callback, 223 bool truncate); 224 225 // Initializes the storage for an internal or external data block. 226 bool CreateDataBlock(int index, int size); 227 228 // Initializes the storage for an internal or external generic block. 229 bool CreateBlock(int size, Addr* address); 230 231 // Deletes the data pointed by address, maybe backed by files_[index]. 232 // Note that most likely the caller should delete (and store) the reference to 233 // |address| *before* calling this method because we don't want to have an 234 // entry using an address that is already free. 235 void DeleteData(Addr address, int index); 236 237 // Updates ranking information. 238 void UpdateRank(bool modified); 239 240 // Returns a pointer to the file that stores the given address. 241 File* GetBackingFile(Addr address, int index); 242 243 // Returns a pointer to the file that stores external data. 244 File* GetExternalFile(Addr address, int index); 245 246 // Prepares the target file or buffer for a write of buf_len bytes at the 247 // given offset. 248 bool PrepareTarget(int index, int offset, int buf_len, bool truncate); 249 250 // Adjusts the internal buffer and file handle for a write that truncates this 251 // stream. 252 bool HandleTruncation(int index, int offset, int buf_len); 253 254 // Copies data from disk to the internal buffer. 255 bool CopyToLocalBuffer(int index); 256 257 // Reads from a block data file to this object's memory buffer. 258 bool MoveToLocalBuffer(int index); 259 260 // Loads the external file to this object's memory buffer. 261 bool ImportSeparateFile(int index, int new_size); 262 263 // Makes sure that the internal buffer can handle the a write of |buf_len| 264 // bytes to |offset|. 265 bool PrepareBuffer(int index, int offset, int buf_len); 266 267 // Flushes the in-memory data to the backing storage. The data destination 268 // is determined based on the current data length and |min_len|. 269 bool Flush(int index, int min_len); 270 271 // Updates the size of a given data stream. 272 void UpdateSize(int index, int old_size, int new_size); 273 274 // Initializes the sparse control object. Returns a net error code. 275 int InitSparseData(); 276 277 // Adds the provided |flags| to the current EntryFlags for this entry. 278 void SetEntryFlags(uint32_t flags); 279 280 // Returns the current EntryFlags for this entry. 281 uint32_t GetEntryFlags(); 282 283 // Gets the data stored at the given index. If the information is in memory, 284 // a buffer will be allocated and the data will be copied to it (the caller 285 // can find out the size of the buffer before making this call). Otherwise, 286 // the cache address of the data will be returned, and that address will be 287 // removed from the regular book keeping of this entry so the caller is 288 // responsible for deleting the block (or file) from the backing store at some 289 // point; there is no need to report any storage-size change, only to do the 290 // actual cleanup. 291 void GetData(int index, std::unique_ptr<char[]>* buffer, Addr* address); 292 293 // |net_log_| should be early since some field destructors (at least 294 // ~SparseControl) can touch it. 295 net::NetLogWithSource net_log_; 296 CacheEntryBlock entry_; // Key related information for this entry. 297 CacheRankingsBlock node_; // Rankings related information for this entry. 298 base::WeakPtr<BackendImpl> backend_; // Back pointer to the cache. 299 base::WeakPtr<InFlightBackendIO> background_queue_; // In-progress queue. 300 std::unique_ptr<UserBuffer> user_buffers_[kNumStreams]; // Stores user data. 301 // Files to store external user data and key. 302 scoped_refptr<File> files_[kNumStreams + 1]; 303 mutable std::string key_; // Copy of the key. 304 // Bytes not reported yet to the backend. 305 int unreported_size_[kNumStreams] = {}; 306 bool doomed_ = false; // True if this entry was removed from the cache. 307 bool read_only_; // True if not yet writing. 308 bool dirty_ = false; // True if we detected that this is a dirty entry. 309 std::unique_ptr<SparseControl> sparse_; // Support for sparse entries. 310 }; 311 312 } // namespace disk_cache 313 314 #endif // NET_DISK_CACHE_BLOCKFILE_ENTRY_IMPL_H_ 315