Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1117)

Side by Side Diff: net/disk_cache/simple/simple_synchronous_entry.cc

Issue 1977863003: SimpleCache: open with fewer seeks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@open-speeder-macbetter
Patch Set: remediate Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/disk_cache/simple/simple_synchronous_entry.h" 5 #include "net/disk_cache/simple/simple_synchronous_entry.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 #include <functional> 9 #include <functional>
10 #include <limits> 10 #include <limits>
11 11
12 #include "base/command_line.h"
12 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
13 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
14 #include "base/hash.h" 15 #include "base/hash.h"
15 #include "base/location.h" 16 #include "base/location.h"
16 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
17 #include "base/numerics/safe_conversions.h" 18 #include "base/numerics/safe_conversions.h"
18 #include "base/sha1.h" 19 #include "base/sha1.h"
19 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
20 #include "base/timer/elapsed_timer.h" 21 #include "base/timer/elapsed_timer.h"
21 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
(...skipping 10 matching lines...) Expand all
32 namespace { 33 namespace {
33 34
34 // Used in histograms, please only add entries at the end. 35 // Used in histograms, please only add entries at the end.
35 enum OpenEntryResult { 36 enum OpenEntryResult {
36 OPEN_ENTRY_SUCCESS = 0, 37 OPEN_ENTRY_SUCCESS = 0,
37 OPEN_ENTRY_PLATFORM_FILE_ERROR = 1, 38 OPEN_ENTRY_PLATFORM_FILE_ERROR = 1,
38 OPEN_ENTRY_CANT_READ_HEADER = 2, 39 OPEN_ENTRY_CANT_READ_HEADER = 2,
39 OPEN_ENTRY_BAD_MAGIC_NUMBER = 3, 40 OPEN_ENTRY_BAD_MAGIC_NUMBER = 3,
40 OPEN_ENTRY_BAD_VERSION = 4, 41 OPEN_ENTRY_BAD_VERSION = 4,
41 OPEN_ENTRY_CANT_READ_KEY = 5, 42 OPEN_ENTRY_CANT_READ_KEY = 5,
42 // OPEN_ENTRY_KEY_MISMATCH = 6, Deprecated. 43 OPEN_ENTRY_KEY_MISMATCH = 6,
43 OPEN_ENTRY_KEY_HASH_MISMATCH = 7, 44 OPEN_ENTRY_KEY_HASH_MISMATCH = 7,
44 OPEN_ENTRY_SPARSE_OPEN_FAILED = 8, 45 OPEN_ENTRY_SPARSE_OPEN_FAILED = 8,
45 OPEN_ENTRY_MAX = 9, 46 OPEN_ENTRY_MAX = 9,
46 }; 47 };
47 48
48 // Used in histograms, please only add entries at the end. 49 // Used in histograms, please only add entries at the end.
49 enum WriteResult { 50 enum WriteResult {
50 WRITE_RESULT_SUCCESS = 0, 51 WRITE_RESULT_SUCCESS = 0,
51 WRITE_RESULT_PRETRUNCATE_FAILURE, 52 WRITE_RESULT_PRETRUNCATE_FAILURE,
52 WRITE_RESULT_WRITE_FAILURE, 53 WRITE_RESULT_WRITE_FAILURE,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 return true; 124 return true;
124 } 125 }
125 126
126 } // namespace 127 } // namespace
127 128
128 namespace disk_cache { 129 namespace disk_cache {
129 130
130 using simple_util::GetEntryHashKey; 131 using simple_util::GetEntryHashKey;
131 using simple_util::GetFilenameFromEntryHashAndFileIndex; 132 using simple_util::GetFilenameFromEntryHashAndFileIndex;
132 using simple_util::GetSparseFilenameFromEntryHash; 133 using simple_util::GetSparseFilenameFromEntryHash;
133 using simple_util::GetDataSizeFromKeyAndFileSize; 134 using simple_util::GetHeaderSize;
134 using simple_util::GetFileSizeFromKeyAndDataSize; 135 using simple_util::GetDataSizeFromFileSize;
136 using simple_util::GetFileSizeFromDataSize;
135 using simple_util::GetFileIndexFromStreamIndex; 137 using simple_util::GetFileIndexFromStreamIndex;
136 138
137 SimpleEntryStat::SimpleEntryStat(base::Time last_used, 139 SimpleEntryStat::SimpleEntryStat(base::Time last_used,
138 base::Time last_modified, 140 base::Time last_modified,
139 const int32_t data_size[], 141 const int32_t data_size[],
140 const int32_t sparse_data_size) 142 const int32_t sparse_data_size)
141 : last_used_(last_used), 143 : last_used_(last_used),
142 last_modified_(last_modified), 144 last_modified_(last_modified),
143 sparse_data_size_(sparse_data_size) { 145 sparse_data_size_(sparse_data_size) {
144 memcpy(data_size_, data_size, sizeof(data_size_)); 146 memcpy(data_size_, data_size, sizeof(data_size_));
145 } 147 }
146 148
147 int SimpleEntryStat::GetOffsetInFile(const std::string& key, 149 int SimpleEntryStat::GetOffsetInFile(size_t key_length,
148 int offset, 150 int offset,
149 int stream_index) const { 151 int stream_index) const {
150 const size_t headers_size = sizeof(SimpleFileHeader) + key.size(); 152 const size_t headers_size = sizeof(SimpleFileHeader) + key_length;
151 const size_t additional_offset = 153 const size_t additional_offset =
152 stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0; 154 stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0;
153 return headers_size + offset + additional_offset; 155 return headers_size + offset + additional_offset;
154 } 156 }
155 157
156 int SimpleEntryStat::GetEOFOffsetInFile(const std::string& key, 158 int SimpleEntryStat::GetEOFOffsetInFile(size_t key_length,
157 int stream_index) const { 159 int stream_index) const {
158 return GetOffsetInFile(key, data_size_[stream_index], stream_index); 160 return GetOffsetInFile(key_length, data_size_[stream_index], stream_index);
159 } 161 }
160 162
161 int SimpleEntryStat::GetLastEOFOffsetInFile(const std::string& key, 163 int SimpleEntryStat::GetLastEOFOffsetInFile(size_t key_length,
162 int stream_index) const { 164 int stream_index) const {
163 const int file_index = GetFileIndexFromStreamIndex(stream_index); 165 const int file_index = GetFileIndexFromStreamIndex(stream_index);
164 const int eof_data_offset = 166 const int eof_data_offset =
165 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) 167 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF)
166 : data_size_[2]; 168 : data_size_[2];
167 return GetOffsetInFile(key, eof_data_offset, stream_index); 169 return GetOffsetInFile(key_length, eof_data_offset, stream_index);
168 } 170 }
169 171
170 int64_t SimpleEntryStat::GetFileSize(const std::string& key, 172 int64_t SimpleEntryStat::GetFileSize(size_t key_length, int file_index) const {
171 int file_index) const {
172 const int32_t total_data_size = 173 const int32_t total_data_size =
173 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) 174 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF)
174 : data_size_[2]; 175 : data_size_[2];
175 return GetFileSizeFromKeyAndDataSize(key, total_data_size); 176 return GetFileSizeFromDataSize(key_length, total_data_size);
176 } 177 }
177 178
178 SimpleEntryCreationResults::SimpleEntryCreationResults( 179 SimpleEntryCreationResults::SimpleEntryCreationResults(
179 SimpleEntryStat entry_stat) 180 SimpleEntryStat entry_stat)
180 : sync_entry(NULL), 181 : sync_entry(NULL),
181 entry_stat(entry_stat), 182 entry_stat(entry_stat),
182 stream_0_crc32(crc32(0, Z_NULL, 0)), 183 stream_0_crc32(crc32(0, Z_NULL, 0)),
183 result(net::OK) { 184 result(net::OK) {
184 } 185 }
185 186
(...skipping 30 matching lines...) Expand all
216 217
217 SimpleSynchronousEntry::EntryOperationData::EntryOperationData( 218 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(
218 int64_t sparse_offset_p, 219 int64_t sparse_offset_p,
219 int buf_len_p) 220 int buf_len_p)
220 : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {} 221 : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {}
221 222
222 // static 223 // static
223 void SimpleSynchronousEntry::OpenEntry( 224 void SimpleSynchronousEntry::OpenEntry(
224 net::CacheType cache_type, 225 net::CacheType cache_type,
225 const FilePath& path, 226 const FilePath& path,
227 const std::string& key,
226 const uint64_t entry_hash, 228 const uint64_t entry_hash,
227 bool had_index, 229 const bool had_index,
228 SimpleEntryCreationResults* out_results) { 230 SimpleEntryCreationResults* out_results) {
229 base::ElapsedTimer open_time; 231 base::ElapsedTimer open_time;
230 SimpleSynchronousEntry* sync_entry = 232 SimpleSynchronousEntry* sync_entry =
231 new SimpleSynchronousEntry(cache_type, path, "", entry_hash); 233 new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index);
232 out_results->result = 234 out_results->result = sync_entry->InitializeForOpen(
233 sync_entry->InitializeForOpen(had_index, 235 &out_results->entry_stat, &out_results->stream_0_data,
234 &out_results->entry_stat, 236 &out_results->stream_0_crc32);
235 &out_results->stream_0_data,
236 &out_results->stream_0_crc32);
237 if (out_results->result != net::OK) { 237 if (out_results->result != net::OK) {
238 sync_entry->Doom(); 238 sync_entry->Doom();
239 delete sync_entry; 239 delete sync_entry;
240 out_results->sync_entry = NULL; 240 out_results->sync_entry = NULL;
241 out_results->stream_0_data = NULL; 241 out_results->stream_0_data = NULL;
242 return; 242 return;
243 } 243 }
244 UMA_HISTOGRAM_TIMES("SimpleCache.DiskOpenLatency", open_time.Elapsed()); 244 UMA_HISTOGRAM_TIMES("SimpleCache.DiskOpenLatency", open_time.Elapsed());
245 out_results->sync_entry = sync_entry; 245 out_results->sync_entry = sync_entry;
246 } 246 }
247 247
248 // static 248 // static
249 void SimpleSynchronousEntry::CreateEntry( 249 void SimpleSynchronousEntry::CreateEntry(
250 net::CacheType cache_type, 250 net::CacheType cache_type,
251 const FilePath& path, 251 const FilePath& path,
252 const std::string& key, 252 const std::string& key,
253 const uint64_t entry_hash, 253 const uint64_t entry_hash,
254 bool had_index, 254 const bool had_index,
255 SimpleEntryCreationResults* out_results) { 255 SimpleEntryCreationResults* out_results) {
256 DCHECK_EQ(entry_hash, GetEntryHashKey(key)); 256 DCHECK_EQ(entry_hash, GetEntryHashKey(key));
257 SimpleSynchronousEntry* sync_entry = 257 SimpleSynchronousEntry* sync_entry =
258 new SimpleSynchronousEntry(cache_type, path, key, entry_hash); 258 new SimpleSynchronousEntry(cache_type, path, key, entry_hash, had_index);
259 out_results->result = sync_entry->InitializeForCreate( 259 out_results->result =
260 had_index, &out_results->entry_stat); 260 sync_entry->InitializeForCreate(&out_results->entry_stat);
261 if (out_results->result != net::OK) { 261 if (out_results->result != net::OK) {
262 if (out_results->result != net::ERR_FILE_EXISTS) 262 if (out_results->result != net::ERR_FILE_EXISTS)
263 sync_entry->Doom(); 263 sync_entry->Doom();
264 delete sync_entry; 264 delete sync_entry;
265 out_results->sync_entry = NULL; 265 out_results->sync_entry = NULL;
266 return; 266 return;
267 } 267 }
268 out_results->sync_entry = sync_entry; 268 out_results->sync_entry = sync_entry;
269 } 269 }
270 270
(...skipping 20 matching lines...) Expand all
291 [&path](const uint64_t& key_hash) { 291 [&path](const uint64_t& key_hash) {
292 return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash); 292 return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash);
293 }); 293 });
294 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED; 294 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED;
295 } 295 }
296 296
297 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op, 297 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op,
298 net::IOBuffer* out_buf, 298 net::IOBuffer* out_buf,
299 uint32_t* out_crc32, 299 uint32_t* out_crc32,
300 SimpleEntryStat* entry_stat, 300 SimpleEntryStat* entry_stat,
301 int* out_result) const { 301 int* out_result) {
302 DCHECK(initialized_); 302 DCHECK(initialized_);
303 DCHECK_NE(0, in_entry_op.index); 303 DCHECK_NE(0, in_entry_op.index);
304 const int64_t file_offset =
305 entry_stat->GetOffsetInFile(key_, in_entry_op.offset, in_entry_op.index);
306 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index); 304 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index);
305 if (header_and_key_check_needed_ && !CheckHeaderAndKeyForOpen(file_index)) {
306 *out_result = net::ERR_FAILED;
307 Doom();
308 return;
309 }
310 const int64_t file_offset = entry_stat->GetOffsetInFile(
311 key_.size(), in_entry_op.offset, in_entry_op.index);
307 // Zero-length reads and reads to the empty streams of omitted files should 312 // Zero-length reads and reads to the empty streams of omitted files should
308 // be handled in the SimpleEntryImpl. 313 // be handled in the SimpleEntryImpl.
309 DCHECK_GT(in_entry_op.buf_len, 0); 314 DCHECK_GT(in_entry_op.buf_len, 0);
310 DCHECK(!empty_file_omitted_[file_index]); 315 DCHECK(!empty_file_omitted_[file_index]);
311 File* file = const_cast<File*>(&files_[file_index]); 316 int bytes_read = files_[file_index].Read(file_offset, out_buf->data(),
312 int bytes_read = 317 in_entry_op.buf_len);
313 file->Read(file_offset, out_buf->data(), in_entry_op.buf_len);
314 if (bytes_read > 0) { 318 if (bytes_read > 0) {
315 entry_stat->set_last_used(Time::Now()); 319 entry_stat->set_last_used(Time::Now());
316 *out_crc32 = crc32(crc32(0L, Z_NULL, 0), 320 *out_crc32 = crc32(crc32(0L, Z_NULL, 0),
317 reinterpret_cast<const Bytef*>(out_buf->data()), 321 reinterpret_cast<const Bytef*>(out_buf->data()),
318 bytes_read); 322 bytes_read);
319 } 323 }
320 if (bytes_read >= 0) { 324 if (bytes_read >= 0) {
321 *out_result = bytes_read; 325 *out_result = bytes_read;
322 } else { 326 } else {
323 *out_result = net::ERR_CACHE_READ_FAILURE; 327 *out_result = net::ERR_CACHE_READ_FAILURE;
324 Doom(); 328 Doom();
325 } 329 }
326 } 330 }
327 331
328 void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op, 332 void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op,
329 net::IOBuffer* in_buf, 333 net::IOBuffer* in_buf,
330 SimpleEntryStat* out_entry_stat, 334 SimpleEntryStat* out_entry_stat,
331 int* out_result) { 335 int* out_result) {
332 DCHECK(initialized_); 336 DCHECK(initialized_);
333 DCHECK_NE(0, in_entry_op.index); 337 DCHECK_NE(0, in_entry_op.index);
334 int index = in_entry_op.index; 338 int index = in_entry_op.index;
335 int file_index = GetFileIndexFromStreamIndex(index); 339 int file_index = GetFileIndexFromStreamIndex(index);
340 if (header_and_key_check_needed_ && !CheckHeaderAndKeyForOpen(file_index)) {
341 *out_result = net::ERR_FAILED;
342 Doom();
343 return;
344 }
336 int offset = in_entry_op.offset; 345 int offset = in_entry_op.offset;
337 int buf_len = in_entry_op.buf_len; 346 int buf_len = in_entry_op.buf_len;
338 bool truncate = in_entry_op.truncate; 347 bool truncate = in_entry_op.truncate;
339 bool doomed = in_entry_op.doomed; 348 bool doomed = in_entry_op.doomed;
340 const int64_t file_offset = out_entry_stat->GetOffsetInFile( 349 const int64_t file_offset = out_entry_stat->GetOffsetInFile(
341 key_, in_entry_op.offset, in_entry_op.index); 350 key_.size(), in_entry_op.offset, in_entry_op.index);
342 bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index); 351 bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index);
343 352
344 if (empty_file_omitted_[file_index]) { 353 if (empty_file_omitted_[file_index]) {
345 // Don't create a new file if the entry has been doomed, to avoid it being 354 // Don't create a new file if the entry has been doomed, to avoid it being
346 // mixed up with a newly-created entry with the same key. 355 // mixed up with a newly-created entry with the same key.
347 if (doomed) { 356 if (doomed) {
348 DLOG(WARNING) << "Rejecting write to lazily omitted stream " 357 DLOG(WARNING) << "Rejecting write to lazily omitted stream "
349 << in_entry_op.index << " of doomed cache entry."; 358 << in_entry_op.index << " of doomed cache entry.";
350 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED); 359 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED);
351 *out_result = net::ERR_CACHE_WRITE_FAILURE; 360 *out_result = net::ERR_CACHE_WRITE_FAILURE;
(...skipping 12 matching lines...) Expand all
364 Doom(); 373 Doom();
365 *out_result = net::ERR_CACHE_WRITE_FAILURE; 374 *out_result = net::ERR_CACHE_WRITE_FAILURE;
366 return; 375 return;
367 } 376 }
368 } 377 }
369 DCHECK(!empty_file_omitted_[file_index]); 378 DCHECK(!empty_file_omitted_[file_index]);
370 379
371 if (extending_by_write) { 380 if (extending_by_write) {
372 // The EOF record and the eventual stream afterward need to be zeroed out. 381 // The EOF record and the eventual stream afterward need to be zeroed out.
373 const int64_t file_eof_offset = 382 const int64_t file_eof_offset =
374 out_entry_stat->GetEOFOffsetInFile(key_, index); 383 out_entry_stat->GetEOFOffsetInFile(key_.size(), index);
375 if (!files_[file_index].SetLength(file_eof_offset)) { 384 if (!files_[file_index].SetLength(file_eof_offset)) {
376 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE); 385 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE);
377 Doom(); 386 Doom();
378 *out_result = net::ERR_CACHE_WRITE_FAILURE; 387 *out_result = net::ERR_CACHE_WRITE_FAILURE;
379 return; 388 return;
380 } 389 }
381 } 390 }
382 if (buf_len > 0) { 391 if (buf_len > 0) {
383 if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) != 392 if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) !=
384 buf_len) { 393 buf_len) {
385 RecordWriteResult(cache_type_, WRITE_RESULT_WRITE_FAILURE); 394 RecordWriteResult(cache_type_, WRITE_RESULT_WRITE_FAILURE);
386 Doom(); 395 Doom();
387 *out_result = net::ERR_CACHE_WRITE_FAILURE; 396 *out_result = net::ERR_CACHE_WRITE_FAILURE;
388 return; 397 return;
389 } 398 }
390 } 399 }
391 if (!truncate && (buf_len > 0 || !extending_by_write)) { 400 if (!truncate && (buf_len > 0 || !extending_by_write)) {
392 out_entry_stat->set_data_size( 401 out_entry_stat->set_data_size(
393 index, std::max(out_entry_stat->data_size(index), offset + buf_len)); 402 index, std::max(out_entry_stat->data_size(index), offset + buf_len));
394 } else { 403 } else {
395 out_entry_stat->set_data_size(index, offset + buf_len); 404 out_entry_stat->set_data_size(index, offset + buf_len);
396 int file_eof_offset = out_entry_stat->GetLastEOFOffsetInFile(key_, index); 405 int file_eof_offset =
406 out_entry_stat->GetLastEOFOffsetInFile(key_.size(), index);
397 if (!files_[file_index].SetLength(file_eof_offset)) { 407 if (!files_[file_index].SetLength(file_eof_offset)) {
398 RecordWriteResult(cache_type_, WRITE_RESULT_TRUNCATE_FAILURE); 408 RecordWriteResult(cache_type_, WRITE_RESULT_TRUNCATE_FAILURE);
399 Doom(); 409 Doom();
400 *out_result = net::ERR_CACHE_WRITE_FAILURE; 410 *out_result = net::ERR_CACHE_WRITE_FAILURE;
401 return; 411 return;
402 } 412 }
403 } 413 }
404 414
405 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); 415 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS);
406 base::Time modification_time = Time::Now(); 416 base::Time modification_time = Time::Now();
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 } 647 }
638 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); 648 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS);
639 } 649 }
640 650
641 void SimpleSynchronousEntry::Close( 651 void SimpleSynchronousEntry::Close(
642 const SimpleEntryStat& entry_stat, 652 const SimpleEntryStat& entry_stat,
643 std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write, 653 std::unique_ptr<std::vector<CRCRecord>> crc32s_to_write,
644 net::GrowableIOBuffer* stream_0_data) { 654 net::GrowableIOBuffer* stream_0_data) {
645 DCHECK(stream_0_data); 655 DCHECK(stream_0_data);
646 // Write stream 0 data. 656 // Write stream 0 data.
647 int stream_0_offset = entry_stat.GetOffsetInFile(key_, 0, 0); 657 int stream_0_offset = entry_stat.GetOffsetInFile(key_.size(), 0, 0);
648 if (files_[0].Write(stream_0_offset, stream_0_data->data(), 658 if (files_[0].Write(stream_0_offset, stream_0_data->data(),
649 entry_stat.data_size(0)) != 659 entry_stat.data_size(0)) !=
650 entry_stat.data_size(0)) { 660 entry_stat.data_size(0)) {
651 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); 661 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE);
652 DVLOG(1) << "Could not write stream 0 data."; 662 DVLOG(1) << "Could not write stream 0 data.";
653 Doom(); 663 Doom();
654 } 664 }
655 665
656 for (std::vector<CRCRecord>::const_iterator it = crc32s_to_write->begin(); 666 for (std::vector<CRCRecord>::const_iterator it = crc32s_to_write->begin();
657 it != crc32s_to_write->end(); ++it) { 667 it != crc32s_to_write->end(); ++it) {
658 const int stream_index = it->index; 668 const int stream_index = it->index;
659 const int file_index = GetFileIndexFromStreamIndex(stream_index); 669 const int file_index = GetFileIndexFromStreamIndex(stream_index);
660 if (empty_file_omitted_[file_index]) 670 if (empty_file_omitted_[file_index])
661 continue; 671 continue;
662 672
663 SimpleFileEOF eof_record; 673 SimpleFileEOF eof_record;
664 eof_record.stream_size = entry_stat.data_size(stream_index); 674 eof_record.stream_size = entry_stat.data_size(stream_index);
665 eof_record.final_magic_number = kSimpleFinalMagicNumber; 675 eof_record.final_magic_number = kSimpleFinalMagicNumber;
666 eof_record.flags = 0; 676 eof_record.flags = 0;
667 if (it->has_crc32) 677 if (it->has_crc32)
668 eof_record.flags |= SimpleFileEOF::FLAG_HAS_CRC32; 678 eof_record.flags |= SimpleFileEOF::FLAG_HAS_CRC32;
669 eof_record.data_crc32 = it->data_crc32; 679 eof_record.data_crc32 = it->data_crc32;
670 int eof_offset = entry_stat.GetEOFOffsetInFile(key_, stream_index); 680 int eof_offset = entry_stat.GetEOFOffsetInFile(key_.size(), stream_index);
671 // If stream 0 changed size, the file needs to be resized, otherwise the 681 // If stream 0 changed size, the file needs to be resized, otherwise the
672 // next open will yield wrong stream sizes. On stream 1 and stream 2 proper 682 // next open will yield wrong stream sizes. On stream 1 and stream 2 proper
673 // resizing of the file is handled in SimpleSynchronousEntry::WriteData(). 683 // resizing of the file is handled in SimpleSynchronousEntry::WriteData().
674 if (stream_index == 0 && 684 if (stream_index == 0 &&
675 !files_[file_index].SetLength(eof_offset)) { 685 !files_[file_index].SetLength(eof_offset)) {
676 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); 686 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE);
677 DVLOG(1) << "Could not truncate stream 0 file."; 687 DVLOG(1) << "Could not truncate stream 0 file.";
678 Doom(); 688 Doom();
679 break; 689 break;
680 } 690 }
681 if (files_[file_index].Write(eof_offset, 691 if (files_[file_index].Write(eof_offset,
682 reinterpret_cast<const char*>(&eof_record), 692 reinterpret_cast<const char*>(&eof_record),
683 sizeof(eof_record)) != 693 sizeof(eof_record)) !=
684 sizeof(eof_record)) { 694 sizeof(eof_record)) {
685 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); 695 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE);
686 DVLOG(1) << "Could not write eof record."; 696 DVLOG(1) << "Could not write eof record.";
687 Doom(); 697 Doom();
688 break; 698 break;
689 } 699 }
690 } 700 }
691 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 701 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
692 if (empty_file_omitted_[i]) 702 if (empty_file_omitted_[i])
693 continue; 703 continue;
694 704
695 files_[i].Close(); 705 files_[i].Close();
696 const int64_t file_size = entry_stat.GetFileSize(key_, i); 706 const int64_t file_size = entry_stat.GetFileSize(key_.size(), i);
697 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, 707 SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
698 "LastClusterSize", cache_type_, 708 "LastClusterSize", cache_type_,
699 file_size % 4096, 0, 4097, 50); 709 file_size % 4096, 0, 4097, 50);
700 const int64_t cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0; 710 const int64_t cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0;
701 SIMPLE_CACHE_UMA(PERCENTAGE, 711 SIMPLE_CACHE_UMA(PERCENTAGE,
702 "LastClusterLossPercent", cache_type_, 712 "LastClusterLossPercent", cache_type_,
703 static_cast<base::HistogramBase::Sample>( 713 static_cast<base::HistogramBase::Sample>(
704 cluster_loss * 100 / (cluster_loss + file_size))); 714 cluster_loss * 100 / (cluster_loss + file_size)));
705 } 715 }
706 716
707 if (sparse_file_open()) 717 if (sparse_file_open())
708 sparse_file_.Close(); 718 sparse_file_.Close();
709 719
710 if (files_created_) { 720 if (files_created_) {
711 const int stream2_file_index = GetFileIndexFromStreamIndex(2); 721 const int stream2_file_index = GetFileIndexFromStreamIndex(2);
712 SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_, 722 SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_,
713 empty_file_omitted_[stream2_file_index]); 723 empty_file_omitted_[stream2_file_index]);
714 } 724 }
715 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); 725 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS);
716 have_open_files_ = false; 726 have_open_files_ = false;
717 delete this; 727 delete this;
718 } 728 }
719 729
720 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type, 730 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type,
721 const FilePath& path, 731 const FilePath& path,
722 const std::string& key, 732 const std::string& key,
723 const uint64_t entry_hash) 733 const uint64_t entry_hash,
734 const bool had_index)
724 : cache_type_(cache_type), 735 : cache_type_(cache_type),
725 path_(path), 736 path_(path),
726 entry_hash_(entry_hash), 737 entry_hash_(entry_hash),
738 had_index_(had_index),
727 key_(key), 739 key_(key),
728 have_open_files_(false), 740 have_open_files_(false),
729 initialized_(false) { 741 initialized_(false),
742 header_and_key_check_needed_(false) {
730 for (int i = 0; i < kSimpleEntryFileCount; ++i) 743 for (int i = 0; i < kSimpleEntryFileCount; ++i)
731 empty_file_omitted_[i] = false; 744 empty_file_omitted_[i] = false;
732 } 745 }
733 746
734 SimpleSynchronousEntry::~SimpleSynchronousEntry() { 747 SimpleSynchronousEntry::~SimpleSynchronousEntry() {
735 DCHECK(!(have_open_files_ && initialized_)); 748 DCHECK(!(have_open_files_ && initialized_));
736 if (have_open_files_) 749 if (have_open_files_)
737 CloseFiles(); 750 CloseFiles();
738 } 751 }
739 752
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 int flags = File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE | 785 int flags = File::FLAG_CREATE | File::FLAG_READ | File::FLAG_WRITE |
773 File::FLAG_SHARE_DELETE; 786 File::FLAG_SHARE_DELETE;
774 files_[file_index].Initialize(filename, flags); 787 files_[file_index].Initialize(filename, flags);
775 *out_error = files_[file_index].error_details(); 788 *out_error = files_[file_index].error_details();
776 789
777 empty_file_omitted_[file_index] = false; 790 empty_file_omitted_[file_index] = false;
778 791
779 return files_[file_index].IsValid(); 792 return files_[file_index].IsValid();
780 } 793 }
781 794
782 bool SimpleSynchronousEntry::OpenFiles( 795 bool SimpleSynchronousEntry::OpenFiles(SimpleEntryStat* out_entry_stat) {
783 bool had_index,
784 SimpleEntryStat* out_entry_stat) {
785 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 796 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
786 File::Error error; 797 File::Error error;
787 if (!MaybeOpenFile(i, &error)) { 798 if (!MaybeOpenFile(i, &error)) {
788 // TODO(juliatuttle,gavinp): Remove one each of these triplets of 799 // TODO(juliatuttle,gavinp): Remove one each of these triplets of
789 // histograms. We can calculate the third as the sum or difference of the 800 // histograms. We can calculate the third as the sum or difference of the
790 // other two. 801 // other two.
791 RecordSyncOpenResult( 802 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_PLATFORM_FILE_ERROR,
792 cache_type_, OPEN_ENTRY_PLATFORM_FILE_ERROR, had_index); 803 had_index_);
793 SIMPLE_CACHE_UMA(ENUMERATION, 804 SIMPLE_CACHE_UMA(ENUMERATION,
794 "SyncOpenPlatformFileError", cache_type_, 805 "SyncOpenPlatformFileError", cache_type_,
795 -error, -base::File::FILE_ERROR_MAX); 806 -error, -base::File::FILE_ERROR_MAX);
796 if (had_index) { 807 if (had_index_) {
797 SIMPLE_CACHE_UMA(ENUMERATION, 808 SIMPLE_CACHE_UMA(ENUMERATION,
798 "SyncOpenPlatformFileError_WithIndex", cache_type_, 809 "SyncOpenPlatformFileError_WithIndex", cache_type_,
799 -error, -base::File::FILE_ERROR_MAX); 810 -error, -base::File::FILE_ERROR_MAX);
800 } else { 811 } else {
801 SIMPLE_CACHE_UMA(ENUMERATION, 812 SIMPLE_CACHE_UMA(ENUMERATION,
802 "SyncOpenPlatformFileError_WithoutIndex", 813 "SyncOpenPlatformFileError_WithoutIndex",
803 cache_type_, 814 cache_type_,
804 -error, -base::File::FILE_ERROR_MAX); 815 -error, -base::File::FILE_ERROR_MAX);
805 } 816 }
806 while (--i >= 0) 817 while (--i >= 0)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } 864 }
854 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, 865 SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
855 "SyncOpenEntryAge", cache_type_, 866 "SyncOpenEntryAge", cache_type_,
856 entry_age.InHours(), 1, 1000, 50); 867 entry_age.InHours(), 1, 1000, 50);
857 868
858 files_created_ = false; 869 files_created_ = false;
859 870
860 return true; 871 return true;
861 } 872 }
862 873
863 bool SimpleSynchronousEntry::CreateFiles( 874 bool SimpleSynchronousEntry::CreateFiles(SimpleEntryStat* out_entry_stat) {
864 bool had_index,
865 SimpleEntryStat* out_entry_stat) {
866 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 875 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
867 File::Error error; 876 File::Error error;
868 if (!MaybeCreateFile(i, FILE_NOT_REQUIRED, &error)) { 877 if (!MaybeCreateFile(i, FILE_NOT_REQUIRED, &error)) {
869 // TODO(juliatuttle,gavinp): Remove one each of these triplets of 878 // TODO(juliatuttle,gavinp): Remove one each of these triplets of
870 // histograms. We can calculate the third as the sum or difference of the 879 // histograms. We can calculate the third as the sum or difference of the
871 // other two. 880 // other two.
872 RecordSyncCreateResult(CREATE_ENTRY_PLATFORM_FILE_ERROR, had_index); 881 RecordSyncCreateResult(CREATE_ENTRY_PLATFORM_FILE_ERROR, had_index_);
873 SIMPLE_CACHE_UMA(ENUMERATION, 882 SIMPLE_CACHE_UMA(ENUMERATION,
874 "SyncCreatePlatformFileError", cache_type_, 883 "SyncCreatePlatformFileError", cache_type_,
875 -error, -base::File::FILE_ERROR_MAX); 884 -error, -base::File::FILE_ERROR_MAX);
876 if (had_index) { 885 if (had_index_) {
877 SIMPLE_CACHE_UMA(ENUMERATION, 886 SIMPLE_CACHE_UMA(ENUMERATION,
878 "SyncCreatePlatformFileError_WithIndex", cache_type_, 887 "SyncCreatePlatformFileError_WithIndex", cache_type_,
879 -error, -base::File::FILE_ERROR_MAX); 888 -error, -base::File::FILE_ERROR_MAX);
880 } else { 889 } else {
881 SIMPLE_CACHE_UMA(ENUMERATION, 890 SIMPLE_CACHE_UMA(ENUMERATION,
882 "SyncCreatePlatformFileError_WithoutIndex", 891 "SyncCreatePlatformFileError_WithoutIndex",
883 cache_type_, 892 cache_type_,
884 -error, -base::File::FILE_ERROR_MAX); 893 -error, -base::File::FILE_ERROR_MAX);
885 } 894 }
886 while (--i >= 0) 895 while (--i >= 0)
(...skipping 25 matching lines...) Expand all
912 921
913 if (sparse_file_open()) 922 if (sparse_file_open())
914 CloseSparseFile(); 923 CloseSparseFile();
915 } 924 }
916 925
917 void SimpleSynchronousEntry::CloseFiles() { 926 void SimpleSynchronousEntry::CloseFiles() {
918 for (int i = 0; i < kSimpleEntryFileCount; ++i) 927 for (int i = 0; i < kSimpleEntryFileCount; ++i)
919 CloseFile(i); 928 CloseFile(i);
920 } 929 }
921 930
931 bool SimpleSynchronousEntry::CheckHeaderAndKeyForOpen(int file_index) {
932 // TODO(gavinp): Frequently we are doing this at the same time as we read from
933 // the beginning of an entry. It might improve performance to make a single
934 // read(2) call rather than two separate reads. On the other hand, it would
935 // mean an extra memory to memory copy. In the case where we are opening an
936 // entry without a key, the kInitialHeaderRead setting means that we are
937 // actually already reading stream 1 data here, and tossing it out.
938 std::vector<char> header_data(key_.empty() ? kInitialHeaderRead
939 : GetHeaderSize(key_.size()));
940 int bytes_read =
941 files_[file_index].Read(0, header_data.data(), header_data.size());
942 const SimpleFileHeader* header =
943 reinterpret_cast<const SimpleFileHeader*>(header_data.data());
944
945 if (bytes_read == -1 || static_cast<size_t>(bytes_read) < sizeof(*header)) {
946 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_HEADER, had_index_);
947 return false;
948 }
949 // This resize will not invalidate iterators since it does not enlarge the
950 // header_data.
951 DCHECK_LE(static_cast<size_t>(bytes_read), header_data.size());
952 header_data.resize(bytes_read);
953
954 if (header->initial_magic_number != kSimpleInitialMagicNumber) {
955 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_MAGIC_NUMBER, had_index_);
956 return false;
957 }
958
959 if (header->version != kSimpleEntryVersionOnDisk) {
960 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_VERSION, had_index_);
961 return false;
962 }
963
964 size_t expected_header_size = GetHeaderSize(header->key_length);
965 if (header_data.size() < expected_header_size) {
966 size_t old_size = header_data.size();
967 // This resize will invalidate iterators, since it is enlarging header_data.
968 header_data.resize(expected_header_size);
969 int bytes_read =
970 files_[file_index].Read(old_size, header_data.data() + old_size,
971 expected_header_size - old_size);
972 // If there was an IO error, just shrink the vector to its original size.
973 // The buffer doesn't hold the entire key, so it will exit with a failure
974 // and record the reason as OPEN_ENTRY_CANT_READ_KEY.
975 if (bytes_read == -1)
976 header_data.resize(old_size);
977 else
978 header_data.resize(old_size + bytes_read);
979 header = reinterpret_cast<const SimpleFileHeader*>(header_data.data());
980 }
981
982 if (header_data.size() < sizeof(*header) + header->key_length) {
Randy Smith (Not in Mondays) 2016/05/18 16:41:30 Why do it by hand here and use GetHeaderSize() abo
Randy Smith (Not in Mondays) 2016/05/18 16:41:30 Suggestion: If I'm reading the code correctly, thi
gavinp 2016/05/18 19:05:03 Good catch. Done.
983 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index_);
984 return false;
985 }
986 char* key_data = header_data.data() + sizeof(*header);
987 if (base::Hash(key_data, header->key_length) != header->key_hash) {
988 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index_);
989 return false;
990 }
991
992 std::string key_from_header(key_data, header->key_length);
993 if (key_.empty()) {
994 key_.swap(key_from_header);
995 } else {
996 if (key_ != key_from_header) {
997 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_KEY_MISMATCH, had_index_);
998 return false;
999 }
1000 }
1001
1002 header_and_key_check_needed_ = false;
1003 return true;
1004 }
1005
922 int SimpleSynchronousEntry::InitializeForOpen( 1006 int SimpleSynchronousEntry::InitializeForOpen(
923 bool had_index,
924 SimpleEntryStat* out_entry_stat, 1007 SimpleEntryStat* out_entry_stat,
925 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, 1008 scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
926 uint32_t* out_stream_0_crc32) { 1009 uint32_t* out_stream_0_crc32) {
927 DCHECK(!initialized_); 1010 DCHECK(!initialized_);
928 if (!OpenFiles(had_index, out_entry_stat)) { 1011 if (!OpenFiles(out_entry_stat)) {
929 DLOG(WARNING) << "Could not open platform files for entry."; 1012 DLOG(WARNING) << "Could not open platform files for entry.";
930 return net::ERR_FAILED; 1013 return net::ERR_FAILED;
931 } 1014 }
932 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 1015 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
933 if (empty_file_omitted_[i]) 1016 if (empty_file_omitted_[i])
934 continue; 1017 continue;
935 1018
936 SimpleFileHeader header; 1019 if (!key_.empty() &&
937 int header_read_result = 1020 base::CommandLine::ForCurrentProcess()->HasSwitch(
938 files_[i].Read(0, reinterpret_cast<char*>(&header), sizeof(header)); 1021 "simple-cache-dont-read-initial-header")) {
939 if (header_read_result != sizeof(header)) { 1022 header_and_key_check_needed_ = true;
940 DLOG(WARNING) << "Cannot read header from entry."; 1023 } else {
941 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_HEADER, had_index); 1024 if (!CheckHeaderAndKeyForOpen(i))
942 return net::ERR_FAILED; 1025 return net::ERR_FAILED;
943 } 1026 }
944 1027
945 if (header.initial_magic_number != kSimpleInitialMagicNumber) {
946 // TODO(gavinp): This seems very bad; for now we log at WARNING, but we
947 // should give consideration to not saturating the log with these if that
948 // becomes a problem.
949 DLOG(WARNING) << "Magic number did not match.";
950 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_MAGIC_NUMBER, had_index);
951 return net::ERR_FAILED;
952 }
953
954 if (header.version != kSimpleEntryVersionOnDisk) {
955 DLOG(WARNING) << "Unreadable version.";
956 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_BAD_VERSION, had_index);
957 return net::ERR_FAILED;
958 }
959
960 std::unique_ptr<char[]> key(new char[header.key_length]);
961 int key_read_result = files_[i].Read(sizeof(header), key.get(),
962 header.key_length);
963 if (key_read_result != base::checked_cast<int>(header.key_length)) {
964 DLOG(WARNING) << "Cannot read key from entry.";
965 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index);
966 return net::ERR_FAILED;
967 }
968
969 key_ = std::string(key.get(), header.key_length);
970 if (i == 0) { 1028 if (i == 0) {
971 // File size for stream 0 has been stored temporarily in data_size[1]. 1029 // File size for stream 0 has been stored temporarily in data_size[1].
972 int total_data_size = 1030 int total_data_size =
973 GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size(1)); 1031 GetDataSizeFromFileSize(key_.size(), out_entry_stat->data_size(1));
974 int ret_value_stream_0 = ReadAndValidateStream0( 1032 int ret_value_stream_0 = ReadAndValidateStream0(
975 total_data_size, out_entry_stat, stream_0_data, out_stream_0_crc32); 1033 total_data_size, out_entry_stat, stream_0_data, out_stream_0_crc32);
976 if (ret_value_stream_0 != net::OK) 1034 if (ret_value_stream_0 != net::OK)
977 return ret_value_stream_0; 1035 return ret_value_stream_0;
978 } else { 1036 } else {
979 out_entry_stat->set_data_size( 1037 out_entry_stat->set_data_size(
980 2, GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size(2))); 1038 2,
1039 GetDataSizeFromFileSize(key_.size(), out_entry_stat->data_size(2)));
981 if (out_entry_stat->data_size(2) < 0) { 1040 if (out_entry_stat->data_size(2) < 0) {
982 DLOG(WARNING) << "Stream 2 file is too small."; 1041 DLOG(WARNING) << "Stream 2 file is too small.";
983 return net::ERR_FAILED; 1042 return net::ERR_FAILED;
984 } 1043 }
985 } 1044 }
986
987 if (base::Hash(key.get(), header.key_length) != header.key_hash) {
988 DLOG(WARNING) << "Hash mismatch on key.";
989 RecordSyncOpenResult(
990 cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index);
991 return net::ERR_FAILED;
992 }
993 } 1045 }
994 1046
995 int32_t sparse_data_size = 0; 1047 int32_t sparse_data_size = 0;
996 if (!OpenSparseFileIfExists(&sparse_data_size)) { 1048 if (!OpenSparseFileIfExists(&sparse_data_size)) {
997 RecordSyncOpenResult( 1049 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED,
998 cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED, had_index); 1050 had_index_);
999 return net::ERR_FAILED; 1051 return net::ERR_FAILED;
1000 } 1052 }
1001 out_entry_stat->set_sparse_data_size(sparse_data_size); 1053 out_entry_stat->set_sparse_data_size(sparse_data_size);
1002 1054
1003 bool removed_stream2 = false; 1055 bool removed_stream2 = false;
1004 const int stream2_file_index = GetFileIndexFromStreamIndex(2); 1056 const int stream2_file_index = GetFileIndexFromStreamIndex(2);
1005 DCHECK(CanOmitEmptyFile(stream2_file_index)); 1057 DCHECK(CanOmitEmptyFile(stream2_file_index));
1006 if (!empty_file_omitted_[stream2_file_index] && 1058 if (!empty_file_omitted_[stream2_file_index] &&
1007 out_entry_stat->data_size(2) == 0) { 1059 out_entry_stat->data_size(2) == 0) {
1008 DVLOG(1) << "Removing empty stream 2 file."; 1060 DVLOG(1) << "Removing empty stream 2 file.";
1009 CloseFile(stream2_file_index); 1061 CloseFile(stream2_file_index);
1010 DeleteFileForEntryHash(path_, entry_hash_, stream2_file_index); 1062 DeleteFileForEntryHash(path_, entry_hash_, stream2_file_index);
1011 empty_file_omitted_[stream2_file_index] = true; 1063 empty_file_omitted_[stream2_file_index] = true;
1012 removed_stream2 = true; 1064 removed_stream2 = true;
1013 } 1065 }
1014 1066
1015 SIMPLE_CACHE_UMA(BOOLEAN, "EntryOpenedAndStream2Removed", cache_type_, 1067 SIMPLE_CACHE_UMA(BOOLEAN, "EntryOpenedAndStream2Removed", cache_type_,
1016 removed_stream2); 1068 removed_stream2);
1017 1069
1018 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SUCCESS, had_index); 1070 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SUCCESS, had_index_);
1019 initialized_ = true; 1071 initialized_ = true;
1020 return net::OK; 1072 return net::OK;
1021 } 1073 }
1022 1074
1023 bool SimpleSynchronousEntry::InitializeCreatedFile( 1075 bool SimpleSynchronousEntry::InitializeCreatedFile(
1024 int file_index, 1076 int file_index,
1025 CreateEntryResult* out_result) { 1077 CreateEntryResult* out_result) {
1026 SimpleFileHeader header; 1078 SimpleFileHeader header;
1027 header.initial_magic_number = kSimpleInitialMagicNumber; 1079 header.initial_magic_number = kSimpleInitialMagicNumber;
1028 header.version = kSimpleEntryVersionOnDisk; 1080 header.version = kSimpleEntryVersionOnDisk;
(...skipping 12 matching lines...) Expand all
1041 key_.size()); 1093 key_.size());
1042 if (bytes_written != base::checked_cast<int>(key_.size())) { 1094 if (bytes_written != base::checked_cast<int>(key_.size())) {
1043 *out_result = CREATE_ENTRY_CANT_WRITE_KEY; 1095 *out_result = CREATE_ENTRY_CANT_WRITE_KEY;
1044 return false; 1096 return false;
1045 } 1097 }
1046 1098
1047 return true; 1099 return true;
1048 } 1100 }
1049 1101
1050 int SimpleSynchronousEntry::InitializeForCreate( 1102 int SimpleSynchronousEntry::InitializeForCreate(
1051 bool had_index,
1052 SimpleEntryStat* out_entry_stat) { 1103 SimpleEntryStat* out_entry_stat) {
1053 DCHECK(!initialized_); 1104 DCHECK(!initialized_);
1054 if (!CreateFiles(had_index, out_entry_stat)) { 1105 if (!CreateFiles(out_entry_stat)) {
1055 DLOG(WARNING) << "Could not create platform files."; 1106 DLOG(WARNING) << "Could not create platform files.";
1056 return net::ERR_FILE_EXISTS; 1107 return net::ERR_FILE_EXISTS;
1057 } 1108 }
1058 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 1109 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
1059 if (empty_file_omitted_[i]) 1110 if (empty_file_omitted_[i])
1060 continue; 1111 continue;
1061 1112
1062 CreateEntryResult result; 1113 CreateEntryResult result;
1063 if (!InitializeCreatedFile(i, &result)) { 1114 if (!InitializeCreatedFile(i, &result)) {
1064 RecordSyncCreateResult(result, had_index); 1115 RecordSyncCreateResult(result, had_index_);
1065 return net::ERR_FAILED; 1116 return net::ERR_FAILED;
1066 } 1117 }
1067 } 1118 }
1068 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS, had_index); 1119 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS, had_index_);
1069 initialized_ = true; 1120 initialized_ = true;
1070 return net::OK; 1121 return net::OK;
1071 } 1122 }
1072 1123
1073 int SimpleSynchronousEntry::ReadAndValidateStream0( 1124 int SimpleSynchronousEntry::ReadAndValidateStream0(
1074 int total_data_size, 1125 int total_data_size,
1075 SimpleEntryStat* out_entry_stat, 1126 SimpleEntryStat* out_entry_stat,
1076 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, 1127 scoped_refptr<net::GrowableIOBuffer>* stream_0_data,
1077 uint32_t* out_stream_0_crc32) const { 1128 uint32_t* out_stream_0_crc32) const {
1078 // Temporarily assign all the data size to stream 1 in order to read the 1129 // Temporarily assign all the data size to stream 1 in order to read the
(...skipping 13 matching lines...) Expand all
1092 return net::ERR_FAILED; 1143 return net::ERR_FAILED;
1093 1144
1094 // These are the real values of data size. 1145 // These are the real values of data size.
1095 out_entry_stat->set_data_size(0, stream_0_size); 1146 out_entry_stat->set_data_size(0, stream_0_size);
1096 out_entry_stat->set_data_size( 1147 out_entry_stat->set_data_size(
1097 1, out_entry_stat->data_size(1) - stream_0_size); 1148 1, out_entry_stat->data_size(1) - stream_0_size);
1098 1149
1099 // Put stream 0 data in memory. 1150 // Put stream 0 data in memory.
1100 *stream_0_data = new net::GrowableIOBuffer(); 1151 *stream_0_data = new net::GrowableIOBuffer();
1101 (*stream_0_data)->SetCapacity(stream_0_size); 1152 (*stream_0_data)->SetCapacity(stream_0_size);
1102 int file_offset = out_entry_stat->GetOffsetInFile(key_, 0, 0); 1153 int file_offset = out_entry_stat->GetOffsetInFile(key_.size(), 0, 0);
1103 File* file = const_cast<File*>(&files_[0]); 1154 File* file = const_cast<File*>(&files_[0]);
1104 int bytes_read = 1155 int bytes_read =
1105 file->Read(file_offset, (*stream_0_data)->data(), stream_0_size); 1156 file->Read(file_offset, (*stream_0_data)->data(), stream_0_size);
1106 if (bytes_read != stream_0_size) 1157 if (bytes_read != stream_0_size)
1107 return net::ERR_FAILED; 1158 return net::ERR_FAILED;
1108 1159
1109 // Check the CRC32. 1160 // Check the CRC32.
1110 uint32_t expected_crc32 = 1161 uint32_t expected_crc32 =
1111 stream_0_size == 0 1162 stream_0_size == 0
1112 ? crc32(0, Z_NULL, 0) 1163 ? crc32(0, Z_NULL, 0)
1113 : crc32(crc32(0, Z_NULL, 0), 1164 : crc32(crc32(0, Z_NULL, 0),
1114 reinterpret_cast<const Bytef*>((*stream_0_data)->data()), 1165 reinterpret_cast<const Bytef*>((*stream_0_data)->data()),
1115 stream_0_size); 1166 stream_0_size);
1116 if (has_crc32 && read_crc32 != expected_crc32) { 1167 if (has_crc32 && read_crc32 != expected_crc32) {
1117 DVLOG(1) << "EOF record had bad crc."; 1168 DVLOG(1) << "EOF record had bad crc.";
1118 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); 1169 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH);
1119 return net::ERR_FAILED; 1170 return net::ERR_FAILED;
1120 } 1171 }
1121 *out_stream_0_crc32 = expected_crc32; 1172 *out_stream_0_crc32 = expected_crc32;
1122 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); 1173 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS);
1123 return net::OK; 1174 return net::OK;
1124 } 1175 }
1125 1176
1126 int SimpleSynchronousEntry::GetEOFRecordData(int index, 1177 int SimpleSynchronousEntry::GetEOFRecordData(int index,
1127 const SimpleEntryStat& entry_stat, 1178 const SimpleEntryStat& entry_stat,
1128 bool* out_has_crc32, 1179 bool* out_has_crc32,
1129 uint32_t* out_crc32, 1180 uint32_t* out_crc32,
1130 int* out_data_size) const { 1181 int* out_data_size) const {
1131 SimpleFileEOF eof_record; 1182 SimpleFileEOF eof_record;
1132 int file_offset = entry_stat.GetEOFOffsetInFile(key_, index); 1183 int file_offset = entry_stat.GetEOFOffsetInFile(key_.size(), index);
1133 int file_index = GetFileIndexFromStreamIndex(index); 1184 int file_index = GetFileIndexFromStreamIndex(index);
1134 File* file = const_cast<File*>(&files_[file_index]); 1185 File* file = const_cast<File*>(&files_[file_index]);
1135 if (file->Read(file_offset, reinterpret_cast<char*>(&eof_record), 1186 if (file->Read(file_offset, reinterpret_cast<char*>(&eof_record),
1136 sizeof(eof_record)) != 1187 sizeof(eof_record)) !=
1137 sizeof(eof_record)) { 1188 sizeof(eof_record)) {
1138 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE); 1189 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE);
1139 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; 1190 return net::ERR_CACHE_CHECKSUM_READ_FAILURE;
1140 } 1191 }
1141 1192
1142 if (eof_record.final_magic_number != kSimpleFinalMagicNumber) { 1193 if (eof_record.final_magic_number != kSimpleFinalMagicNumber) {
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 range.offset = offset; 1518 range.offset = offset;
1468 range.length = len; 1519 range.length = len;
1469 range.data_crc32 = data_crc32; 1520 range.data_crc32 = data_crc32;
1470 range.file_offset = data_file_offset; 1521 range.file_offset = data_file_offset;
1471 sparse_ranges_.insert(std::make_pair(offset, range)); 1522 sparse_ranges_.insert(std::make_pair(offset, range));
1472 1523
1473 return true; 1524 return true;
1474 } 1525 }
1475 1526
1476 } // namespace disk_cache 1527 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698