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_BLOCKFILE_SPARSE_CONTROL_V3_H_ 6#define NET_DISK_CACHE_BLOCKFILE_SPARSE_CONTROL_V3_H_ 7 8#include <string> 9#include <vector> 10 11#include "base/basictypes.h" 12#include "base/compiler_specific.h" 13#include "net/base/completion_callback.h" 14#include "net/disk_cache/blockfile/bitmap.h" 15#include "net/disk_cache/disk_format.h" 16 17namespace net { 18class IOBuffer; 19class DrainableIOBuffer; 20} 21 22namespace disk_cache { 23 24class Entry; 25class EntryImpl; 26 27// This class provides support for the sparse capabilities of the disk cache. 28// Basically, sparse IO is directed from EntryImpl to this class, and we split 29// the operation into multiple small pieces, sending each one to the 30// appropriate entry. An instance of this class is asociated with each entry 31// used directly for sparse operations (the entry passed in to the constructor). 32class SparseControl { 33 public: 34 typedef net::CompletionCallback CompletionCallback; 35 36 // The operation to perform. 37 enum SparseOperation { 38 kNoOperation, 39 kReadOperation, 40 kWriteOperation, 41 kGetRangeOperation 42 }; 43 44 explicit SparseControl(EntryImpl* entry); 45 ~SparseControl(); 46 47 // Performs a quick test to see if the entry is sparse or not, without 48 // generating disk IO (so the answer provided is only a best effort). 49 bool CouldBeSparse() const; 50 51 // Performs an actual sparse read or write operation for this entry. |op| is 52 // the operation to perform, |offset| is the desired sparse offset, |buf| and 53 // |buf_len| specify the actual data to use and |callback| is the callback 54 // to use for asynchronous operations. See the description of the Read / 55 // WriteSparseData for details about the arguments. The return value is the 56 // number of bytes read or written, or a net error code. 57 int StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf, 58 int buf_len, const CompletionCallback& callback); 59 60 // Implements Entry::GetAvailableRange(). 61 int GetAvailableRange(int64 offset, int len, int64* start); 62 63 // Cancels the current sparse operation (if any). 64 void CancelIO(); 65 66 // Returns OK if the entry can be used for new IO or ERR_IO_PENDING if we are 67 // busy. If the entry is busy, we'll invoke the callback when we are ready 68 // again. See disk_cache::Entry::ReadyToUse() for more info. 69 int ReadyToUse(const CompletionCallback& completion_callback); 70 71 // Deletes the children entries of |entry|. 72 static void DeleteChildren(EntryImpl* entry); 73 74 private: 75 // Initializes the object for the current entry. If this entry already stores 76 // sparse data, or can be used to do it, it updates the relevant information 77 // on disk and returns net::OK. Otherwise it returns a net error code. 78 int Init(); 79 80 // Creates a new sparse entry or opens an aready created entry from disk. 81 // These methods just read / write the required info from disk for the current 82 // entry, and verify that everything is correct. The return value is a net 83 // error code. 84 int CreateSparseEntry(); 85 int OpenSparseEntry(int data_len); 86 87 // Opens and closes a child entry. A child entry is a regular EntryImpl object 88 // with a key derived from the key of the resource to store and the range 89 // stored by that child. 90 bool OpenChild(); 91 void CloseChild(); 92 93 // Continues the current operation (open) without a current child. 94 bool ContinueWithoutChild(const std::string& key); 95 96 // Writes to disk the tracking information for this entry. 97 void WriteSparseData(); 98 99 // Performs a single operation with the current child. Returns true when we 100 // should move on to the next child and false when we should interrupt our 101 // work. 102 bool DoChildIO(); 103 104 // Performs the required work after a single IO operations finishes. 105 void DoChildIOCompleted(int result); 106 107 std::string GenerateChildKey(); 108 109 // Deletes the current child and continues the current operation (open). 110 bool KillChildAndContinue(const std::string& key, bool fatal); 111 112 // Returns true if the required child is tracked by the parent entry, i.e. it 113 // was already created. 114 bool ChildPresent(); 115 116 // Sets the bit for the current child to the provided |value|. In other words, 117 // starts or stops tracking this child. 118 void SetChildBit(bool value); 119 120 // Verify that the range to be accessed for the current child is appropriate. 121 // Returns false if an error is detected or there is no need to perform the 122 // current IO operation (for instance if the required range is not stored by 123 // the child). 124 bool VerifyRange(); 125 126 // Updates the contents bitmap for the current range, based on the result of 127 // the current operation. 128 void UpdateRange(int result); 129 130 // Returns the number of bytes stored at |block_index|, if its allocation-bit 131 // is off (because it is not completely filled). 132 int PartialBlockLength(int block_index) const; 133 134 // Initializes the sparse info for the current child. 135 void InitChildData(); 136 137 // Performs the required work for GetAvailableRange for one child. 138 int DoGetAvailableRange(); 139 140 // Reports to the user that we are done. 141 void DoUserCallback(); 142 void DoAbortCallbacks(); 143 144 // Invoked by the callback of asynchronous operations. 145 void OnChildIOCompleted(int result); 146 147 EntryImpl* entry_; // The sparse entry. 148 EntryImpl* child_; // The current child entry. 149 SparseOperation operation_; 150 bool pending_; // True if any child IO operation returned pending. 151 bool finished_; 152 bool init_; 153 bool range_found_; // True if GetAvailableRange found something. 154 bool abort_; // True if we should abort the current operation ASAP. 155 156 SparseHeader sparse_header_; // Data about the children of entry_. 157 Bitmap children_map_; // The actual bitmap of children. 158 SparseData child_data_; // Parent and allocation map of child_. 159 Bitmap child_map_; // The allocation map as a bitmap. 160 161 CompletionCallback user_callback_; 162 std::vector<CompletionCallback> abort_callbacks_; 163 int64 offset_; // Current sparse offset. 164 scoped_refptr<net::DrainableIOBuffer> user_buf_; 165 int buf_len_; // Bytes to read or write. 166 int child_offset_; // Offset to use for the current child. 167 int child_len_; // Bytes to read or write for this child. 168 int result_; 169 170 DISALLOW_COPY_AND_ASSIGN(SparseControl); 171}; 172 173} // namespace disk_cache 174 175#endif // NET_DISK_CACHE_BLOCKFILE_SPARSE_CONTROL_V3_H_ 176