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_ENTRY_IMPL_H_
6#define NET_DISK_CACHE_ENTRY_IMPL_H_
7
8#include "base/memory/scoped_ptr.h"
9#include "net/base/net_log.h"
10#include "net/disk_cache/disk_cache.h"
11#include "net/disk_cache/storage_block.h"
12#include "net/disk_cache/storage_block-inl.h"
13
14namespace disk_cache {
15
16class BackendImpl;
17class InFlightBackendIO;
18class SparseControl;
19
20// This class implements the Entry interface. An object of this
21// class represents a single entry on the cache.
22class NET_EXPORT_PRIVATE EntryImpl
23    : public Entry,
24      public base::RefCounted<EntryImpl> {
25  friend class base::RefCounted<EntryImpl>;
26  friend class SparseControl;
27 public:
28  enum Operation {
29    kRead,
30    kWrite,
31    kSparseRead,
32    kSparseWrite,
33    kAsyncIO,
34    kReadAsync1,
35    kWriteAsync1
36  };
37
38  EntryImpl(BackendImpl* backend, Addr address, bool read_only);
39
40  // Background implementation of the Entry interface.
41  void DoomImpl();
42  int ReadDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
43                   const CompletionCallback& callback);
44  int WriteDataImpl(int index, int offset, IOBuffer* buf, int buf_len,
45                    const CompletionCallback& callback, bool truncate);
46  int ReadSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
47                         const CompletionCallback& callback);
48  int WriteSparseDataImpl(int64 offset, IOBuffer* buf, int buf_len,
49                          const CompletionCallback& callback);
50  int GetAvailableRangeImpl(int64 offset, int len, int64* start);
51  void CancelSparseIOImpl();
52  int ReadyForSparseIOImpl(const CompletionCallback& callback);
53
54  // Performs the initialization of a EntryImpl that will be added to the
55  // cache.
56  bool CreateEntry(Addr node_address, const std::string& key, uint32 hash);
57
58  uint32 GetHash();
59
60  // Returns true if this entry matches the lookup arguments.
61  bool IsSameEntry(const std::string& key, uint32 hash);
62
63  // Permamently destroys this entry.
64  void InternalDoom();
65
66  bool dirty() {
67    return dirty_;
68  }
69
70  bool doomed() {
71    return doomed_;
72  }
73
74  // Returns false if the entry is clearly invalid.
75  bool SanityCheck();
76  bool DataSanityCheck();
77
78  // Attempts to make this entry reachable though the key.
79  void FixForDelete();
80
81  // Set the access times for this entry. This method provides support for
82  // the upgrade tool.
83  void SetTimes(base::Time last_used, base::Time last_modified);
84
85  // Logs a begin event and enables logging for the EntryImpl.  Will also cause
86  // an end event to be logged on destruction.  The EntryImpl must have its key
87  // initialized before this is called.  |created| is true if the Entry was
88  // created rather than opened.
89  void BeginLogging(net::NetLog* net_log, bool created);
90
91  const net::BoundNetLog& net_log() const;
92
93  // Entry interface.
94  virtual void Doom() OVERRIDE;
95  virtual void Close() OVERRIDE;
96  virtual std::string GetKey() const OVERRIDE;
97  virtual base::Time GetLastUsed() const OVERRIDE;
98  virtual base::Time GetLastModified() const OVERRIDE;
99  virtual int32 GetDataSize(int index) const OVERRIDE;
100  virtual int ReadData(int index, int offset, IOBuffer* buf, int buf_len,
101                       const CompletionCallback& callback) OVERRIDE;
102  virtual int WriteData(int index, int offset, IOBuffer* buf, int buf_len,
103                        const CompletionCallback& callback,
104                        bool truncate) OVERRIDE;
105  virtual int ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
106                             const CompletionCallback& callback) OVERRIDE;
107  virtual int WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
108                              const CompletionCallback& callback) OVERRIDE;
109  virtual int GetAvailableRange(int64 offset, int len, int64* start,
110                                const CompletionCallback& callback) OVERRIDE;
111  virtual bool CouldBeSparse() const OVERRIDE;
112  virtual void CancelSparseIO() OVERRIDE;
113  virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE;
114
115 private:
116  enum {
117     kNumStreams = 3
118  };
119  class UserBuffer;
120
121  virtual ~EntryImpl();
122
123  // Do all the work for ReadDataImpl and WriteDataImpl.  Implemented as
124  // separate functions to make logging of results simpler.
125  int InternalReadData(int index, int offset, IOBuffer* buf,
126                       int buf_len, const CompletionCallback& callback);
127  int InternalWriteData(int index, int offset, IOBuffer* buf, int buf_len,
128                        const CompletionCallback& callback, bool truncate);
129
130  // Initializes the storage for an internal or external data block.
131  bool CreateDataBlock(int index, int size);
132
133  // Initializes the storage for an internal or external generic block.
134  bool CreateBlock(int size, Addr* address);
135
136  // Deletes the data pointed by address, maybe backed by files_[index].
137  // Note that most likely the caller should delete (and store) the reference to
138  // |address| *before* calling this method because we don't want to have an
139  // entry using an address that is already free.
140  void DeleteData(Addr address, int index);
141
142  // Updates ranking information.
143  void UpdateRank(bool modified);
144
145  // Deletes this entry from disk. If |everything| is false, only the user data
146  // will be removed, leaving the key and control data intact.
147  void DeleteEntryData(bool everything);
148
149  // Prepares the target file or buffer for a write of buf_len bytes at the
150  // given offset.
151  bool PrepareTarget(int index, int offset, int buf_len, bool truncate);
152
153  // Adjusts the internal buffer and file handle for a write that truncates this
154  // stream.
155  bool HandleTruncation(int index, int offset, int buf_len);
156
157  // Copies data from disk to the internal buffer.
158  bool CopyToLocalBuffer(int index);
159
160  // Reads from a block data file to this object's memory buffer.
161  bool MoveToLocalBuffer(int index);
162
163  // Loads the external file to this object's memory buffer.
164  bool ImportSeparateFile(int index, int new_size);
165
166  // Makes sure that the internal buffer can handle the a write of |buf_len|
167  // bytes to |offset|.
168  bool PrepareBuffer(int index, int offset, int buf_len);
169
170  // Flushes the in-memory data to the backing storage. The data destination
171  // is determined based on the current data length and |min_len|.
172  bool Flush(int index, int min_len);
173
174  // Updates the size of a given data stream.
175  void UpdateSize(int index, int old_size, int new_size);
176
177  // Initializes the sparse control object. Returns a net error code.
178  int InitSparseData();
179
180  // Adds the provided |flags| to the current EntryFlags for this entry.
181  void SetEntryFlags(uint32 flags);
182
183  // Returns the current EntryFlags for this entry.
184  uint32 GetEntryFlags();
185
186  // Gets the data stored at the given index. If the information is in memory,
187  // a buffer will be allocated and the data will be copied to it (the caller
188  // can find out the size of the buffer before making this call). Otherwise,
189  // the cache address of the data will be returned, and that address will be
190  // removed from the regular book keeping of this entry so the caller is
191  // responsible for deleting the block (or file) from the backing store at some
192  // point; there is no need to report any storage-size change, only to do the
193  // actual cleanup.
194  void GetData(int index, char** buffer, Addr* address);
195
196  // Generates a histogram for the time spent working on this operation.
197  void ReportIOTime(Operation op, const base::TimeTicks& start);
198
199  // Logs this entry to the internal trace buffer.
200  void Log(const char* msg);
201
202  CacheEntryBlock entry_;     // Key related information for this entry.
203  CacheRankingsBlock node_;   // Rankings related information for this entry.
204  base::WeakPtr<BackendImpl> backend_;  // Back pointer to the cache.
205  base::WeakPtr<InFlightBackendIO> background_queue_;  // In-progress queue.
206  scoped_ptr<UserBuffer> user_buffers_[kNumStreams];  // Stores user data.
207  // Files to store external user data and key.
208  scoped_refptr<File> files_[kNumStreams + 1];
209  mutable std::string key_;           // Copy of the key.
210  int unreported_size_[kNumStreams];  // Bytes not reported yet to the backend.
211  bool doomed_;               // True if this entry was removed from the cache.
212  bool read_only_;            // True if not yet writing.
213  bool dirty_;                // True if we detected that this is a dirty entry.
214  scoped_ptr<SparseControl> sparse_;  // Support for sparse entries.
215
216  net::BoundNetLog net_log_;
217
218  DISALLOW_COPY_AND_ASSIGN(EntryImpl);
219};
220
221}  // namespace disk_cache
222
223#endif  // NET_DISK_CACHE_ENTRY_IMPL_H_
224