summaryrefslogtreecommitdiff
path: root/chromium/net/disk_cache/v3/sparse_control_v3.h
blob: 8455ad724b59b4e71574b0b853b62feb7252c86e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_DISK_CACHE_SPARSE_CONTROL_H_
#define NET_DISK_CACHE_SPARSE_CONTROL_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "net/base/completion_callback.h"
#include "net/disk_cache/bitmap.h"
#include "net/disk_cache/disk_format.h"

namespace net {
class IOBuffer;
class DrainableIOBuffer;
}

namespace disk_cache {

class Entry;
class EntryImpl;

// This class provides support for the sparse capabilities of the disk cache.
// Basically, sparse IO is directed from EntryImpl to this class, and we split
// the operation into multiple small pieces, sending each one to the
// appropriate entry. An instance of this class is asociated with each entry
// used directly for sparse operations (the entry passed in to the constructor).
class SparseControl {
 public:
  typedef net::CompletionCallback CompletionCallback;

  // The operation to perform.
  enum SparseOperation {
    kNoOperation,
    kReadOperation,
    kWriteOperation,
    kGetRangeOperation
  };

  explicit SparseControl(EntryImpl* entry);
  ~SparseControl();

  // Performs a quick test to see if the entry is sparse or not, without
  // generating disk IO (so the answer provided is only a best effort).
  bool CouldBeSparse() const;

  // Performs an actual sparse read or write operation for this entry. |op| is
  // the operation to perform, |offset| is the desired sparse offset, |buf| and
  // |buf_len| specify the actual data to use and |callback| is the callback
  // to use for asynchronous operations. See the description of the Read /
  // WriteSparseData for details about the arguments. The return value is the
  // number of bytes read or written, or a net error code.
  int StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
              int buf_len, const CompletionCallback& callback);

  // Implements Entry::GetAvailableRange().
  int GetAvailableRange(int64 offset, int len, int64* start);

  // Cancels the current sparse operation (if any).
  void CancelIO();

  // Returns OK if the entry can be used for new IO or ERR_IO_PENDING if we are
  // busy. If the entry is busy, we'll invoke the callback when we are ready
  // again. See disk_cache::Entry::ReadyToUse() for more info.
  int ReadyToUse(const CompletionCallback& completion_callback);

  // Deletes the children entries of |entry|.
  static void DeleteChildren(EntryImpl* entry);

 private:
  // Initializes the object for the current entry. If this entry already stores
  // sparse data, or can be used to do it, it updates the relevant information
  // on disk and returns net::OK. Otherwise it returns a net error code.
  int Init();

  // Creates a new sparse entry or opens an aready created entry from disk.
  // These methods just read / write the required info from disk for the current
  // entry, and verify that everything is correct. The return value is a net
  // error code.
  int CreateSparseEntry();
  int OpenSparseEntry(int data_len);

  // Opens and closes a child entry. A child entry is a regular EntryImpl object
  // with a key derived from the key of the resource to store and the range
  // stored by that child.
  bool OpenChild();
  void CloseChild();

  // Continues the current operation (open) without a current child.
  bool ContinueWithoutChild(const std::string& key);

    // Writes to disk the tracking information for this entry.
  void WriteSparseData();

  // Performs a single operation with the current child. Returns true when we
  // should move on to the next child and false when we should interrupt our
  // work.
  bool DoChildIO();

  // Performs the required work after a single IO operations finishes.
  void DoChildIOCompleted(int result);

  std::string GenerateChildKey();

  // Deletes the current child and continues the current operation (open).
  bool KillChildAndContinue(const std::string& key, bool fatal);

  // Returns true if the required child is tracked by the parent entry, i.e. it
  // was already created.
  bool ChildPresent();

  // Sets the bit for the current child to the provided |value|. In other words,
  // starts or stops tracking this child.
  void SetChildBit(bool value);

  // Verify that the range to be accessed for the current child is appropriate.
  // Returns false if an error is detected or there is no need to perform the
  // current IO operation (for instance if the required range is not stored by
  // the child).
  bool VerifyRange();

  // Updates the contents bitmap for the current range, based on the result of
  // the current operation.
  void UpdateRange(int result);

  // Returns the number of bytes stored at |block_index|, if its allocation-bit
  // is off (because it is not completely filled).
  int PartialBlockLength(int block_index) const;

  // Initializes the sparse info for the current child.
  void InitChildData();

  // Performs the required work for GetAvailableRange for one child.
  int DoGetAvailableRange();

  // Reports to the user that we are done.
  void DoUserCallback();
  void DoAbortCallbacks();

  // Invoked by the callback of asynchronous operations.
  void OnChildIOCompleted(int result);

  EntryImpl* entry_;  // The sparse entry.
  EntryImpl* child_;  // The current child entry.
  SparseOperation operation_;
  bool pending_;  // True if any child IO operation returned pending.
  bool finished_;
  bool init_;
  bool range_found_;  // True if GetAvailableRange found something.
  bool abort_;  // True if we should abort the current operation ASAP.

  SparseHeader sparse_header_;  // Data about the children of entry_.
  Bitmap children_map_;  // The actual bitmap of children.
  SparseData child_data_;  // Parent and allocation map of child_.
  Bitmap child_map_;  // The allocation map as a bitmap.

  CompletionCallback user_callback_;
  std::vector<CompletionCallback> abort_callbacks_;
  int64 offset_;  // Current sparse offset.
  scoped_refptr<net::DrainableIOBuffer> user_buf_;
  int buf_len_;  // Bytes to read or write.
  int child_offset_;  // Offset to use for the current child.
  int child_len_;  // Bytes to read or write for this child.
  int result_;

  DISALLOW_COPY_AND_ASSIGN(SparseControl);
};

}  // namespace disk_cache

#endif  // NET_DISK_CACHE_SPARSE_CONTROL_H_