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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
|
// Copyright (c) 2013 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_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
#include <algorithm>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "net/base/cache_type.h"
#include "net/base/net_export.h"
#include "net/disk_cache/simple/simple_entry_format.h"
namespace net {
class GrowableIOBuffer;
class IOBuffer;
}
namespace disk_cache {
class SimpleSynchronousEntry;
// This class handles the passing of data about the entry between
// SimpleEntryImplementation and SimpleSynchronousEntry and the computation of
// file offsets based on the data size for all streams.
class NET_EXPORT_PRIVATE SimpleEntryStat {
public:
SimpleEntryStat(base::Time last_used,
base::Time last_modified,
const int32 data_size[],
const int32 sparse_data_size);
int GetOffsetInFile(const std::string& key,
int offset,
int stream_index) const;
int GetEOFOffsetInFile(const std::string& key, int stream_index) const;
int GetLastEOFOffsetInFile(const std::string& key, int file_index) const;
int GetFileSize(const std::string& key, int file_index) const;
base::Time last_used() const { return last_used_; }
base::Time last_modified() const { return last_modified_; }
void set_last_used(base::Time last_used) { last_used_ = last_used; }
void set_last_modified(base::Time last_modified) {
last_modified_ = last_modified;
}
int32 data_size(int stream_index) const { return data_size_[stream_index]; }
void set_data_size(int stream_index, int data_size) {
data_size_[stream_index] = data_size;
}
int32 sparse_data_size() const { return sparse_data_size_; }
void set_sparse_data_size(int32 sparse_data_size) {
sparse_data_size_ = sparse_data_size;
}
private:
base::Time last_used_;
base::Time last_modified_;
int32 data_size_[kSimpleEntryStreamCount];
int32 sparse_data_size_;
};
struct SimpleEntryCreationResults {
explicit SimpleEntryCreationResults(SimpleEntryStat entry_stat);
~SimpleEntryCreationResults();
SimpleSynchronousEntry* sync_entry;
scoped_refptr<net::GrowableIOBuffer> stream_0_data;
SimpleEntryStat entry_stat;
uint32 stream_0_crc32;
int result;
};
// Worker thread interface to the very simple cache. This interface is not
// thread safe, and callers must ensure that it is only ever accessed from
// a single thread between synchronization points.
class SimpleSynchronousEntry {
public:
struct CRCRecord {
CRCRecord();
CRCRecord(int index_p, bool has_crc32_p, uint32 data_crc32_p);
int index;
bool has_crc32;
uint32 data_crc32;
};
struct EntryOperationData {
EntryOperationData(int index_p, int offset_p, int buf_len_p);
EntryOperationData(int index_p,
int offset_p,
int buf_len_p,
bool truncate_p,
bool doomed_p);
EntryOperationData(int64 sparse_offset_p, int buf_len_p);
int index;
int offset;
int64 sparse_offset;
int buf_len;
bool truncate;
bool doomed;
};
static void OpenEntry(net::CacheType cache_type,
const base::FilePath& path,
uint64 entry_hash,
bool had_index,
SimpleEntryCreationResults* out_results);
static void CreateEntry(net::CacheType cache_type,
const base::FilePath& path,
const std::string& key,
uint64 entry_hash,
bool had_index,
SimpleEntryCreationResults* out_results);
// Deletes an entry from the file system without affecting the state of the
// corresponding instance, if any (allowing operations to continue to be
// executed through that instance). Returns a net error code.
static int DoomEntry(const base::FilePath& path,
uint64 entry_hash);
// Like |DoomEntry()| above. Deletes all entries corresponding to the
// |key_hashes|. Succeeds only when all entries are deleted. Returns a net
// error code.
static int DoomEntrySet(const std::vector<uint64>* key_hashes,
const base::FilePath& path);
// N.B. ReadData(), WriteData(), CheckEOFRecord() and Close() may block on IO.
void ReadData(const EntryOperationData& in_entry_op,
net::IOBuffer* out_buf,
uint32* out_crc32,
SimpleEntryStat* entry_stat,
int* out_result) const;
void WriteData(const EntryOperationData& in_entry_op,
net::IOBuffer* in_buf,
SimpleEntryStat* out_entry_stat,
int* out_result);
void CheckEOFRecord(int index,
const SimpleEntryStat& entry_stat,
uint32 expected_crc32,
int* out_result) const;
void ReadSparseData(const EntryOperationData& in_entry_op,
net::IOBuffer* out_buf,
base::Time* out_last_used,
int* out_result);
void WriteSparseData(const EntryOperationData& in_entry_op,
net::IOBuffer* in_buf,
int64 max_sparse_data_size,
SimpleEntryStat* out_entry_stat,
int* out_result);
void GetAvailableRange(const EntryOperationData& in_entry_op,
int64* out_start,
int* out_result);
// Close all streams, and add write EOF records to streams indicated by the
// CRCRecord entries in |crc32s_to_write|.
void Close(const SimpleEntryStat& entry_stat,
scoped_ptr<std::vector<CRCRecord> > crc32s_to_write,
net::GrowableIOBuffer* stream_0_data);
const base::FilePath& path() const { return path_; }
std::string key() const { return key_; }
private:
enum CreateEntryResult {
CREATE_ENTRY_SUCCESS = 0,
CREATE_ENTRY_PLATFORM_FILE_ERROR = 1,
CREATE_ENTRY_CANT_WRITE_HEADER = 2,
CREATE_ENTRY_CANT_WRITE_KEY = 3,
CREATE_ENTRY_MAX = 4,
};
enum FileRequired {
FILE_NOT_REQUIRED,
FILE_REQUIRED
};
struct SparseRange {
int64 offset;
int64 length;
uint32 data_crc32;
int64 file_offset;
bool operator<(const SparseRange& other) const {
return offset < other.offset;
}
};
SimpleSynchronousEntry(
net::CacheType cache_type,
const base::FilePath& path,
const std::string& key,
uint64 entry_hash);
// Like Entry, the SimpleSynchronousEntry self releases when Close() is
// called.
~SimpleSynchronousEntry();
// Tries to open one of the cache entry files. Succeeds if the open succeeds
// or if the file was not found and is allowed to be omitted if the
// corresponding stream is empty.
bool MaybeOpenFile(int file_index,
base::File::Error* out_error);
// Creates one of the cache entry files if necessary. If the file is allowed
// to be omitted if the corresponding stream is empty, and if |file_required|
// is FILE_NOT_REQUIRED, then the file is not created; otherwise, it is.
bool MaybeCreateFile(int file_index,
FileRequired file_required,
base::File::Error* out_error);
bool OpenFiles(bool had_index,
SimpleEntryStat* out_entry_stat);
bool CreateFiles(bool had_index,
SimpleEntryStat* out_entry_stat);
void CloseFile(int index);
void CloseFiles();
// Returns a net error, i.e. net::OK on success. |had_index| is passed
// from the main entry for metrics purposes, and is true if the index was
// initialized when the open operation began.
int InitializeForOpen(bool had_index,
SimpleEntryStat* out_entry_stat,
scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
uint32* out_stream_0_crc32);
// Writes the header and key to a newly-created stream file. |index| is the
// index of the stream. Returns true on success; returns false and sets
// |*out_result| on failure.
bool InitializeCreatedFile(int index, CreateEntryResult* out_result);
// Returns a net error, including net::OK on success and net::FILE_EXISTS
// when the entry already exists. |had_index| is passed from the main entry
// for metrics purposes, and is true if the index was initialized when the
// create operation began.
int InitializeForCreate(bool had_index, SimpleEntryStat* out_entry_stat);
// Allocates and fills a buffer with stream 0 data in |stream_0_data|, then
// checks its crc32.
int ReadAndValidateStream0(
int total_data_size,
SimpleEntryStat* out_entry_stat,
scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
uint32* out_stream_0_crc32) const;
int GetEOFRecordData(int index,
const SimpleEntryStat& entry_stat,
bool* out_has_crc32,
uint32* out_crc32,
int* out_data_size) const;
void Doom() const;
// Opens the sparse data file and scans it if it exists.
bool OpenSparseFileIfExists(int32* out_sparse_data_size);
// Creates and initializes the sparse data file.
bool CreateSparseFile();
// Closes the sparse data file.
void CloseSparseFile();
// Writes the header to the (newly-created) sparse file.
bool InitializeSparseFile();
// Removes all but the header of the sparse file.
bool TruncateSparseFile();
// Scans the existing ranges in the sparse file. Populates |sparse_ranges_|
// and sets |*out_sparse_data_size| to the total size of all the ranges (not
// including headers).
bool ScanSparseFile(int32* out_sparse_data_size);
// Reads from a single sparse range. If asked to read the entire range, also
// verifies the CRC32.
bool ReadSparseRange(const SparseRange* range,
int offset, int len, char* buf);
// Writes to a single (existing) sparse range. If asked to write the entire
// range, also updates the CRC32; otherwise, invalidates it.
bool WriteSparseRange(SparseRange* range,
int offset, int len, const char* buf);
// Appends a new sparse range to the sparse data file.
bool AppendSparseRange(int64 offset, int len, const char* buf);
static bool DeleteFileForEntryHash(const base::FilePath& path,
uint64 entry_hash,
int file_index);
static bool DeleteFilesForEntryHash(const base::FilePath& path,
uint64 entry_hash);
void RecordSyncCreateResult(CreateEntryResult result, bool had_index);
base::FilePath GetFilenameFromFileIndex(int file_index);
bool sparse_file_open() const {
return sparse_file_.IsValid();
}
const net::CacheType cache_type_;
const base::FilePath path_;
const uint64 entry_hash_;
std::string key_;
bool have_open_files_;
bool initialized_;
base::File files_[kSimpleEntryFileCount];
// True if the corresponding stream is empty and therefore no on-disk file
// was created to store it.
bool empty_file_omitted_[kSimpleEntryFileCount];
typedef std::map<int64, SparseRange> SparseRangeOffsetMap;
typedef SparseRangeOffsetMap::iterator SparseRangeIterator;
SparseRangeOffsetMap sparse_ranges_;
base::File sparse_file_;
// Offset of the end of the sparse file (where the next sparse range will be
// written).
int64 sparse_tail_offset_;
// True if the entry was created, or false if it was opened. Used to log
// SimpleCache.*.EntryCreatedWithStream2Omitted only for created entries.
bool files_created_;
};
} // namespace disk_cache
#endif // NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
|