simple_entry_impl.h revision 58537e28ecd584eab876aee8be7156509866d23a
1// Copyright (c) 2013 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_SIMPLE_SIMPLE_ENTRY_IMPL_H_ 6#define NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_ 7 8#include <queue> 9#include <string> 10 11#include "base/files/file_path.h" 12#include "base/memory/ref_counted.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/memory/weak_ptr.h" 15#include "base/threading/thread_checker.h" 16#include "net/base/cache_type.h" 17#include "net/base/net_log.h" 18#include "net/disk_cache/disk_cache.h" 19#include "net/disk_cache/simple/simple_entry_format.h" 20#include "net/disk_cache/simple/simple_entry_operation.h" 21 22namespace base { 23class TaskRunner; 24} 25 26namespace net { 27class IOBuffer; 28} 29 30namespace disk_cache { 31 32class SimpleBackendImpl; 33class SimpleSynchronousEntry; 34struct SimpleEntryStat; 35struct SimpleEntryCreationResults; 36 37// SimpleEntryImpl is the IO thread interface to an entry in the very simple 38// disk cache. It proxies for the SimpleSynchronousEntry, which performs IO 39// on the worker thread. 40class SimpleEntryImpl : public Entry, public base::RefCounted<SimpleEntryImpl>, 41 public base::SupportsWeakPtr<SimpleEntryImpl> { 42 friend class base::RefCounted<SimpleEntryImpl>; 43 public: 44 enum OperationsMode { 45 NON_OPTIMISTIC_OPERATIONS, 46 OPTIMISTIC_OPERATIONS, 47 }; 48 49 SimpleEntryImpl(net::CacheType cache_type, 50 const base::FilePath& path, 51 uint64 entry_hash, 52 OperationsMode operations_mode, 53 SimpleBackendImpl* backend, 54 net::NetLog* net_log); 55 56 // Adds another reader/writer to this entry, if possible, returning |this| to 57 // |entry|. 58 int OpenEntry(Entry** entry, const CompletionCallback& callback); 59 60 // Creates this entry, if possible. Returns |this| to |entry|. 61 int CreateEntry(Entry** entry, const CompletionCallback& callback); 62 63 // Identical to Backend::Doom() except that it accepts a CompletionCallback. 64 int DoomEntry(const CompletionCallback& callback); 65 66 const std::string& key() const { return key_; } 67 uint64 entry_hash() const { return entry_hash_; } 68 void SetKey(const std::string& key); 69 70 // From Entry: 71 virtual void Doom() OVERRIDE; 72 virtual void Close() OVERRIDE; 73 virtual std::string GetKey() const OVERRIDE; 74 virtual base::Time GetLastUsed() const OVERRIDE; 75 virtual base::Time GetLastModified() const OVERRIDE; 76 virtual int32 GetDataSize(int index) const OVERRIDE; 77 virtual int ReadData(int stream_index, 78 int offset, 79 net::IOBuffer* buf, 80 int buf_len, 81 const CompletionCallback& callback) OVERRIDE; 82 virtual int WriteData(int stream_index, 83 int offset, 84 net::IOBuffer* buf, 85 int buf_len, 86 const CompletionCallback& callback, 87 bool truncate) OVERRIDE; 88 virtual int ReadSparseData(int64 offset, 89 net::IOBuffer* buf, 90 int buf_len, 91 const CompletionCallback& callback) OVERRIDE; 92 virtual int WriteSparseData(int64 offset, 93 net::IOBuffer* buf, 94 int buf_len, 95 const CompletionCallback& callback) OVERRIDE; 96 virtual int GetAvailableRange(int64 offset, 97 int len, 98 int64* start, 99 const CompletionCallback& callback) OVERRIDE; 100 virtual bool CouldBeSparse() const OVERRIDE; 101 virtual void CancelSparseIO() OVERRIDE; 102 virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE; 103 104 private: 105 class ScopedOperationRunner; 106 friend class ScopedOperationRunner; 107 108 enum State { 109 // The state immediately after construction, but before |synchronous_entry_| 110 // has been assigned. This is the state at construction, and is the only 111 // legal state to destruct an entry in. 112 STATE_UNINITIALIZED, 113 114 // This entry is available for regular IO. 115 STATE_READY, 116 117 // IO is currently in flight, operations must wait for completion before 118 // launching. 119 STATE_IO_PENDING, 120 121 // A failure occurred in the current or previous operation. All operations 122 // after that must fail, until we receive a Close(). 123 STATE_FAILURE, 124 }; 125 126 // Used in histograms, please only add entries at the end. 127 enum CheckCrcResult { 128 CRC_CHECK_NEVER_READ_TO_END = 0, 129 CRC_CHECK_NOT_DONE = 1, 130 CRC_CHECK_DONE = 2, 131 CRC_CHECK_NEVER_READ_AT_ALL = 3, 132 CRC_CHECK_MAX = 4, 133 }; 134 135 virtual ~SimpleEntryImpl(); 136 137 // Sets entry to STATE_UNINITIALIZED. 138 void MakeUninitialized(); 139 140 // Return this entry to a user of the API in |out_entry|. Increments the user 141 // count. 142 void ReturnEntryToCaller(Entry** out_entry); 143 144 // Ensures that |this| is no longer referenced by our |backend_|, this 145 // guarantees that this entry cannot have OpenEntry/CreateEntry called again. 146 void RemoveSelfFromBackend(); 147 148 // An error occured, and the SimpleSynchronousEntry should have Doomed 149 // us at this point. We need to remove |this| from the Backend and the 150 // index. 151 void MarkAsDoomed(); 152 153 // Runs the next operation in the queue, if any and if there is no other 154 // operation running at the moment. 155 // WARNING: May delete |this|, as an operation in the queue can contain 156 // the last reference. 157 void RunNextOperationIfNeeded(); 158 159 void OpenEntryInternal(bool have_index, 160 const CompletionCallback& callback, 161 Entry** out_entry); 162 163 void CreateEntryInternal(bool have_index, 164 const CompletionCallback& callback, 165 Entry** out_entry); 166 167 void CloseInternal(); 168 169 void ReadDataInternal(int index, 170 int offset, 171 net::IOBuffer* buf, 172 int buf_len, 173 const CompletionCallback& callback); 174 175 void WriteDataInternal(int index, 176 int offset, 177 net::IOBuffer* buf, 178 int buf_len, 179 const CompletionCallback& callback, 180 bool truncate); 181 182 void DoomEntryInternal(const CompletionCallback& callback); 183 184 // Called after a SimpleSynchronousEntry has completed CreateEntry() or 185 // OpenEntry(). If |in_sync_entry| is non-NULL, creation is successful and we 186 // can return |this| SimpleEntryImpl to |*out_entry|. Runs 187 // |completion_callback|. 188 void CreationOperationComplete( 189 const CompletionCallback& completion_callback, 190 const base::TimeTicks& start_time, 191 scoped_ptr<SimpleEntryCreationResults> in_results, 192 Entry** out_entry, 193 net::NetLog::EventType end_event_type); 194 195 // Called after we've closed and written the EOF record to our entry. Until 196 // this point it hasn't been safe to OpenEntry() the same entry, but from this 197 // point it is. 198 void CloseOperationComplete(); 199 200 // Internal utility method used by other completion methods. Calls 201 // |completion_callback| after updating state and dooming on errors. 202 void EntryOperationComplete(int stream_index, 203 const CompletionCallback& completion_callback, 204 const SimpleEntryStat& entry_stat, 205 scoped_ptr<int> result); 206 207 // Called after an asynchronous read. Updates |crc32s_| if possible. 208 void ReadOperationComplete(int stream_index, 209 int offset, 210 const CompletionCallback& completion_callback, 211 scoped_ptr<uint32> read_crc32, 212 scoped_ptr<base::Time> last_used, 213 scoped_ptr<int> result); 214 215 // Called after an asynchronous write completes. 216 void WriteOperationComplete(int stream_index, 217 const CompletionCallback& completion_callback, 218 scoped_ptr<SimpleEntryStat> entry_stat, 219 scoped_ptr<int> result); 220 221 // Called after an asynchronous doom completes. 222 void DoomOperationComplete(const CompletionCallback& callback, 223 State state_to_restore, 224 int result); 225 226 // Called after validating the checksums on an entry. Passes through the 227 // original result if successful, propogates the error if the checksum does 228 // not validate. 229 void ChecksumOperationComplete( 230 int stream_index, 231 int orig_result, 232 const CompletionCallback& completion_callback, 233 scoped_ptr<int> result); 234 235 // Called after completion of asynchronous IO and receiving file metadata for 236 // the entry in |entry_stat|. Updates the metadata in the entry and in the 237 // index to make them available on next IO operations. 238 void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat); 239 240 int64 GetDiskUsage() const; 241 242 // Used to report histograms. 243 void RecordReadIsParallelizable(const SimpleEntryOperation& operation) const; 244 void RecordWriteDependencyType(const SimpleEntryOperation& operation) const; 245 246 // All nonstatic SimpleEntryImpl methods should always be called on the IO 247 // thread, in all cases. |io_thread_checker_| documents and enforces this. 248 base::ThreadChecker io_thread_checker_; 249 250 const base::WeakPtr<SimpleBackendImpl> backend_; 251 const net::CacheType cache_type_; 252 const scoped_refptr<base::TaskRunner> worker_pool_; 253 const base::FilePath path_; 254 const uint64 entry_hash_; 255 const bool use_optimistic_operations_; 256 std::string key_; 257 258 // |last_used_|, |last_modified_| and |data_size_| are copied from the 259 // synchronous entry at the completion of each item of asynchronous IO. 260 // TODO(clamy): Unify last_used_ with data in the index. 261 base::Time last_used_; 262 base::Time last_modified_; 263 int32 data_size_[kSimpleEntryFileCount]; 264 265 // Number of times this object has been returned from Backend::OpenEntry() and 266 // Backend::CreateEntry() without subsequent Entry::Close() calls. Used to 267 // notify the backend when this entry not used by any callers. 268 int open_count_; 269 270 bool doomed_; 271 272 State state_; 273 274 // When possible, we compute a crc32, for the data in each entry as we read or 275 // write. For each stream, |crc32s_[index]| is the crc32 of that stream from 276 // [0 .. |crc32s_end_offset_|). If |crc32s_end_offset_[index] == 0| then the 277 // value of |crc32s_[index]| is undefined. 278 int32 crc32s_end_offset_[kSimpleEntryFileCount]; 279 uint32 crc32s_[kSimpleEntryFileCount]; 280 281 // If |have_written_[index]| is true, we have written to the stream |index|. 282 bool have_written_[kSimpleEntryFileCount]; 283 284 // Reflects how much CRC checking has been done with the entry. This state is 285 // reported on closing each entry stream. 286 CheckCrcResult crc_check_state_[kSimpleEntryFileCount]; 287 288 // The |synchronous_entry_| is the worker thread object that performs IO on 289 // entries. It's owned by this SimpleEntryImpl whenever |executing_operation_| 290 // is false (i.e. when an operation is not pending on the worker pool). When 291 // an operation is being executed no one owns the synchronous entry. Therefore 292 // SimpleEntryImpl should not be deleted while an operation is running as that 293 // would leak the SimpleSynchronousEntry. 294 SimpleSynchronousEntry* synchronous_entry_; 295 296 std::queue<SimpleEntryOperation> pending_operations_; 297 298 net::BoundNetLog net_log_; 299 300 scoped_ptr<SimpleEntryOperation> executing_operation_; 301}; 302 303} // namespace disk_cache 304 305#endif // NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_ 306