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