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

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

Issue 23983005: SimpleCache: merge the first and second stream in one file (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed functions from simple_util Created 7 years, 3 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>
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 134
135 void RecordCloseResult(net::CacheType cache_type, CloseResult result) { 135 void RecordCloseResult(net::CacheType cache_type, CloseResult result) {
136 SIMPLE_CACHE_UMA(ENUMERATION, 136 SIMPLE_CACHE_UMA(ENUMERATION,
137 "SyncCloseResult", cache_type, result, WRITE_RESULT_MAX); 137 "SyncCloseResult", cache_type, result, WRITE_RESULT_MAX);
138 } 138 }
139 139
140 } // namespace 140 } // namespace
141 141
142 namespace disk_cache { 142 namespace disk_cache {
143 143
144 using simple_util::ConvertEntryHashKeyToHexString; 144 using simple_util::ConvertEntryHashKeyToHexString;
pasko 2013/09/17 16:40:52 this one is not used
clamy 2013/09/18 16:17:15 Done.
145 using simple_util::GetEntryHashKey; 145 using simple_util::GetEntryHashKey;
146 using simple_util::GetFilenameFromEntryHashAndIndex; 146 using simple_util::GetFilenameFromEntryHashAndFileIndex;
147 using simple_util::GetDataSizeFromKeyAndFileSize; 147 using simple_util::GetDataSizeFromKeyAndFileSize;
148 using simple_util::GetFileSizeFromKeyAndDataSize; 148 using simple_util::GetFileSizeFromKeyAndDataSize;
149 using simple_util::GetFileOffsetFromKeyAndDataOffset; 149 using simple_util::GetFileIndexFromStreamIndex;
150 150
151 SimpleEntryStat::SimpleEntryStat() {} 151 SimpleEntryStat::SimpleEntryStat() {}
pasko 2013/09/17 16:40:52 we do not need this constructor
clamy 2013/09/18 16:17:15 Done.
152 152
153 SimpleEntryStat::SimpleEntryStat(base::Time last_used_p, 153 SimpleEntryStat::SimpleEntryStat(base::Time last_used_p,
154 base::Time last_modified_p, 154 base::Time last_modified_p,
155 const int32 data_size_p[]) 155 const int32 data_size_p[])
156 : last_used(last_used_p), 156 : last_used(last_used_p),
157 last_modified(last_modified_p) { 157 last_modified(last_modified_p) {
158 memcpy(data_size, data_size_p, sizeof(data_size)); 158 memcpy(data_size, data_size_p, sizeof(data_size));
159 } 159 }
160 160
161 int SimpleEntryStat::GetOffsetInFile(const std::string& key,
162 int offset,
163 int stream_index) const {
164 const int64 headers_size = sizeof(SimpleFileHeader) + key.size();
165 const int64 additional_offset =
166 stream_index == 0 ? data_size[1] + sizeof(SimpleFileEOF) : 0;
167 return headers_size + offset + additional_offset;
168 }
169
170 int SimpleEntryStat::GetEOFOffsetInFile(const std::string& key,
171 int stream_index) const {
172 return GetOffsetInFile(key, data_size[stream_index], stream_index);
173 }
174
175 int SimpleEntryStat::GetLastEOFOffsetInFile(const std::string& key,
176 int stream_index) const {
177 const int file_index = GetFileIndexFromStreamIndex(stream_index);
178 const int eof_data_offset = file_index == 0 ?
179 data_size[0] + data_size[1] + sizeof(SimpleFileEOF) : data_size[2];
180 return GetOffsetInFile(key, eof_data_offset, stream_index);
181 }
182
183 int SimpleEntryStat::GetFileSize(const std::string& key, int file_index) const {
184 const int total_data_size = file_index == 0 ?
185 data_size[0] + data_size[1] + sizeof(SimpleFileEOF) : data_size[2];
186 return GetFileSizeFromKeyAndDataSize(key, total_data_size);
187 }
188
161 SimpleEntryCreationResults::SimpleEntryCreationResults( 189 SimpleEntryCreationResults::SimpleEntryCreationResults(
162 SimpleEntryStat entry_stat) 190 SimpleEntryStat entry_stat)
163 : sync_entry(NULL), 191 : sync_entry(NULL),
164 entry_stat(entry_stat), 192 entry_stat(entry_stat),
165 result(net::OK) { 193 result(net::OK) {
166 } 194 }
167 195
168 SimpleEntryCreationResults::~SimpleEntryCreationResults() { 196 SimpleEntryCreationResults::~SimpleEntryCreationResults() {
169 } 197 }
170 198
(...skipping 28 matching lines...) Expand all
199 // static 227 // static
200 void SimpleSynchronousEntry::OpenEntry( 228 void SimpleSynchronousEntry::OpenEntry(
201 net::CacheType cache_type, 229 net::CacheType cache_type,
202 const FilePath& path, 230 const FilePath& path,
203 const uint64 entry_hash, 231 const uint64 entry_hash,
204 bool had_index, 232 bool had_index,
205 SimpleEntryCreationResults *out_results) { 233 SimpleEntryCreationResults *out_results) {
206 SimpleSynchronousEntry* sync_entry = 234 SimpleSynchronousEntry* sync_entry =
207 new SimpleSynchronousEntry(cache_type, path, "", entry_hash); 235 new SimpleSynchronousEntry(cache_type, path, "", entry_hash);
208 out_results->result = sync_entry->InitializeForOpen( 236 out_results->result = sync_entry->InitializeForOpen(
209 had_index, &out_results->entry_stat); 237 had_index, &out_results->entry_stat, &out_results->stream_0_data);
210 if (out_results->result != net::OK) { 238 if (out_results->result != net::OK) {
211 sync_entry->Doom(); 239 sync_entry->Doom();
212 delete sync_entry; 240 delete sync_entry;
213 out_results->sync_entry = NULL; 241 out_results->sync_entry = NULL;
242 out_results->stream_0_data = NULL;
214 return; 243 return;
215 } 244 }
216 out_results->sync_entry = sync_entry; 245 out_results->sync_entry = sync_entry;
217 } 246 }
218 247
219 // static 248 // static
220 void SimpleSynchronousEntry::CreateEntry( 249 void SimpleSynchronousEntry::CreateEntry(
221 net::CacheType cache_type, 250 net::CacheType cache_type,
222 const FilePath& path, 251 const FilePath& path,
223 const std::string& key, 252 const std::string& key,
(...skipping 15 matching lines...) Expand all
239 out_results->sync_entry = sync_entry; 268 out_results->sync_entry = sync_entry;
240 } 269 }
241 270
242 // TODO(gavinp): Move this function to its correct location in this .cc file. 271 // TODO(gavinp): Move this function to its correct location in this .cc file.
243 // static 272 // static
244 bool SimpleSynchronousEntry::DeleteFilesForEntryHash( 273 bool SimpleSynchronousEntry::DeleteFilesForEntryHash(
245 const FilePath& path, 274 const FilePath& path,
246 const uint64 entry_hash) { 275 const uint64 entry_hash) {
247 bool result = true; 276 bool result = true;
248 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 277 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
249 FilePath to_delete = path.AppendASCII( 278 FilePath to_delete =
250 GetFilenameFromEntryHashAndIndex(entry_hash, i)); 279 path.AppendASCII(GetFilenameFromEntryHashAndFileIndex(entry_hash, i));
251 if (!base::DeleteFile(to_delete, false)) { 280 if (!base::DeleteFile(to_delete, false)) {
252 result = false; 281 result = false;
253 DLOG(ERROR) << "Could not delete " << to_delete.MaybeAsASCII(); 282 DLOG(ERROR) << "Could not delete " << to_delete.MaybeAsASCII();
254 } 283 }
255 } 284 }
256 return result; 285 return result;
257 } 286 }
258 287
259 // static 288 // static
260 int SimpleSynchronousEntry::DoomEntry( 289 int SimpleSynchronousEntry::DoomEntry(
(...skipping 11 matching lines...) Expand all
272 const FilePath& path) { 301 const FilePath& path) {
273 const size_t did_delete_count = std::count_if( 302 const size_t did_delete_count = std::count_if(
274 key_hashes->begin(), key_hashes->end(), std::bind1st( 303 key_hashes->begin(), key_hashes->end(), std::bind1st(
275 std::ptr_fun(SimpleSynchronousEntry::DeleteFilesForEntryHash), path)); 304 std::ptr_fun(SimpleSynchronousEntry::DeleteFilesForEntryHash), path));
276 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED; 305 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED;
277 } 306 }
278 307
279 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op, 308 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op,
280 net::IOBuffer* out_buf, 309 net::IOBuffer* out_buf,
281 uint32* out_crc32, 310 uint32* out_crc32,
282 base::Time* out_last_used, 311 SimpleEntryStat* out_entry_stat,
283 int* out_result) const { 312 int* out_result) const {
284 DCHECK(initialized_); 313 DCHECK(initialized_);
285 int64 file_offset = 314 const int64 file_offset = out_entry_stat->GetOffsetInFile(
gavinp 2013/09/17 15:07:43 That doesn't look like an output parameter! Perhap
pasko 2013/09/17 16:40:52 seems like a cool simple strategy to assert agains
pasko 2013/09/18 12:03:19 .. but on the other hand I also like the uniformit
clamy 2013/09/18 16:17:15 All offset functions are now used part of EntrySta
gavinp 2013/09/18 17:20:35 Or you could just rename the parameter to remove t
clamy 2013/09/18 18:29:38 Done.
286 GetFileOffsetFromKeyAndDataOffset(key_, in_entry_op.offset); 315 key_, in_entry_op.offset, in_entry_op.index);
287 int bytes_read = ReadPlatformFile(files_[in_entry_op.index], 316 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index);
288 file_offset, 317 int bytes_read = ReadPlatformFile(
289 out_buf->data(), 318 files_[file_index], file_offset, out_buf->data(), in_entry_op.buf_len);
290 in_entry_op.buf_len);
291 if (bytes_read > 0) { 319 if (bytes_read > 0) {
292 *out_last_used = Time::Now(); 320 out_entry_stat->last_used = Time::Now();
293 *out_crc32 = crc32(crc32(0L, Z_NULL, 0), 321 *out_crc32 = crc32(crc32(0L, Z_NULL, 0),
294 reinterpret_cast<const Bytef*>(out_buf->data()), 322 reinterpret_cast<const Bytef*>(out_buf->data()),
295 bytes_read); 323 bytes_read);
296 } 324 }
297 if (bytes_read >= 0) { 325 if (bytes_read >= 0) {
298 *out_result = bytes_read; 326 *out_result = bytes_read;
299 } else { 327 } else {
300 *out_result = net::ERR_CACHE_READ_FAILURE; 328 *out_result = net::ERR_CACHE_READ_FAILURE;
301 Doom(); 329 Doom();
302 } 330 }
303 } 331 }
304 332
305 void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op, 333 void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op,
306 net::IOBuffer* in_buf, 334 net::IOBuffer* in_buf,
307 SimpleEntryStat* out_entry_stat, 335 SimpleEntryStat* out_entry_stat,
308 int* out_result) const { 336 int* out_result) const {
309 DCHECK(initialized_); 337 DCHECK(initialized_);
310 int index = in_entry_op.index; 338 int index = in_entry_op.index;
pasko 2013/09/18 12:03:19 please add a DCHECK_NE(0, index), similarly in SSE
clamy 2013/09/18 16:17:15 Done.
339 int file_index = GetFileIndexFromStreamIndex(index);
311 int offset = in_entry_op.offset; 340 int offset = in_entry_op.offset;
312 int buf_len = in_entry_op.buf_len; 341 int buf_len = in_entry_op.buf_len;
313 int truncate = in_entry_op.truncate; 342 int truncate = in_entry_op.truncate;
314 343 const int64 file_offset = out_entry_stat->GetOffsetInFile(
344 key_, in_entry_op.offset, in_entry_op.index);
315 bool extending_by_write = offset + buf_len > out_entry_stat->data_size[index]; 345 bool extending_by_write = offset + buf_len > out_entry_stat->data_size[index];
316 if (extending_by_write) { 346 if (extending_by_write) {
317 // We are extending the file, and need to insure the EOF record is zeroed. 347 // The EOF record and the eventual stream afterward need to be zeroed out.
318 const int64 file_eof_offset = GetFileOffsetFromKeyAndDataOffset( 348 const int64 file_eof_offset =
319 key_, out_entry_stat->data_size[index]); 349 out_entry_stat->GetEOFOffsetInFile(key_, index);
320 if (!TruncatePlatformFile(files_[index], file_eof_offset)) { 350 if (!TruncatePlatformFile(files_[file_index], file_eof_offset)) {
321 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE); 351 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE);
322 Doom(); 352 Doom();
323 *out_result = net::ERR_CACHE_WRITE_FAILURE; 353 *out_result = net::ERR_CACHE_WRITE_FAILURE;
324 return; 354 return;
325 } 355 }
326 } 356 }
327 const int64 file_offset = GetFileOffsetFromKeyAndDataOffset(key_, offset);
328 if (buf_len > 0) { 357 if (buf_len > 0) {
329 if (WritePlatformFile( 358 if (WritePlatformFile(
330 files_[index], file_offset, in_buf->data(), buf_len) != buf_len) { 359 files_[file_index], file_offset, in_buf->data(), buf_len) !=
360 buf_len) {
331 RecordWriteResult(cache_type_, WRITE_RESULT_WRITE_FAILURE); 361 RecordWriteResult(cache_type_, WRITE_RESULT_WRITE_FAILURE);
332 Doom(); 362 Doom();
333 *out_result = net::ERR_CACHE_WRITE_FAILURE; 363 *out_result = net::ERR_CACHE_WRITE_FAILURE;
334 return; 364 return;
335 } 365 }
336 } 366 }
337 if (!truncate && (buf_len > 0 || !extending_by_write)) { 367 if (!truncate && (buf_len > 0 || !extending_by_write)) {
338 out_entry_stat->data_size[index] = 368 out_entry_stat->data_size[index] =
339 std::max(out_entry_stat->data_size[index], offset + buf_len); 369 std::max(out_entry_stat->data_size[index], offset + buf_len);
340 } else { 370 } else {
341 if (!TruncatePlatformFile(files_[index], file_offset + buf_len)) { 371 out_entry_stat->data_size[index] = offset + buf_len;
372 int file_eof_offset = out_entry_stat->GetLastEOFOffsetInFile(key_, index);
373 if (!TruncatePlatformFile(files_[file_index], file_eof_offset)) {
342 RecordWriteResult(cache_type_, WRITE_RESULT_TRUNCATE_FAILURE); 374 RecordWriteResult(cache_type_, WRITE_RESULT_TRUNCATE_FAILURE);
343 Doom(); 375 Doom();
344 *out_result = net::ERR_CACHE_WRITE_FAILURE; 376 *out_result = net::ERR_CACHE_WRITE_FAILURE;
345 return; 377 return;
346 } 378 }
347 out_entry_stat->data_size[index] = offset + buf_len;
pasko 2013/09/18 12:03:19 nit: is there a reason to move this line above th
clamy 2013/09/18 16:17:15 Otherwise out_entry_stat will return the wrong off
348 } 379 }
349 380
350 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS); 381 RecordWriteResult(cache_type_, WRITE_RESULT_SUCCESS);
351 out_entry_stat->last_used = out_entry_stat->last_modified = Time::Now(); 382 out_entry_stat->last_used = out_entry_stat->last_modified = Time::Now();
352 *out_result = buf_len; 383 *out_result = buf_len;
353 } 384 }
354 385
355 void SimpleSynchronousEntry::CheckEOFRecord(int index, 386 void SimpleSynchronousEntry::CheckEOFRecord(int index,
356 int32 data_size, 387 const SimpleEntryStat& entry_stat,
357 uint32 expected_crc32, 388 uint32 expected_crc32,
358 int* out_result) const { 389 int* out_result) const {
359 DCHECK(initialized_); 390 DCHECK(initialized_);
360 391 uint32 crc32;
361 SimpleFileEOF eof_record; 392 bool has_crc32;
362 int64 file_offset = GetFileOffsetFromKeyAndDataOffset(key_, data_size); 393 int stream_size;
363 if (ReadPlatformFile(files_[index], 394 *out_result =
364 file_offset, 395 GetEOFRecordData(index, entry_stat, &has_crc32, &crc32, &stream_size);
365 reinterpret_cast<char*>(&eof_record), 396 if (*out_result != net::OK) {
366 sizeof(eof_record)) != sizeof(eof_record)) {
367 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE);
368 Doom(); 397 Doom();
369 *out_result = net::ERR_CACHE_CHECKSUM_READ_FAILURE;
370 return; 398 return;
371 } 399 }
372 400 if (has_crc32 && crc32 != expected_crc32) {
373 if (eof_record.final_magic_number != kSimpleFinalMagicNumber) { 401 DLOG(INFO) << "Eof record had bad crc.";
pasko 2013/09/18 12:03:19 nit: s/Eof/EOF/, same in other places
clamy 2013/09/18 16:17:15 Done.
374 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH); 402 *out_result = net::ERR_CACHE_CHECKSUM_MISMATCH;
375 DLOG(INFO) << "eof record had bad magic number."; 403 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH);
376 Doom(); 404 Doom();
377 *out_result = net::ERR_CACHE_CHECKSUM_READ_FAILURE;
378 return; 405 return;
379 } 406 }
380
381 const bool has_crc = (eof_record.flags & SimpleFileEOF::FLAG_HAS_CRC32) ==
382 SimpleFileEOF::FLAG_HAS_CRC32;
383 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_, has_crc);
384 if (has_crc && eof_record.data_crc32 != expected_crc32) {
385 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH);
386 DLOG(INFO) << "eof record had bad crc.";
387 Doom();
388 *out_result = net::ERR_CACHE_CHECKSUM_MISMATCH;
389 return;
390 }
391
392 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); 407 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS);
393 *out_result = net::OK;
394 } 408 }
395 409
396 void SimpleSynchronousEntry::Close( 410 void SimpleSynchronousEntry::Close(
397 const SimpleEntryStat& entry_stat, 411 const SimpleEntryStat& entry_stat,
398 scoped_ptr<std::vector<CRCRecord> > crc32s_to_write) { 412 scoped_ptr<std::vector<CRCRecord> > crc32s_to_write,
413 net::GrowableIOBuffer* stream_0_data) {
414 if (!stream_0_data) {
415 if (entry_stat.data_size[0])
416 Doom();
417 } else {
418 // Write stream 0 data.
419 int stream_0_offset = entry_stat.GetOffsetInFile(key_, 0, 0);
420 if (WritePlatformFile(files_[0],
421 stream_0_offset,
422 stream_0_data->data(),
423 entry_stat.data_size[0]) != entry_stat.data_size[0]) {
424 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE);
425 DLOG(INFO) << "Could not write stream 0 data.";
426 Doom();
427 }
428 }
429
399 for (std::vector<CRCRecord>::const_iterator it = crc32s_to_write->begin(); 430 for (std::vector<CRCRecord>::const_iterator it = crc32s_to_write->begin();
400 it != crc32s_to_write->end(); ++it) { 431 it != crc32s_to_write->end(); ++it) {
401 SimpleFileEOF eof_record; 432 SimpleFileEOF eof_record;
433 int index = it->index;
434 eof_record.stream_size = entry_stat.data_size[index];
402 eof_record.final_magic_number = kSimpleFinalMagicNumber; 435 eof_record.final_magic_number = kSimpleFinalMagicNumber;
403 eof_record.flags = 0; 436 eof_record.flags = 0;
404 if (it->has_crc32) 437 if (it->has_crc32)
405 eof_record.flags |= SimpleFileEOF::FLAG_HAS_CRC32; 438 eof_record.flags |= SimpleFileEOF::FLAG_HAS_CRC32;
406 eof_record.data_crc32 = it->data_crc32; 439 eof_record.data_crc32 = it->data_crc32;
407 int64 file_offset = GetFileOffsetFromKeyAndDataOffset( 440 int file_index = GetFileIndexFromStreamIndex(index);
408 key_, entry_stat.data_size[it->index]); 441 int eof_offset = entry_stat.GetEOFOffsetInFile(key_, index);
409 if (WritePlatformFile(files_[it->index], 442 if (WritePlatformFile(files_[file_index],
pasko 2013/09/18 15:08:16 With your other CL for testing all streams (crrev.
clamy 2013/09/18 16:17:15 Done.
410 file_offset, 443 eof_offset,
411 reinterpret_cast<const char*>(&eof_record), 444 reinterpret_cast<const char*>(&eof_record),
412 sizeof(eof_record)) != sizeof(eof_record)) { 445 sizeof(eof_record)) != sizeof(eof_record)) {
413 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE); 446 RecordCloseResult(cache_type_, CLOSE_RESULT_WRITE_FAILURE);
414 DLOG(INFO) << "Could not write eof record."; 447 DLOG(INFO) << "Could not write eof record.";
415 Doom(); 448 Doom();
416 break; 449 break;
417 } 450 }
418 const int64 file_size = file_offset + sizeof(eof_record); 451 }
452 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
453 bool did_close_file = ClosePlatformFile(files_[i]);
454 CHECK(did_close_file);
pasko 2013/09/18 12:03:19 we don't want to crash the browser here on a file
clamy 2013/09/18 16:17:15 Done.
455 const int64 file_size = entry_stat.GetFileSize(key_, i);
419 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, 456 SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
420 "LastClusterSize", cache_type_, 457 "LastClusterSize", cache_type_,
421 file_size % 4096, 0, 4097, 50); 458 file_size % 4096, 0, 4097, 50);
422 const int64 cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0; 459 const int64 cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0;
423 SIMPLE_CACHE_UMA(PERCENTAGE, 460 SIMPLE_CACHE_UMA(PERCENTAGE,
424 "LastClusterLossPercent", cache_type_, 461 "LastClusterLossPercent", cache_type_,
425 cluster_loss * 100 / (cluster_loss + file_size)); 462 cluster_loss * 100 / (cluster_loss + file_size));
426 } 463 }
427
428 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
429 bool did_close_file = ClosePlatformFile(files_[i]);
430 CHECK(did_close_file);
431 }
432 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); 464 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS);
433 have_open_files_ = false; 465 have_open_files_ = false;
434 delete this; 466 delete this;
435 } 467 }
436 468
437 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type, 469 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type,
438 const FilePath& path, 470 const FilePath& path,
439 const std::string& key, 471 const std::string& key,
440 const uint64 entry_hash) 472 const uint64 entry_hash)
441 : cache_type_(cache_type), 473 : cache_type_(cache_type),
(...skipping 11 matching lines...) Expand all
453 DCHECK(!(have_open_files_ && initialized_)); 485 DCHECK(!(have_open_files_ && initialized_));
454 if (have_open_files_) 486 if (have_open_files_)
455 CloseFiles(); 487 CloseFiles();
456 } 488 }
457 489
458 bool SimpleSynchronousEntry::OpenOrCreateFiles( 490 bool SimpleSynchronousEntry::OpenOrCreateFiles(
459 bool create, 491 bool create,
460 bool had_index, 492 bool had_index,
461 SimpleEntryStat* out_entry_stat) { 493 SimpleEntryStat* out_entry_stat) {
462 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 494 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
463 FilePath filename = path_.AppendASCII( 495 FilePath filename =
464 GetFilenameFromEntryHashAndIndex(entry_hash_, i)); 496 path_.AppendASCII(GetFilenameFromEntryHashAndFileIndex(entry_hash_, i));
465 int flags = PLATFORM_FILE_READ | PLATFORM_FILE_WRITE; 497 int flags = PLATFORM_FILE_READ | PLATFORM_FILE_WRITE;
466 if (create) 498 if (create)
467 flags |= PLATFORM_FILE_CREATE; 499 flags |= PLATFORM_FILE_CREATE;
468 else 500 else
469 flags |= PLATFORM_FILE_OPEN; 501 flags |= PLATFORM_FILE_OPEN;
470 PlatformFileError error; 502 PlatformFileError error;
471 files_[i] = CreatePlatformFile(filename, flags, NULL, &error); 503 files_[i] = CreatePlatformFile(filename, flags, NULL, &error);
472 if (error != PLATFORM_FILE_OK) { 504 if (error != PLATFORM_FILE_OK) {
473 // TODO(ttuttle,gavinp): Remove one each of these triplets of histograms. 505 // TODO(ttuttle,gavinp): Remove one each of these triplets of histograms.
474 // We can calculate the third as the sum or difference of the other two. 506 // We can calculate the third as the sum or difference of the other two.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 DLOG_IF(INFO, !did_close) << "Could not close file " 542 DLOG_IF(INFO, !did_close) << "Could not close file "
511 << filename.MaybeAsASCII(); 543 << filename.MaybeAsASCII();
512 } 544 }
513 return false; 545 return false;
514 } 546 }
515 } 547 }
516 548
517 have_open_files_ = true; 549 have_open_files_ = true;
518 if (create) { 550 if (create) {
519 out_entry_stat->last_modified = out_entry_stat->last_used = Time::Now(); 551 out_entry_stat->last_modified = out_entry_stat->last_used = Time::Now();
520 for (int i = 0; i < kSimpleEntryFileCount; ++i) 552 for (int i = 0; i < kSimpleEntryStreamCount; ++i)
521 out_entry_stat->data_size[i] = 0; 553 out_entry_stat->data_size[i] = 0;
522 } else { 554 } else {
523 base::TimeDelta entry_age = base::Time::Now() - base::Time::UnixEpoch(); 555 base::TimeDelta entry_age = base::Time::Now() - base::Time::UnixEpoch();
524 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 556 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
525 PlatformFileInfo file_info; 557 PlatformFileInfo file_info;
526 bool success = GetPlatformFileInfo(files_[i], &file_info); 558 bool success = GetPlatformFileInfo(files_[i], &file_info);
527 base::Time file_last_modified; 559 base::Time file_last_modified;
528 if (!success) { 560 if (!success) {
529 DLOG(WARNING) << "Could not get platform file info."; 561 DLOG(WARNING) << "Could not get platform file info.";
530 continue; 562 continue;
531 } 563 }
532 out_entry_stat->last_used = file_info.last_accessed; 564 out_entry_stat->last_used = file_info.last_accessed;
533 if (simple_util::GetMTime(path_, &file_last_modified)) 565 if (simple_util::GetMTime(path_, &file_last_modified))
534 out_entry_stat->last_modified = file_last_modified; 566 out_entry_stat->last_modified = file_last_modified;
535 else 567 else
536 out_entry_stat->last_modified = file_info.last_modified; 568 out_entry_stat->last_modified = file_info.last_modified;
537 569
538 base::TimeDelta stream_age = 570 base::TimeDelta stream_age =
539 base::Time::Now() - out_entry_stat->last_modified; 571 base::Time::Now() - out_entry_stat->last_modified;
540 if (stream_age < entry_age) 572 if (stream_age < entry_age)
541 entry_age = stream_age; 573 entry_age = stream_age;
542 574
543 // Keep the file size in |data size_| briefly until the key is initialized 575 // Keep the file size in |data size_| temporarily until the data sizes are
544 // properly. 576 // initialized correctly.
pasko 2013/09/18 12:03:19 Let's write a more detailed comment here. The 'dat
clamy 2013/09/18 16:17:15 Done.
545 out_entry_stat->data_size[i] = file_info.size; 577 out_entry_stat->data_size[i + 1] = file_info.size;
546 } 578 }
547 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, 579 SIMPLE_CACHE_UMA(CUSTOM_COUNTS,
548 "SyncOpenEntryAge", cache_type_, 580 "SyncOpenEntryAge", cache_type_,
549 entry_age.InHours(), 1, 1000, 50); 581 entry_age.InHours(), 1, 1000, 50);
550 } 582 }
551 583
552 return true; 584 return true;
553 } 585 }
554 586
555 void SimpleSynchronousEntry::CloseFiles() { 587 void SimpleSynchronousEntry::CloseFiles() {
556 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 588 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
557 DCHECK_NE(kInvalidPlatformFileValue, files_[i]); 589 DCHECK_NE(kInvalidPlatformFileValue, files_[i]);
558 bool did_close = ClosePlatformFile(files_[i]); 590 bool did_close = ClosePlatformFile(files_[i]);
559 DCHECK(did_close); 591 DCHECK(did_close);
560 } 592 }
561 } 593 }
562 594
563 int SimpleSynchronousEntry::InitializeForOpen(bool had_index, 595 int SimpleSynchronousEntry::InitializeForOpen(
564 SimpleEntryStat* out_entry_stat) { 596 bool had_index,
597 SimpleEntryStat* out_entry_stat,
598 scoped_refptr<net::GrowableIOBuffer>* stream_0_data) {
565 DCHECK(!initialized_); 599 DCHECK(!initialized_);
566 if (!OpenOrCreateFiles(false, had_index, out_entry_stat)) 600 if (!OpenOrCreateFiles(false, had_index, out_entry_stat))
567 return net::ERR_FAILED; 601 return net::ERR_FAILED;
568
569 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 602 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
570 SimpleFileHeader header; 603 SimpleFileHeader header;
571 int header_read_result = 604 int header_read_result =
572 ReadPlatformFile(files_[i], 0, reinterpret_cast<char*>(&header), 605 ReadPlatformFile(files_[i], 0, reinterpret_cast<char*>(&header),
573 sizeof(header)); 606 sizeof(header));
574 if (header_read_result != sizeof(header)) { 607 if (header_read_result != sizeof(header)) {
575 DLOG(WARNING) << "Cannot read header from entry."; 608 DLOG(WARNING) << "Cannot read header from entry.";
576 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_HEADER, had_index); 609 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_HEADER, had_index);
577 return net::ERR_FAILED; 610 return net::ERR_FAILED;
578 } 611 }
(...skipping 16 matching lines...) Expand all
595 scoped_ptr<char[]> key(new char[header.key_length]); 628 scoped_ptr<char[]> key(new char[header.key_length]);
596 int key_read_result = ReadPlatformFile(files_[i], sizeof(header), 629 int key_read_result = ReadPlatformFile(files_[i], sizeof(header),
597 key.get(), header.key_length); 630 key.get(), header.key_length);
598 if (key_read_result != implicit_cast<int>(header.key_length)) { 631 if (key_read_result != implicit_cast<int>(header.key_length)) {
599 DLOG(WARNING) << "Cannot read key from entry."; 632 DLOG(WARNING) << "Cannot read key from entry.";
600 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index); 633 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_CANT_READ_KEY, had_index);
601 return net::ERR_FAILED; 634 return net::ERR_FAILED;
602 } 635 }
603 636
604 key_ = std::string(key.get(), header.key_length); 637 key_ = std::string(key.get(), header.key_length);
605 out_entry_stat->data_size[i] = 638 if (i == 0) {
606 GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size[i]); 639 // File size for stream 0 has been stored temporarily in data_size[1].
607 if (out_entry_stat->data_size[i] < 0) { 640 int total_data_size =
608 // This entry can't possibly be valid, as it does not have enough space to 641 GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size[1]);
609 // store a valid SimpleFileEOF record. 642 int ret_value_stream_0 = ReadAndValidateStream0(
610 return net::ERR_FAILED; 643 total_data_size, out_entry_stat, stream_0_data);
644 if (ret_value_stream_0 != net::OK)
645 return ret_value_stream_0;
646 } else {
647 out_entry_stat->data_size[2] =
648 GetDataSizeFromKeyAndFileSize(key_, out_entry_stat->data_size[2]);
649 if (out_entry_stat->data_size[2] < 0)
650 return net::ERR_FAILED;
611 } 651 }
612 652
613 if (base::Hash(key.get(), header.key_length) != header.key_hash) { 653 if (base::Hash(key.get(), header.key_length) != header.key_hash) {
614 DLOG(WARNING) << "Hash mismatch on key."; 654 DLOG(WARNING) << "Hash mismatch on key.";
615 RecordSyncOpenResult( 655 RecordSyncOpenResult(
616 cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index); 656 cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index);
617 return net::ERR_FAILED; 657 return net::ERR_FAILED;
618 } 658 }
619 } 659 }
620 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SUCCESS, had_index); 660 RecordSyncOpenResult(cache_type_, OPEN_ENTRY_SUCCESS, had_index);
(...skipping 10 matching lines...) Expand all
631 return net::ERR_FILE_EXISTS; 671 return net::ERR_FILE_EXISTS;
632 } 672 }
633 for (int i = 0; i < kSimpleEntryFileCount; ++i) { 673 for (int i = 0; i < kSimpleEntryFileCount; ++i) {
634 SimpleFileHeader header; 674 SimpleFileHeader header;
635 header.initial_magic_number = kSimpleInitialMagicNumber; 675 header.initial_magic_number = kSimpleInitialMagicNumber;
636 header.version = kSimpleVersion; 676 header.version = kSimpleVersion;
637 677
638 header.key_length = key_.size(); 678 header.key_length = key_.size();
639 header.key_hash = base::Hash(key_); 679 header.key_hash = base::Hash(key_);
640 680
641 if (WritePlatformFile(files_[i], 0, reinterpret_cast<char*>(&header), 681 if (WritePlatformFile(
642 sizeof(header)) != sizeof(header)) { 682 files_[i], 0, reinterpret_cast<char*>(&header), sizeof(header)) !=
643 DLOG(WARNING) << "Could not write headers to new cache entry."; 683 sizeof(header)) {
684 DLOG(WARNING) << "Could not write cache file header to cache entry.";
644 RecordSyncCreateResult( 685 RecordSyncCreateResult(
645 cache_type_, CREATE_ENTRY_CANT_WRITE_HEADER, had_index); 686 cache_type_, CREATE_ENTRY_CANT_WRITE_HEADER, had_index);
646 return net::ERR_FAILED; 687 return net::ERR_FAILED;
647 } 688 }
648 689
649 if (WritePlatformFile(files_[i], sizeof(header), key_.data(), 690 if (WritePlatformFile(
650 key_.size()) != implicit_cast<int>(key_.size())) { 691 files_[i], sizeof(SimpleFileHeader), key_.data(), key_.size()) !=
692 implicit_cast<int>(key_.size())) {
651 DLOG(WARNING) << "Could not write keys to new cache entry."; 693 DLOG(WARNING) << "Could not write keys to new cache entry.";
652 RecordSyncCreateResult( 694 RecordSyncCreateResult(
653 cache_type_, CREATE_ENTRY_CANT_WRITE_KEY, had_index); 695 cache_type_, CREATE_ENTRY_CANT_WRITE_KEY, had_index);
654 return net::ERR_FAILED; 696 return net::ERR_FAILED;
655 } 697 }
656 } 698 }
657 RecordSyncCreateResult(cache_type_, CREATE_ENTRY_SUCCESS, had_index); 699 RecordSyncCreateResult(cache_type_, CREATE_ENTRY_SUCCESS, had_index);
658 initialized_ = true; 700 initialized_ = true;
659 return net::OK; 701 return net::OK;
660 } 702 }
661 703
704 int SimpleSynchronousEntry::ReadAndValidateStream0(
705 int total_data_size,
706 SimpleEntryStat* out_entry_stat,
707 scoped_refptr<net::GrowableIOBuffer>* stream_0_data) const {
708 // Temporarily assign all the data size to stream 1 in order to read the
709 // EOF record for stream 0, which contains the size of stream 0.
710 out_entry_stat->data_size[0] = 0;
711 out_entry_stat->data_size[1] = total_data_size - sizeof(SimpleFileEOF);
712
713 bool has_crc32;
714 uint32 read_crc32;
715 int stream_0_size;
716 int ret_value_crc32 = GetEOFRecordData(
717 0, *out_entry_stat, &has_crc32, &read_crc32, &stream_0_size);
718 if (ret_value_crc32 != net::OK)
719 return ret_value_crc32;
720
721 if (stream_0_size > out_entry_stat->data_size[1])
722 return net::ERR_FAILED;
723
724 // These are the real values of data size.
725 out_entry_stat->data_size[0] = stream_0_size;
pasko 2013/09/18 12:03:19 so the function ReadAndValidateStream0() also upda
726 out_entry_stat->data_size[1] -= stream_0_size;
727
728 // Put stream 0 data in memory.
729 *stream_0_data = NULL;
pasko 2013/09/18 12:03:19 is there a reason in touching this here? the value
clamy 2013/09/18 16:17:15 Done.
730 if (stream_0_size != 0) {
731 *stream_0_data = new net::GrowableIOBuffer();
732 (*stream_0_data)->SetCapacity(stream_0_size);
733 int file_offset = out_entry_stat->GetOffsetInFile(key_, 0, 0);
734 int bytes_read = ReadPlatformFile(
735 files_[0], file_offset, (*stream_0_data)->data(), stream_0_size);
736 if (bytes_read != stream_0_size)
737 return net::ERR_FAILED;
738 }
739
740 // Check the CRC32.
741 uint32 expected_crc32 =
742 stream_0_size == 0
743 ? crc32(0, Z_NULL, 0)
744 : crc32(crc32(0, Z_NULL, 0),
745 reinterpret_cast<const Bytef*>((*stream_0_data)->data()),
746 stream_0_size);
747 if (has_crc32 && read_crc32 != expected_crc32) {
748 DLOG(INFO) << "Eof record had bad crc.";
749 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH);
750 return net::ERR_FAILED;
751 }
752 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS);
753 return net::OK;
754 }
755
756 int SimpleSynchronousEntry::GetEOFRecordData(int index,
757 const SimpleEntryStat& entry_stat,
758 bool* out_has_crc32,
759 uint32* out_crc32,
760 int* out_data_size) const {
761 SimpleFileEOF eof_record;
762 int file_offset = entry_stat.GetEOFOffsetInFile(key_, index);
763 int file_index = GetFileIndexFromStreamIndex(index);
764 if (ReadPlatformFile(files_[file_index],
765 file_offset,
766 reinterpret_cast<char*>(&eof_record),
767 sizeof(eof_record)) != sizeof(eof_record)) {
768 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE);
769 return net::ERR_CACHE_CHECKSUM_READ_FAILURE;
pasko 2013/09/18 12:03:19 fun fact: cache checksum read failure can happen e
770 }
771
772 if (eof_record.final_magic_number != kSimpleFinalMagicNumber) {
773 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_MAGIC_NUMBER_MISMATCH);
774 DLOG(INFO) << "Eof record had bad magic number.";
775 return net::ERR_CACHE_CHECKSUM_READ_FAILURE;
776 }
777
778 *out_has_crc32 = (eof_record.flags & SimpleFileEOF::FLAG_HAS_CRC32) ==
779 SimpleFileEOF::FLAG_HAS_CRC32;
780 *out_crc32 = eof_record.data_crc32;
781 *out_data_size = eof_record.stream_size;
782 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_, *out_has_crc32);
783 return net::OK;
784 }
785
662 void SimpleSynchronousEntry::Doom() const { 786 void SimpleSynchronousEntry::Doom() const {
663 // TODO(gavinp): Consider if we should guard against redundant Doom() calls. 787 // TODO(gavinp): Consider if we should guard against redundant Doom() calls.
664 DeleteFilesForEntryHash(path_, entry_hash_); 788 DeleteFilesForEntryHash(path_, entry_hash_);
665 } 789 }
666 790
667 } // namespace disk_cache 791 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698