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