| OLD | NEW |
| 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 | 118 |
| 119 using simple_util::GetEntryHashKey; | 119 using simple_util::GetEntryHashKey; |
| 120 using simple_util::GetFilenameFromEntryHashAndFileIndex; | 120 using simple_util::GetFilenameFromEntryHashAndFileIndex; |
| 121 using simple_util::GetSparseFilenameFromEntryHash; | 121 using simple_util::GetSparseFilenameFromEntryHash; |
| 122 using simple_util::GetDataSizeFromKeyAndFileSize; | 122 using simple_util::GetDataSizeFromKeyAndFileSize; |
| 123 using simple_util::GetFileSizeFromKeyAndDataSize; | 123 using simple_util::GetFileSizeFromKeyAndDataSize; |
| 124 using simple_util::GetFileIndexFromStreamIndex; | 124 using simple_util::GetFileIndexFromStreamIndex; |
| 125 | 125 |
| 126 SimpleEntryStat::SimpleEntryStat(base::Time last_used, | 126 SimpleEntryStat::SimpleEntryStat(base::Time last_used, |
| 127 base::Time last_modified, | 127 base::Time last_modified, |
| 128 const int32 data_size[], | 128 const int32_t data_size[], |
| 129 const int32 sparse_data_size) | 129 const int32_t sparse_data_size) |
| 130 : last_used_(last_used), | 130 : last_used_(last_used), |
| 131 last_modified_(last_modified), | 131 last_modified_(last_modified), |
| 132 sparse_data_size_(sparse_data_size) { | 132 sparse_data_size_(sparse_data_size) { |
| 133 memcpy(data_size_, data_size, sizeof(data_size_)); | 133 memcpy(data_size_, data_size, sizeof(data_size_)); |
| 134 } | 134 } |
| 135 | 135 |
| 136 int SimpleEntryStat::GetOffsetInFile(const std::string& key, | 136 int SimpleEntryStat::GetOffsetInFile(const std::string& key, |
| 137 int offset, | 137 int offset, |
| 138 int stream_index) const { | 138 int stream_index) const { |
| 139 const size_t headers_size = sizeof(SimpleFileHeader) + key.size(); | 139 const size_t headers_size = sizeof(SimpleFileHeader) + key.size(); |
| 140 const size_t additional_offset = | 140 const size_t additional_offset = |
| 141 stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0; | 141 stream_index == 0 ? data_size_[1] + sizeof(SimpleFileEOF) : 0; |
| 142 return headers_size + offset + additional_offset; | 142 return headers_size + offset + additional_offset; |
| 143 } | 143 } |
| 144 | 144 |
| 145 int SimpleEntryStat::GetEOFOffsetInFile(const std::string& key, | 145 int SimpleEntryStat::GetEOFOffsetInFile(const std::string& key, |
| 146 int stream_index) const { | 146 int stream_index) const { |
| 147 return GetOffsetInFile(key, data_size_[stream_index], stream_index); | 147 return GetOffsetInFile(key, data_size_[stream_index], stream_index); |
| 148 } | 148 } |
| 149 | 149 |
| 150 int SimpleEntryStat::GetLastEOFOffsetInFile(const std::string& key, | 150 int SimpleEntryStat::GetLastEOFOffsetInFile(const std::string& key, |
| 151 int stream_index) const { | 151 int stream_index) const { |
| 152 const int file_index = GetFileIndexFromStreamIndex(stream_index); | 152 const int file_index = GetFileIndexFromStreamIndex(stream_index); |
| 153 const int eof_data_offset = | 153 const int eof_data_offset = |
| 154 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) | 154 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) |
| 155 : data_size_[2]; | 155 : data_size_[2]; |
| 156 return GetOffsetInFile(key, eof_data_offset, stream_index); | 156 return GetOffsetInFile(key, eof_data_offset, stream_index); |
| 157 } | 157 } |
| 158 | 158 |
| 159 int64 SimpleEntryStat::GetFileSize(const std::string& key, | 159 int64_t SimpleEntryStat::GetFileSize(const std::string& key, |
| 160 int file_index) const { | 160 int file_index) const { |
| 161 const int32 total_data_size = | 161 const int32_t total_data_size = |
| 162 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) | 162 file_index == 0 ? data_size_[0] + data_size_[1] + sizeof(SimpleFileEOF) |
| 163 : data_size_[2]; | 163 : data_size_[2]; |
| 164 return GetFileSizeFromKeyAndDataSize(key, total_data_size); | 164 return GetFileSizeFromKeyAndDataSize(key, total_data_size); |
| 165 } | 165 } |
| 166 | 166 |
| 167 SimpleEntryCreationResults::SimpleEntryCreationResults( | 167 SimpleEntryCreationResults::SimpleEntryCreationResults( |
| 168 SimpleEntryStat entry_stat) | 168 SimpleEntryStat entry_stat) |
| 169 : sync_entry(NULL), | 169 : sync_entry(NULL), |
| 170 entry_stat(entry_stat), | 170 entry_stat(entry_stat), |
| 171 stream_0_crc32(crc32(0, Z_NULL, 0)), | 171 stream_0_crc32(crc32(0, Z_NULL, 0)), |
| 172 result(net::OK) { | 172 result(net::OK) { |
| 173 } | 173 } |
| 174 | 174 |
| 175 SimpleEntryCreationResults::~SimpleEntryCreationResults() { | 175 SimpleEntryCreationResults::~SimpleEntryCreationResults() { |
| 176 } | 176 } |
| 177 | 177 |
| 178 SimpleSynchronousEntry::CRCRecord::CRCRecord() : index(-1), | 178 SimpleSynchronousEntry::CRCRecord::CRCRecord() : index(-1), |
| 179 has_crc32(false), | 179 has_crc32(false), |
| 180 data_crc32(0) { | 180 data_crc32(0) { |
| 181 } | 181 } |
| 182 | 182 |
| 183 SimpleSynchronousEntry::CRCRecord::CRCRecord(int index_p, | 183 SimpleSynchronousEntry::CRCRecord::CRCRecord(int index_p, |
| 184 bool has_crc32_p, | 184 bool has_crc32_p, |
| 185 uint32 data_crc32_p) | 185 uint32_t data_crc32_p) |
| 186 : index(index_p), | 186 : index(index_p), has_crc32(has_crc32_p), data_crc32(data_crc32_p) {} |
| 187 has_crc32(has_crc32_p), | |
| 188 data_crc32(data_crc32_p) {} | |
| 189 | 187 |
| 190 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p, | 188 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p, |
| 191 int offset_p, | 189 int offset_p, |
| 192 int buf_len_p) | 190 int buf_len_p) |
| 193 : index(index_p), | 191 : index(index_p), |
| 194 offset(offset_p), | 192 offset(offset_p), |
| 195 buf_len(buf_len_p) {} | 193 buf_len(buf_len_p) {} |
| 196 | 194 |
| 197 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p, | 195 SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p, |
| 198 int offset_p, | 196 int offset_p, |
| 199 int buf_len_p, | 197 int buf_len_p, |
| 200 bool truncate_p, | 198 bool truncate_p, |
| 201 bool doomed_p) | 199 bool doomed_p) |
| 202 : index(index_p), | 200 : index(index_p), |
| 203 offset(offset_p), | 201 offset(offset_p), |
| 204 buf_len(buf_len_p), | 202 buf_len(buf_len_p), |
| 205 truncate(truncate_p), | 203 truncate(truncate_p), |
| 206 doomed(doomed_p) {} | 204 doomed(doomed_p) {} |
| 207 | 205 |
| 208 SimpleSynchronousEntry::EntryOperationData::EntryOperationData( | 206 SimpleSynchronousEntry::EntryOperationData::EntryOperationData( |
| 209 int64 sparse_offset_p, | 207 int64_t sparse_offset_p, |
| 210 int buf_len_p) | 208 int buf_len_p) |
| 211 : sparse_offset(sparse_offset_p), | 209 : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {} |
| 212 buf_len(buf_len_p) {} | |
| 213 | 210 |
| 214 // static | 211 // static |
| 215 void SimpleSynchronousEntry::OpenEntry( | 212 void SimpleSynchronousEntry::OpenEntry( |
| 216 net::CacheType cache_type, | 213 net::CacheType cache_type, |
| 217 const FilePath& path, | 214 const FilePath& path, |
| 218 const uint64 entry_hash, | 215 const uint64_t entry_hash, |
| 219 bool had_index, | 216 bool had_index, |
| 220 SimpleEntryCreationResults *out_results) { | 217 SimpleEntryCreationResults* out_results) { |
| 221 base::ElapsedTimer open_time; | 218 base::ElapsedTimer open_time; |
| 222 SimpleSynchronousEntry* sync_entry = | 219 SimpleSynchronousEntry* sync_entry = |
| 223 new SimpleSynchronousEntry(cache_type, path, "", entry_hash); | 220 new SimpleSynchronousEntry(cache_type, path, "", entry_hash); |
| 224 out_results->result = | 221 out_results->result = |
| 225 sync_entry->InitializeForOpen(had_index, | 222 sync_entry->InitializeForOpen(had_index, |
| 226 &out_results->entry_stat, | 223 &out_results->entry_stat, |
| 227 &out_results->stream_0_data, | 224 &out_results->stream_0_data, |
| 228 &out_results->stream_0_crc32); | 225 &out_results->stream_0_crc32); |
| 229 if (out_results->result != net::OK) { | 226 if (out_results->result != net::OK) { |
| 230 sync_entry->Doom(); | 227 sync_entry->Doom(); |
| 231 delete sync_entry; | 228 delete sync_entry; |
| 232 out_results->sync_entry = NULL; | 229 out_results->sync_entry = NULL; |
| 233 out_results->stream_0_data = NULL; | 230 out_results->stream_0_data = NULL; |
| 234 return; | 231 return; |
| 235 } | 232 } |
| 236 UMA_HISTOGRAM_TIMES("SimpleCache.DiskOpenLatency", open_time.Elapsed()); | 233 UMA_HISTOGRAM_TIMES("SimpleCache.DiskOpenLatency", open_time.Elapsed()); |
| 237 out_results->sync_entry = sync_entry; | 234 out_results->sync_entry = sync_entry; |
| 238 } | 235 } |
| 239 | 236 |
| 240 // static | 237 // static |
| 241 void SimpleSynchronousEntry::CreateEntry( | 238 void SimpleSynchronousEntry::CreateEntry( |
| 242 net::CacheType cache_type, | 239 net::CacheType cache_type, |
| 243 const FilePath& path, | 240 const FilePath& path, |
| 244 const std::string& key, | 241 const std::string& key, |
| 245 const uint64 entry_hash, | 242 const uint64_t entry_hash, |
| 246 bool had_index, | 243 bool had_index, |
| 247 SimpleEntryCreationResults *out_results) { | 244 SimpleEntryCreationResults* out_results) { |
| 248 DCHECK_EQ(entry_hash, GetEntryHashKey(key)); | 245 DCHECK_EQ(entry_hash, GetEntryHashKey(key)); |
| 249 SimpleSynchronousEntry* sync_entry = | 246 SimpleSynchronousEntry* sync_entry = |
| 250 new SimpleSynchronousEntry(cache_type, path, key, entry_hash); | 247 new SimpleSynchronousEntry(cache_type, path, key, entry_hash); |
| 251 out_results->result = sync_entry->InitializeForCreate( | 248 out_results->result = sync_entry->InitializeForCreate( |
| 252 had_index, &out_results->entry_stat); | 249 had_index, &out_results->entry_stat); |
| 253 if (out_results->result != net::OK) { | 250 if (out_results->result != net::OK) { |
| 254 if (out_results->result != net::ERR_FILE_EXISTS) | 251 if (out_results->result != net::ERR_FILE_EXISTS) |
| 255 sync_entry->Doom(); | 252 sync_entry->Doom(); |
| 256 delete sync_entry; | 253 delete sync_entry; |
| 257 out_results->sync_entry = NULL; | 254 out_results->sync_entry = NULL; |
| 258 return; | 255 return; |
| 259 } | 256 } |
| 260 out_results->sync_entry = sync_entry; | 257 out_results->sync_entry = sync_entry; |
| 261 } | 258 } |
| 262 | 259 |
| 263 // static | 260 // static |
| 264 int SimpleSynchronousEntry::DoomEntry( | 261 int SimpleSynchronousEntry::DoomEntry(const FilePath& path, |
| 265 const FilePath& path, | 262 uint64_t entry_hash) { |
| 266 uint64 entry_hash) { | |
| 267 const bool deleted_well = DeleteFilesForEntryHash(path, entry_hash); | 263 const bool deleted_well = DeleteFilesForEntryHash(path, entry_hash); |
| 268 return deleted_well ? net::OK : net::ERR_FAILED; | 264 return deleted_well ? net::OK : net::ERR_FAILED; |
| 269 } | 265 } |
| 270 | 266 |
| 271 // static | 267 // static |
| 272 int SimpleSynchronousEntry::DoomEntrySet( | 268 int SimpleSynchronousEntry::DoomEntrySet( |
| 273 const std::vector<uint64>* key_hashes, | 269 const std::vector<uint64_t>* key_hashes, |
| 274 const FilePath& path) { | 270 const FilePath& path) { |
| 275 const size_t did_delete_count = std::count_if( | 271 const size_t did_delete_count = std::count_if( |
| 276 key_hashes->begin(), key_hashes->end(), [&path](const uint64& key_hash) { | 272 key_hashes->begin(), key_hashes->end(), |
| 273 [&path](const uint64_t& key_hash) { |
| 277 return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash); | 274 return SimpleSynchronousEntry::DeleteFilesForEntryHash(path, key_hash); |
| 278 }); | 275 }); |
| 279 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED; | 276 return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED; |
| 280 } | 277 } |
| 281 | 278 |
| 282 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op, | 279 void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op, |
| 283 net::IOBuffer* out_buf, | 280 net::IOBuffer* out_buf, |
| 284 uint32* out_crc32, | 281 uint32_t* out_crc32, |
| 285 SimpleEntryStat* entry_stat, | 282 SimpleEntryStat* entry_stat, |
| 286 int* out_result) const { | 283 int* out_result) const { |
| 287 DCHECK(initialized_); | 284 DCHECK(initialized_); |
| 288 DCHECK_NE(0, in_entry_op.index); | 285 DCHECK_NE(0, in_entry_op.index); |
| 289 const int64 file_offset = | 286 const int64_t file_offset = |
| 290 entry_stat->GetOffsetInFile(key_, in_entry_op.offset, in_entry_op.index); | 287 entry_stat->GetOffsetInFile(key_, in_entry_op.offset, in_entry_op.index); |
| 291 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index); | 288 int file_index = GetFileIndexFromStreamIndex(in_entry_op.index); |
| 292 // Zero-length reads and reads to the empty streams of omitted files should | 289 // Zero-length reads and reads to the empty streams of omitted files should |
| 293 // be handled in the SimpleEntryImpl. | 290 // be handled in the SimpleEntryImpl. |
| 294 DCHECK_GT(in_entry_op.buf_len, 0); | 291 DCHECK_GT(in_entry_op.buf_len, 0); |
| 295 DCHECK(!empty_file_omitted_[file_index]); | 292 DCHECK(!empty_file_omitted_[file_index]); |
| 296 File* file = const_cast<File*>(&files_[file_index]); | 293 File* file = const_cast<File*>(&files_[file_index]); |
| 297 int bytes_read = | 294 int bytes_read = |
| 298 file->Read(file_offset, out_buf->data(), in_entry_op.buf_len); | 295 file->Read(file_offset, out_buf->data(), in_entry_op.buf_len); |
| 299 if (bytes_read > 0) { | 296 if (bytes_read > 0) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 315 SimpleEntryStat* out_entry_stat, | 312 SimpleEntryStat* out_entry_stat, |
| 316 int* out_result) { | 313 int* out_result) { |
| 317 DCHECK(initialized_); | 314 DCHECK(initialized_); |
| 318 DCHECK_NE(0, in_entry_op.index); | 315 DCHECK_NE(0, in_entry_op.index); |
| 319 int index = in_entry_op.index; | 316 int index = in_entry_op.index; |
| 320 int file_index = GetFileIndexFromStreamIndex(index); | 317 int file_index = GetFileIndexFromStreamIndex(index); |
| 321 int offset = in_entry_op.offset; | 318 int offset = in_entry_op.offset; |
| 322 int buf_len = in_entry_op.buf_len; | 319 int buf_len = in_entry_op.buf_len; |
| 323 bool truncate = in_entry_op.truncate; | 320 bool truncate = in_entry_op.truncate; |
| 324 bool doomed = in_entry_op.doomed; | 321 bool doomed = in_entry_op.doomed; |
| 325 const int64 file_offset = out_entry_stat->GetOffsetInFile( | 322 const int64_t file_offset = out_entry_stat->GetOffsetInFile( |
| 326 key_, in_entry_op.offset, in_entry_op.index); | 323 key_, in_entry_op.offset, in_entry_op.index); |
| 327 bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index); | 324 bool extending_by_write = offset + buf_len > out_entry_stat->data_size(index); |
| 328 | 325 |
| 329 if (empty_file_omitted_[file_index]) { | 326 if (empty_file_omitted_[file_index]) { |
| 330 // Don't create a new file if the entry has been doomed, to avoid it being | 327 // Don't create a new file if the entry has been doomed, to avoid it being |
| 331 // mixed up with a newly-created entry with the same key. | 328 // mixed up with a newly-created entry with the same key. |
| 332 if (doomed) { | 329 if (doomed) { |
| 333 DLOG(WARNING) << "Rejecting write to lazily omitted stream " | 330 DLOG(WARNING) << "Rejecting write to lazily omitted stream " |
| 334 << in_entry_op.index << " of doomed cache entry."; | 331 << in_entry_op.index << " of doomed cache entry."; |
| 335 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED); | 332 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_STREAM_ENTRY_DOOMED); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 348 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_INITIALIZE_FAILURE); | 345 RecordWriteResult(cache_type_, WRITE_RESULT_LAZY_INITIALIZE_FAILURE); |
| 349 Doom(); | 346 Doom(); |
| 350 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 347 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 351 return; | 348 return; |
| 352 } | 349 } |
| 353 } | 350 } |
| 354 DCHECK(!empty_file_omitted_[file_index]); | 351 DCHECK(!empty_file_omitted_[file_index]); |
| 355 | 352 |
| 356 if (extending_by_write) { | 353 if (extending_by_write) { |
| 357 // The EOF record and the eventual stream afterward need to be zeroed out. | 354 // The EOF record and the eventual stream afterward need to be zeroed out. |
| 358 const int64 file_eof_offset = | 355 const int64_t file_eof_offset = |
| 359 out_entry_stat->GetEOFOffsetInFile(key_, index); | 356 out_entry_stat->GetEOFOffsetInFile(key_, index); |
| 360 if (!files_[file_index].SetLength(file_eof_offset)) { | 357 if (!files_[file_index].SetLength(file_eof_offset)) { |
| 361 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE); | 358 RecordWriteResult(cache_type_, WRITE_RESULT_PRETRUNCATE_FAILURE); |
| 362 Doom(); | 359 Doom(); |
| 363 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 360 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 364 return; | 361 return; |
| 365 } | 362 } |
| 366 } | 363 } |
| 367 if (buf_len > 0) { | 364 if (buf_len > 0) { |
| 368 if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) != | 365 if (files_[file_index].Write(file_offset, in_buf->data(), buf_len) != |
| (...skipping 24 matching lines...) Expand all Loading... |
| 393 out_entry_stat->set_last_modified(modification_time); | 390 out_entry_stat->set_last_modified(modification_time); |
| 394 *out_result = buf_len; | 391 *out_result = buf_len; |
| 395 } | 392 } |
| 396 | 393 |
| 397 void SimpleSynchronousEntry::ReadSparseData( | 394 void SimpleSynchronousEntry::ReadSparseData( |
| 398 const EntryOperationData& in_entry_op, | 395 const EntryOperationData& in_entry_op, |
| 399 net::IOBuffer* out_buf, | 396 net::IOBuffer* out_buf, |
| 400 base::Time* out_last_used, | 397 base::Time* out_last_used, |
| 401 int* out_result) { | 398 int* out_result) { |
| 402 DCHECK(initialized_); | 399 DCHECK(initialized_); |
| 403 int64 offset = in_entry_op.sparse_offset; | 400 int64_t offset = in_entry_op.sparse_offset; |
| 404 int buf_len = in_entry_op.buf_len; | 401 int buf_len = in_entry_op.buf_len; |
| 405 | 402 |
| 406 char* buf = out_buf->data(); | 403 char* buf = out_buf->data(); |
| 407 int read_so_far = 0; | 404 int read_so_far = 0; |
| 408 | 405 |
| 409 // Find the first sparse range at or after the requested offset. | 406 // Find the first sparse range at or after the requested offset. |
| 410 SparseRangeIterator it = sparse_ranges_.lower_bound(offset); | 407 SparseRangeIterator it = sparse_ranges_.lower_bound(offset); |
| 411 | 408 |
| 412 if (it != sparse_ranges_.begin()) { | 409 if (it != sparse_ranges_.begin()) { |
| 413 // Hop back one range and read the one overlapping with the start. | 410 // Hop back one range and read the one overlapping with the start. |
| 414 --it; | 411 --it; |
| 415 SparseRange* found_range = &it->second; | 412 SparseRange* found_range = &it->second; |
| 416 DCHECK_EQ(it->first, found_range->offset); | 413 DCHECK_EQ(it->first, found_range->offset); |
| 417 if (found_range->offset + found_range->length > offset) { | 414 if (found_range->offset + found_range->length > offset) { |
| 418 DCHECK_GE(found_range->length, 0); | 415 DCHECK_GE(found_range->length, 0); |
| 419 DCHECK_LE(found_range->length, kint32max); | 416 DCHECK_LE(found_range->length, std::numeric_limits<int32_t>::max()); |
| 420 DCHECK_GE(offset - found_range->offset, 0); | 417 DCHECK_GE(offset - found_range->offset, 0); |
| 421 DCHECK_LE(offset - found_range->offset, kint32max); | 418 DCHECK_LE(offset - found_range->offset, |
| 419 std::numeric_limits<int32_t>::max()); |
| 422 int net_offset = static_cast<int>(offset - found_range->offset); | 420 int net_offset = static_cast<int>(offset - found_range->offset); |
| 423 int range_len_after_offset = | 421 int range_len_after_offset = |
| 424 static_cast<int>(found_range->length - net_offset); | 422 static_cast<int>(found_range->length - net_offset); |
| 425 DCHECK_GE(range_len_after_offset, 0); | 423 DCHECK_GE(range_len_after_offset, 0); |
| 426 | 424 |
| 427 int len_to_read = std::min(buf_len, range_len_after_offset); | 425 int len_to_read = std::min(buf_len, range_len_after_offset); |
| 428 if (!ReadSparseRange(found_range, net_offset, len_to_read, buf)) { | 426 if (!ReadSparseRange(found_range, net_offset, len_to_read, buf)) { |
| 429 *out_result = net::ERR_CACHE_READ_FAILURE; | 427 *out_result = net::ERR_CACHE_READ_FAILURE; |
| 430 return; | 428 return; |
| 431 } | 429 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 450 read_so_far += len_to_read; | 448 read_so_far += len_to_read; |
| 451 ++it; | 449 ++it; |
| 452 } | 450 } |
| 453 | 451 |
| 454 *out_result = read_so_far; | 452 *out_result = read_so_far; |
| 455 } | 453 } |
| 456 | 454 |
| 457 void SimpleSynchronousEntry::WriteSparseData( | 455 void SimpleSynchronousEntry::WriteSparseData( |
| 458 const EntryOperationData& in_entry_op, | 456 const EntryOperationData& in_entry_op, |
| 459 net::IOBuffer* in_buf, | 457 net::IOBuffer* in_buf, |
| 460 uint64 max_sparse_data_size, | 458 uint64_t max_sparse_data_size, |
| 461 SimpleEntryStat* out_entry_stat, | 459 SimpleEntryStat* out_entry_stat, |
| 462 int* out_result) { | 460 int* out_result) { |
| 463 DCHECK(initialized_); | 461 DCHECK(initialized_); |
| 464 int64 offset = in_entry_op.sparse_offset; | 462 int64_t offset = in_entry_op.sparse_offset; |
| 465 int buf_len = in_entry_op.buf_len; | 463 int buf_len = in_entry_op.buf_len; |
| 466 | 464 |
| 467 const char* buf = in_buf->data(); | 465 const char* buf = in_buf->data(); |
| 468 int written_so_far = 0; | 466 int written_so_far = 0; |
| 469 int appended_so_far = 0; | 467 int appended_so_far = 0; |
| 470 | 468 |
| 471 if (!sparse_file_open() && !CreateSparseFile()) { | 469 if (!sparse_file_open() && !CreateSparseFile()) { |
| 472 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 470 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 473 return; | 471 return; |
| 474 } | 472 } |
| 475 | 473 |
| 476 uint64 sparse_data_size = out_entry_stat->sparse_data_size(); | 474 uint64_t sparse_data_size = out_entry_stat->sparse_data_size(); |
| 477 // This is a pessimistic estimate; it assumes the entire buffer is going to | 475 // This is a pessimistic estimate; it assumes the entire buffer is going to |
| 478 // be appended as a new range, not written over existing ranges. | 476 // be appended as a new range, not written over existing ranges. |
| 479 if (sparse_data_size + buf_len > max_sparse_data_size) { | 477 if (sparse_data_size + buf_len > max_sparse_data_size) { |
| 480 DVLOG(1) << "Truncating sparse data file (" << sparse_data_size << " + " | 478 DVLOG(1) << "Truncating sparse data file (" << sparse_data_size << " + " |
| 481 << buf_len << " > " << max_sparse_data_size << ")"; | 479 << buf_len << " > " << max_sparse_data_size << ")"; |
| 482 TruncateSparseFile(); | 480 TruncateSparseFile(); |
| 483 out_entry_stat->set_sparse_data_size(0); | 481 out_entry_stat->set_sparse_data_size(0); |
| 484 } | 482 } |
| 485 | 483 |
| 486 SparseRangeIterator it = sparse_ranges_.lower_bound(offset); | 484 SparseRangeIterator it = sparse_ranges_.lower_bound(offset); |
| 487 | 485 |
| 488 if (it != sparse_ranges_.begin()) { | 486 if (it != sparse_ranges_.begin()) { |
| 489 --it; | 487 --it; |
| 490 SparseRange* found_range = &it->second; | 488 SparseRange* found_range = &it->second; |
| 491 if (found_range->offset + found_range->length > offset) { | 489 if (found_range->offset + found_range->length > offset) { |
| 492 DCHECK_GE(found_range->length, 0); | 490 DCHECK_GE(found_range->length, 0); |
| 493 DCHECK_LE(found_range->length, kint32max); | 491 DCHECK_LE(found_range->length, std::numeric_limits<int32_t>::max()); |
| 494 DCHECK_GE(offset - found_range->offset, 0); | 492 DCHECK_GE(offset - found_range->offset, 0); |
| 495 DCHECK_LE(offset - found_range->offset, kint32max); | 493 DCHECK_LE(offset - found_range->offset, |
| 494 std::numeric_limits<int32_t>::max()); |
| 496 int net_offset = static_cast<int>(offset - found_range->offset); | 495 int net_offset = static_cast<int>(offset - found_range->offset); |
| 497 int range_len_after_offset = | 496 int range_len_after_offset = |
| 498 static_cast<int>(found_range->length - net_offset); | 497 static_cast<int>(found_range->length - net_offset); |
| 499 DCHECK_GE(range_len_after_offset, 0); | 498 DCHECK_GE(range_len_after_offset, 0); |
| 500 | 499 |
| 501 int len_to_write = std::min(buf_len, range_len_after_offset); | 500 int len_to_write = std::min(buf_len, range_len_after_offset); |
| 502 if (!WriteSparseRange(found_range, net_offset, len_to_write, buf)) { | 501 if (!WriteSparseRange(found_range, net_offset, len_to_write, buf)) { |
| 503 *out_result = net::ERR_CACHE_WRITE_FAILURE; | 502 *out_result = net::ERR_CACHE_WRITE_FAILURE; |
| 504 return; | 503 return; |
| 505 } | 504 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 } | 546 } |
| 548 written_so_far += len_to_append; | 547 written_so_far += len_to_append; |
| 549 appended_so_far += len_to_append; | 548 appended_so_far += len_to_append; |
| 550 } | 549 } |
| 551 | 550 |
| 552 DCHECK_EQ(buf_len, written_so_far); | 551 DCHECK_EQ(buf_len, written_so_far); |
| 553 | 552 |
| 554 base::Time modification_time = Time::Now(); | 553 base::Time modification_time = Time::Now(); |
| 555 out_entry_stat->set_last_used(modification_time); | 554 out_entry_stat->set_last_used(modification_time); |
| 556 out_entry_stat->set_last_modified(modification_time); | 555 out_entry_stat->set_last_modified(modification_time); |
| 557 int32 old_sparse_data_size = out_entry_stat->sparse_data_size(); | 556 int32_t old_sparse_data_size = out_entry_stat->sparse_data_size(); |
| 558 out_entry_stat->set_sparse_data_size(old_sparse_data_size + appended_so_far); | 557 out_entry_stat->set_sparse_data_size(old_sparse_data_size + appended_so_far); |
| 559 *out_result = written_so_far; | 558 *out_result = written_so_far; |
| 560 } | 559 } |
| 561 | 560 |
| 562 void SimpleSynchronousEntry::GetAvailableRange( | 561 void SimpleSynchronousEntry::GetAvailableRange( |
| 563 const EntryOperationData& in_entry_op, | 562 const EntryOperationData& in_entry_op, |
| 564 int64* out_start, | 563 int64_t* out_start, |
| 565 int* out_result) { | 564 int* out_result) { |
| 566 DCHECK(initialized_); | 565 DCHECK(initialized_); |
| 567 int64 offset = in_entry_op.sparse_offset; | 566 int64_t offset = in_entry_op.sparse_offset; |
| 568 int len = in_entry_op.buf_len; | 567 int len = in_entry_op.buf_len; |
| 569 | 568 |
| 570 SparseRangeIterator it = sparse_ranges_.lower_bound(offset); | 569 SparseRangeIterator it = sparse_ranges_.lower_bound(offset); |
| 571 | 570 |
| 572 int64 start = offset; | 571 int64_t start = offset; |
| 573 int64 avail_so_far = 0; | 572 int64_t avail_so_far = 0; |
| 574 | 573 |
| 575 if (it != sparse_ranges_.end() && it->second.offset < offset + len) | 574 if (it != sparse_ranges_.end() && it->second.offset < offset + len) |
| 576 start = it->second.offset; | 575 start = it->second.offset; |
| 577 | 576 |
| 578 if ((it == sparse_ranges_.end() || it->second.offset > offset) && | 577 if ((it == sparse_ranges_.end() || it->second.offset > offset) && |
| 579 it != sparse_ranges_.begin()) { | 578 it != sparse_ranges_.begin()) { |
| 580 --it; | 579 --it; |
| 581 if (it->second.offset + it->second.length > offset) { | 580 if (it->second.offset + it->second.length > offset) { |
| 582 start = offset; | 581 start = offset; |
| 583 avail_so_far = (it->second.offset + it->second.length) - offset; | 582 avail_so_far = (it->second.offset + it->second.length) - offset; |
| 584 } | 583 } |
| 585 ++it; | 584 ++it; |
| 586 } | 585 } |
| 587 | 586 |
| 588 while (start + avail_so_far < offset + len && | 587 while (start + avail_so_far < offset + len && |
| 589 it != sparse_ranges_.end() && | 588 it != sparse_ranges_.end() && |
| 590 it->second.offset == start + avail_so_far) { | 589 it->second.offset == start + avail_so_far) { |
| 591 avail_so_far += it->second.length; | 590 avail_so_far += it->second.length; |
| 592 ++it; | 591 ++it; |
| 593 } | 592 } |
| 594 | 593 |
| 595 int64 len_from_start = len - (start - offset); | 594 int64_t len_from_start = len - (start - offset); |
| 596 *out_start = start; | 595 *out_start = start; |
| 597 *out_result = static_cast<int>(std::min(avail_so_far, len_from_start)); | 596 *out_result = static_cast<int>(std::min(avail_so_far, len_from_start)); |
| 598 } | 597 } |
| 599 | 598 |
| 600 void SimpleSynchronousEntry::CheckEOFRecord(int index, | 599 void SimpleSynchronousEntry::CheckEOFRecord(int index, |
| 601 const SimpleEntryStat& entry_stat, | 600 const SimpleEntryStat& entry_stat, |
| 602 uint32 expected_crc32, | 601 uint32_t expected_crc32, |
| 603 int* out_result) const { | 602 int* out_result) const { |
| 604 DCHECK(initialized_); | 603 DCHECK(initialized_); |
| 605 uint32 crc32; | 604 uint32_t crc32; |
| 606 bool has_crc32; | 605 bool has_crc32; |
| 607 int stream_size; | 606 int stream_size; |
| 608 *out_result = | 607 *out_result = |
| 609 GetEOFRecordData(index, entry_stat, &has_crc32, &crc32, &stream_size); | 608 GetEOFRecordData(index, entry_stat, &has_crc32, &crc32, &stream_size); |
| 610 if (*out_result != net::OK) { | 609 if (*out_result != net::OK) { |
| 611 Doom(); | 610 Doom(); |
| 612 return; | 611 return; |
| 613 } | 612 } |
| 614 if (has_crc32 && crc32 != expected_crc32) { | 613 if (has_crc32 && crc32 != expected_crc32) { |
| 615 DVLOG(1) << "EOF record had bad crc."; | 614 DVLOG(1) << "EOF record had bad crc."; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 DVLOG(1) << "Could not write eof record."; | 668 DVLOG(1) << "Could not write eof record."; |
| 670 Doom(); | 669 Doom(); |
| 671 break; | 670 break; |
| 672 } | 671 } |
| 673 } | 672 } |
| 674 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 673 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 675 if (empty_file_omitted_[i]) | 674 if (empty_file_omitted_[i]) |
| 676 continue; | 675 continue; |
| 677 | 676 |
| 678 files_[i].Close(); | 677 files_[i].Close(); |
| 679 const int64 file_size = entry_stat.GetFileSize(key_, i); | 678 const int64_t file_size = entry_stat.GetFileSize(key_, i); |
| 680 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, | 679 SIMPLE_CACHE_UMA(CUSTOM_COUNTS, |
| 681 "LastClusterSize", cache_type_, | 680 "LastClusterSize", cache_type_, |
| 682 file_size % 4096, 0, 4097, 50); | 681 file_size % 4096, 0, 4097, 50); |
| 683 const int64 cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0; | 682 const int64_t cluster_loss = file_size % 4096 ? 4096 - file_size % 4096 : 0; |
| 684 SIMPLE_CACHE_UMA(PERCENTAGE, | 683 SIMPLE_CACHE_UMA(PERCENTAGE, |
| 685 "LastClusterLossPercent", cache_type_, | 684 "LastClusterLossPercent", cache_type_, |
| 686 static_cast<base::HistogramBase::Sample>( | 685 static_cast<base::HistogramBase::Sample>( |
| 687 cluster_loss * 100 / (cluster_loss + file_size))); | 686 cluster_loss * 100 / (cluster_loss + file_size))); |
| 688 } | 687 } |
| 689 | 688 |
| 690 if (sparse_file_open()) | 689 if (sparse_file_open()) |
| 691 sparse_file_.Close(); | 690 sparse_file_.Close(); |
| 692 | 691 |
| 693 if (files_created_) { | 692 if (files_created_) { |
| 694 const int stream2_file_index = GetFileIndexFromStreamIndex(2); | 693 const int stream2_file_index = GetFileIndexFromStreamIndex(2); |
| 695 SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_, | 694 SIMPLE_CACHE_UMA(BOOLEAN, "EntryCreatedAndStream2Omitted", cache_type_, |
| 696 empty_file_omitted_[stream2_file_index]); | 695 empty_file_omitted_[stream2_file_index]); |
| 697 } | 696 } |
| 698 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); | 697 RecordCloseResult(cache_type_, CLOSE_RESULT_SUCCESS); |
| 699 have_open_files_ = false; | 698 have_open_files_ = false; |
| 700 delete this; | 699 delete this; |
| 701 } | 700 } |
| 702 | 701 |
| 703 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type, | 702 SimpleSynchronousEntry::SimpleSynchronousEntry(net::CacheType cache_type, |
| 704 const FilePath& path, | 703 const FilePath& path, |
| 705 const std::string& key, | 704 const std::string& key, |
| 706 const uint64 entry_hash) | 705 const uint64_t entry_hash) |
| 707 : cache_type_(cache_type), | 706 : cache_type_(cache_type), |
| 708 path_(path), | 707 path_(path), |
| 709 entry_hash_(entry_hash), | 708 entry_hash_(entry_hash), |
| 710 key_(key), | 709 key_(key), |
| 711 have_open_files_(false), | 710 have_open_files_(false), |
| 712 initialized_(false) { | 711 initialized_(false) { |
| 713 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 712 for (int i = 0; i < kSimpleEntryFileCount; ++i) |
| 714 empty_file_omitted_[i] = false; | 713 empty_file_omitted_[i] = false; |
| 715 } | 714 } |
| 716 | 715 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 | 896 |
| 898 void SimpleSynchronousEntry::CloseFiles() { | 897 void SimpleSynchronousEntry::CloseFiles() { |
| 899 for (int i = 0; i < kSimpleEntryFileCount; ++i) | 898 for (int i = 0; i < kSimpleEntryFileCount; ++i) |
| 900 CloseFile(i); | 899 CloseFile(i); |
| 901 } | 900 } |
| 902 | 901 |
| 903 int SimpleSynchronousEntry::InitializeForOpen( | 902 int SimpleSynchronousEntry::InitializeForOpen( |
| 904 bool had_index, | 903 bool had_index, |
| 905 SimpleEntryStat* out_entry_stat, | 904 SimpleEntryStat* out_entry_stat, |
| 906 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, | 905 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, |
| 907 uint32* out_stream_0_crc32) { | 906 uint32_t* out_stream_0_crc32) { |
| 908 DCHECK(!initialized_); | 907 DCHECK(!initialized_); |
| 909 if (!OpenFiles(had_index, out_entry_stat)) { | 908 if (!OpenFiles(had_index, out_entry_stat)) { |
| 910 DLOG(WARNING) << "Could not open platform files for entry."; | 909 DLOG(WARNING) << "Could not open platform files for entry."; |
| 911 return net::ERR_FAILED; | 910 return net::ERR_FAILED; |
| 912 } | 911 } |
| 913 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 912 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 914 if (empty_file_omitted_[i]) | 913 if (empty_file_omitted_[i]) |
| 915 continue; | 914 continue; |
| 916 | 915 |
| 917 SimpleFileHeader header; | 916 SimpleFileHeader header; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 } | 965 } |
| 967 | 966 |
| 968 if (base::Hash(key.get(), header.key_length) != header.key_hash) { | 967 if (base::Hash(key.get(), header.key_length) != header.key_hash) { |
| 969 DLOG(WARNING) << "Hash mismatch on key."; | 968 DLOG(WARNING) << "Hash mismatch on key."; |
| 970 RecordSyncOpenResult( | 969 RecordSyncOpenResult( |
| 971 cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index); | 970 cache_type_, OPEN_ENTRY_KEY_HASH_MISMATCH, had_index); |
| 972 return net::ERR_FAILED; | 971 return net::ERR_FAILED; |
| 973 } | 972 } |
| 974 } | 973 } |
| 975 | 974 |
| 976 int32 sparse_data_size = 0; | 975 int32_t sparse_data_size = 0; |
| 977 if (!OpenSparseFileIfExists(&sparse_data_size)) { | 976 if (!OpenSparseFileIfExists(&sparse_data_size)) { |
| 978 RecordSyncOpenResult( | 977 RecordSyncOpenResult( |
| 979 cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED, had_index); | 978 cache_type_, OPEN_ENTRY_SPARSE_OPEN_FAILED, had_index); |
| 980 return net::ERR_FAILED; | 979 return net::ERR_FAILED; |
| 981 } | 980 } |
| 982 out_entry_stat->set_sparse_data_size(sparse_data_size); | 981 out_entry_stat->set_sparse_data_size(sparse_data_size); |
| 983 | 982 |
| 984 bool removed_stream2 = false; | 983 bool removed_stream2 = false; |
| 985 const int stream2_file_index = GetFileIndexFromStreamIndex(2); | 984 const int stream2_file_index = GetFileIndexFromStreamIndex(2); |
| 986 DCHECK(CanOmitEmptyFile(stream2_file_index)); | 985 DCHECK(CanOmitEmptyFile(stream2_file_index)); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 } | 1047 } |
| 1049 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS, had_index); | 1048 RecordSyncCreateResult(CREATE_ENTRY_SUCCESS, had_index); |
| 1050 initialized_ = true; | 1049 initialized_ = true; |
| 1051 return net::OK; | 1050 return net::OK; |
| 1052 } | 1051 } |
| 1053 | 1052 |
| 1054 int SimpleSynchronousEntry::ReadAndValidateStream0( | 1053 int SimpleSynchronousEntry::ReadAndValidateStream0( |
| 1055 int total_data_size, | 1054 int total_data_size, |
| 1056 SimpleEntryStat* out_entry_stat, | 1055 SimpleEntryStat* out_entry_stat, |
| 1057 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, | 1056 scoped_refptr<net::GrowableIOBuffer>* stream_0_data, |
| 1058 uint32* out_stream_0_crc32) const { | 1057 uint32_t* out_stream_0_crc32) const { |
| 1059 // Temporarily assign all the data size to stream 1 in order to read the | 1058 // Temporarily assign all the data size to stream 1 in order to read the |
| 1060 // EOF record for stream 0, which contains the size of stream 0. | 1059 // EOF record for stream 0, which contains the size of stream 0. |
| 1061 out_entry_stat->set_data_size(0, 0); | 1060 out_entry_stat->set_data_size(0, 0); |
| 1062 out_entry_stat->set_data_size(1, total_data_size - sizeof(SimpleFileEOF)); | 1061 out_entry_stat->set_data_size(1, total_data_size - sizeof(SimpleFileEOF)); |
| 1063 | 1062 |
| 1064 bool has_crc32; | 1063 bool has_crc32; |
| 1065 uint32 read_crc32; | 1064 uint32_t read_crc32; |
| 1066 int stream_0_size; | 1065 int stream_0_size; |
| 1067 int ret_value_crc32 = GetEOFRecordData( | 1066 int ret_value_crc32 = GetEOFRecordData( |
| 1068 0, *out_entry_stat, &has_crc32, &read_crc32, &stream_0_size); | 1067 0, *out_entry_stat, &has_crc32, &read_crc32, &stream_0_size); |
| 1069 if (ret_value_crc32 != net::OK) | 1068 if (ret_value_crc32 != net::OK) |
| 1070 return ret_value_crc32; | 1069 return ret_value_crc32; |
| 1071 | 1070 |
| 1072 if (stream_0_size > out_entry_stat->data_size(1)) | 1071 if (stream_0_size > out_entry_stat->data_size(1)) |
| 1073 return net::ERR_FAILED; | 1072 return net::ERR_FAILED; |
| 1074 | 1073 |
| 1075 // These are the real values of data size. | 1074 // These are the real values of data size. |
| 1076 out_entry_stat->set_data_size(0, stream_0_size); | 1075 out_entry_stat->set_data_size(0, stream_0_size); |
| 1077 out_entry_stat->set_data_size( | 1076 out_entry_stat->set_data_size( |
| 1078 1, out_entry_stat->data_size(1) - stream_0_size); | 1077 1, out_entry_stat->data_size(1) - stream_0_size); |
| 1079 | 1078 |
| 1080 // Put stream 0 data in memory. | 1079 // Put stream 0 data in memory. |
| 1081 *stream_0_data = new net::GrowableIOBuffer(); | 1080 *stream_0_data = new net::GrowableIOBuffer(); |
| 1082 (*stream_0_data)->SetCapacity(stream_0_size); | 1081 (*stream_0_data)->SetCapacity(stream_0_size); |
| 1083 int file_offset = out_entry_stat->GetOffsetInFile(key_, 0, 0); | 1082 int file_offset = out_entry_stat->GetOffsetInFile(key_, 0, 0); |
| 1084 File* file = const_cast<File*>(&files_[0]); | 1083 File* file = const_cast<File*>(&files_[0]); |
| 1085 int bytes_read = | 1084 int bytes_read = |
| 1086 file->Read(file_offset, (*stream_0_data)->data(), stream_0_size); | 1085 file->Read(file_offset, (*stream_0_data)->data(), stream_0_size); |
| 1087 if (bytes_read != stream_0_size) | 1086 if (bytes_read != stream_0_size) |
| 1088 return net::ERR_FAILED; | 1087 return net::ERR_FAILED; |
| 1089 | 1088 |
| 1090 // Check the CRC32. | 1089 // Check the CRC32. |
| 1091 uint32 expected_crc32 = | 1090 uint32_t expected_crc32 = |
| 1092 stream_0_size == 0 | 1091 stream_0_size == 0 |
| 1093 ? crc32(0, Z_NULL, 0) | 1092 ? crc32(0, Z_NULL, 0) |
| 1094 : crc32(crc32(0, Z_NULL, 0), | 1093 : crc32(crc32(0, Z_NULL, 0), |
| 1095 reinterpret_cast<const Bytef*>((*stream_0_data)->data()), | 1094 reinterpret_cast<const Bytef*>((*stream_0_data)->data()), |
| 1096 stream_0_size); | 1095 stream_0_size); |
| 1097 if (has_crc32 && read_crc32 != expected_crc32) { | 1096 if (has_crc32 && read_crc32 != expected_crc32) { |
| 1098 DVLOG(1) << "EOF record had bad crc."; | 1097 DVLOG(1) << "EOF record had bad crc."; |
| 1099 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); | 1098 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_CRC_MISMATCH); |
| 1100 return net::ERR_FAILED; | 1099 return net::ERR_FAILED; |
| 1101 } | 1100 } |
| 1102 *out_stream_0_crc32 = expected_crc32; | 1101 *out_stream_0_crc32 = expected_crc32; |
| 1103 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); | 1102 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_SUCCESS); |
| 1104 return net::OK; | 1103 return net::OK; |
| 1105 } | 1104 } |
| 1106 | 1105 |
| 1107 int SimpleSynchronousEntry::GetEOFRecordData(int index, | 1106 int SimpleSynchronousEntry::GetEOFRecordData(int index, |
| 1108 const SimpleEntryStat& entry_stat, | 1107 const SimpleEntryStat& entry_stat, |
| 1109 bool* out_has_crc32, | 1108 bool* out_has_crc32, |
| 1110 uint32* out_crc32, | 1109 uint32_t* out_crc32, |
| 1111 int* out_data_size) const { | 1110 int* out_data_size) const { |
| 1112 SimpleFileEOF eof_record; | 1111 SimpleFileEOF eof_record; |
| 1113 int file_offset = entry_stat.GetEOFOffsetInFile(key_, index); | 1112 int file_offset = entry_stat.GetEOFOffsetInFile(key_, index); |
| 1114 int file_index = GetFileIndexFromStreamIndex(index); | 1113 int file_index = GetFileIndexFromStreamIndex(index); |
| 1115 File* file = const_cast<File*>(&files_[file_index]); | 1114 File* file = const_cast<File*>(&files_[file_index]); |
| 1116 if (file->Read(file_offset, reinterpret_cast<char*>(&eof_record), | 1115 if (file->Read(file_offset, reinterpret_cast<char*>(&eof_record), |
| 1117 sizeof(eof_record)) != | 1116 sizeof(eof_record)) != |
| 1118 sizeof(eof_record)) { | 1117 sizeof(eof_record)) { |
| 1119 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE); | 1118 RecordCheckEOFResult(cache_type_, CHECK_EOF_RESULT_READ_FAILURE); |
| 1120 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; | 1119 return net::ERR_CACHE_CHECKSUM_READ_FAILURE; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1132 *out_data_size = eof_record.stream_size; | 1131 *out_data_size = eof_record.stream_size; |
| 1133 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_, *out_has_crc32); | 1132 SIMPLE_CACHE_UMA(BOOLEAN, "SyncCheckEOFHasCrc", cache_type_, *out_has_crc32); |
| 1134 return net::OK; | 1133 return net::OK; |
| 1135 } | 1134 } |
| 1136 | 1135 |
| 1137 void SimpleSynchronousEntry::Doom() const { | 1136 void SimpleSynchronousEntry::Doom() const { |
| 1138 DeleteFilesForEntryHash(path_, entry_hash_); | 1137 DeleteFilesForEntryHash(path_, entry_hash_); |
| 1139 } | 1138 } |
| 1140 | 1139 |
| 1141 // static | 1140 // static |
| 1142 bool SimpleSynchronousEntry::DeleteFileForEntryHash( | 1141 bool SimpleSynchronousEntry::DeleteFileForEntryHash(const FilePath& path, |
| 1143 const FilePath& path, | 1142 const uint64_t entry_hash, |
| 1144 const uint64 entry_hash, | 1143 const int file_index) { |
| 1145 const int file_index) { | |
| 1146 FilePath to_delete = path.AppendASCII( | 1144 FilePath to_delete = path.AppendASCII( |
| 1147 GetFilenameFromEntryHashAndFileIndex(entry_hash, file_index)); | 1145 GetFilenameFromEntryHashAndFileIndex(entry_hash, file_index)); |
| 1148 return simple_util::SimpleCacheDeleteFile(to_delete); | 1146 return simple_util::SimpleCacheDeleteFile(to_delete); |
| 1149 } | 1147 } |
| 1150 | 1148 |
| 1151 // static | 1149 // static |
| 1152 bool SimpleSynchronousEntry::DeleteFilesForEntryHash( | 1150 bool SimpleSynchronousEntry::DeleteFilesForEntryHash( |
| 1153 const FilePath& path, | 1151 const FilePath& path, |
| 1154 const uint64 entry_hash) { | 1152 const uint64_t entry_hash) { |
| 1155 bool result = true; | 1153 bool result = true; |
| 1156 for (int i = 0; i < kSimpleEntryFileCount; ++i) { | 1154 for (int i = 0; i < kSimpleEntryFileCount; ++i) { |
| 1157 if (!DeleteFileForEntryHash(path, entry_hash, i) && !CanOmitEmptyFile(i)) | 1155 if (!DeleteFileForEntryHash(path, entry_hash, i) && !CanOmitEmptyFile(i)) |
| 1158 result = false; | 1156 result = false; |
| 1159 } | 1157 } |
| 1160 FilePath to_delete = path.AppendASCII( | 1158 FilePath to_delete = path.AppendASCII( |
| 1161 GetSparseFilenameFromEntryHash(entry_hash)); | 1159 GetSparseFilenameFromEntryHash(entry_hash)); |
| 1162 simple_util::SimpleCacheDeleteFile(to_delete); | 1160 simple_util::SimpleCacheDeleteFile(to_delete); |
| 1163 return result; | 1161 return result; |
| 1164 } | 1162 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1178 result, CREATE_ENTRY_MAX); | 1176 result, CREATE_ENTRY_MAX); |
| 1179 } | 1177 } |
| 1180 } | 1178 } |
| 1181 | 1179 |
| 1182 FilePath SimpleSynchronousEntry::GetFilenameFromFileIndex(int file_index) { | 1180 FilePath SimpleSynchronousEntry::GetFilenameFromFileIndex(int file_index) { |
| 1183 return path_.AppendASCII( | 1181 return path_.AppendASCII( |
| 1184 GetFilenameFromEntryHashAndFileIndex(entry_hash_, file_index)); | 1182 GetFilenameFromEntryHashAndFileIndex(entry_hash_, file_index)); |
| 1185 } | 1183 } |
| 1186 | 1184 |
| 1187 bool SimpleSynchronousEntry::OpenSparseFileIfExists( | 1185 bool SimpleSynchronousEntry::OpenSparseFileIfExists( |
| 1188 int32* out_sparse_data_size) { | 1186 int32_t* out_sparse_data_size) { |
| 1189 DCHECK(!sparse_file_open()); | 1187 DCHECK(!sparse_file_open()); |
| 1190 | 1188 |
| 1191 FilePath filename = path_.AppendASCII( | 1189 FilePath filename = path_.AppendASCII( |
| 1192 GetSparseFilenameFromEntryHash(entry_hash_)); | 1190 GetSparseFilenameFromEntryHash(entry_hash_)); |
| 1193 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE | | 1191 int flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE | |
| 1194 File::FLAG_SHARE_DELETE; | 1192 File::FLAG_SHARE_DELETE; |
| 1195 sparse_file_.Initialize(filename, flags); | 1193 sparse_file_.Initialize(filename, flags); |
| 1196 if (sparse_file_.IsValid()) | 1194 if (sparse_file_.IsValid()) |
| 1197 return ScanSparseFile(out_sparse_data_size); | 1195 return ScanSparseFile(out_sparse_data_size); |
| 1198 | 1196 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1214 } | 1212 } |
| 1215 | 1213 |
| 1216 void SimpleSynchronousEntry::CloseSparseFile() { | 1214 void SimpleSynchronousEntry::CloseSparseFile() { |
| 1217 DCHECK(sparse_file_open()); | 1215 DCHECK(sparse_file_open()); |
| 1218 sparse_file_.Close(); | 1216 sparse_file_.Close(); |
| 1219 } | 1217 } |
| 1220 | 1218 |
| 1221 bool SimpleSynchronousEntry::TruncateSparseFile() { | 1219 bool SimpleSynchronousEntry::TruncateSparseFile() { |
| 1222 DCHECK(sparse_file_open()); | 1220 DCHECK(sparse_file_open()); |
| 1223 | 1221 |
| 1224 int64 header_and_key_length = sizeof(SimpleFileHeader) + key_.size(); | 1222 int64_t header_and_key_length = sizeof(SimpleFileHeader) + key_.size(); |
| 1225 if (!sparse_file_.SetLength(header_and_key_length)) { | 1223 if (!sparse_file_.SetLength(header_and_key_length)) { |
| 1226 DLOG(WARNING) << "Could not truncate sparse file"; | 1224 DLOG(WARNING) << "Could not truncate sparse file"; |
| 1227 return false; | 1225 return false; |
| 1228 } | 1226 } |
| 1229 | 1227 |
| 1230 sparse_ranges_.clear(); | 1228 sparse_ranges_.clear(); |
| 1231 sparse_tail_offset_ = header_and_key_length; | 1229 sparse_tail_offset_ = header_and_key_length; |
| 1232 | 1230 |
| 1233 return true; | 1231 return true; |
| 1234 } | 1232 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1255 DLOG(WARNING) << "Could not write sparse file key"; | 1253 DLOG(WARNING) << "Could not write sparse file key"; |
| 1256 return false; | 1254 return false; |
| 1257 } | 1255 } |
| 1258 | 1256 |
| 1259 sparse_ranges_.clear(); | 1257 sparse_ranges_.clear(); |
| 1260 sparse_tail_offset_ = sizeof(header) + key_.size(); | 1258 sparse_tail_offset_ = sizeof(header) + key_.size(); |
| 1261 | 1259 |
| 1262 return true; | 1260 return true; |
| 1263 } | 1261 } |
| 1264 | 1262 |
| 1265 bool SimpleSynchronousEntry::ScanSparseFile(int32* out_sparse_data_size) { | 1263 bool SimpleSynchronousEntry::ScanSparseFile(int32_t* out_sparse_data_size) { |
| 1266 DCHECK(sparse_file_open()); | 1264 DCHECK(sparse_file_open()); |
| 1267 | 1265 |
| 1268 int64 sparse_data_size = 0; | 1266 int64_t sparse_data_size = 0; |
| 1269 | 1267 |
| 1270 SimpleFileHeader header; | 1268 SimpleFileHeader header; |
| 1271 int header_read_result = | 1269 int header_read_result = |
| 1272 sparse_file_.Read(0, reinterpret_cast<char*>(&header), sizeof(header)); | 1270 sparse_file_.Read(0, reinterpret_cast<char*>(&header), sizeof(header)); |
| 1273 if (header_read_result != sizeof(header)) { | 1271 if (header_read_result != sizeof(header)) { |
| 1274 DLOG(WARNING) << "Could not read header from sparse file."; | 1272 DLOG(WARNING) << "Could not read header from sparse file."; |
| 1275 return false; | 1273 return false; |
| 1276 } | 1274 } |
| 1277 | 1275 |
| 1278 if (header.initial_magic_number != kSimpleInitialMagicNumber) { | 1276 if (header.initial_magic_number != kSimpleInitialMagicNumber) { |
| 1279 DLOG(WARNING) << "Sparse file magic number did not match."; | 1277 DLOG(WARNING) << "Sparse file magic number did not match."; |
| 1280 return false; | 1278 return false; |
| 1281 } | 1279 } |
| 1282 | 1280 |
| 1283 if (header.version != kSimpleVersion) { | 1281 if (header.version != kSimpleVersion) { |
| 1284 DLOG(WARNING) << "Sparse file unreadable version."; | 1282 DLOG(WARNING) << "Sparse file unreadable version."; |
| 1285 return false; | 1283 return false; |
| 1286 } | 1284 } |
| 1287 | 1285 |
| 1288 sparse_ranges_.clear(); | 1286 sparse_ranges_.clear(); |
| 1289 | 1287 |
| 1290 int64 range_header_offset = sizeof(header) + key_.size(); | 1288 int64_t range_header_offset = sizeof(header) + key_.size(); |
| 1291 while (1) { | 1289 while (1) { |
| 1292 SimpleFileSparseRangeHeader range_header; | 1290 SimpleFileSparseRangeHeader range_header; |
| 1293 int range_header_read_result = | 1291 int range_header_read_result = |
| 1294 sparse_file_.Read(range_header_offset, | 1292 sparse_file_.Read(range_header_offset, |
| 1295 reinterpret_cast<char*>(&range_header), | 1293 reinterpret_cast<char*>(&range_header), |
| 1296 sizeof(range_header)); | 1294 sizeof(range_header)); |
| 1297 if (range_header_read_result == 0) | 1295 if (range_header_read_result == 0) |
| 1298 break; | 1296 break; |
| 1299 if (range_header_read_result != sizeof(range_header)) { | 1297 if (range_header_read_result != sizeof(range_header)) { |
| 1300 DLOG(WARNING) << "Could not read sparse range header."; | 1298 DLOG(WARNING) << "Could not read sparse range header."; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1313 range.data_crc32 = range_header.data_crc32; | 1311 range.data_crc32 = range_header.data_crc32; |
| 1314 range.file_offset = range_header_offset + sizeof(range_header); | 1312 range.file_offset = range_header_offset + sizeof(range_header); |
| 1315 sparse_ranges_.insert(std::make_pair(range.offset, range)); | 1313 sparse_ranges_.insert(std::make_pair(range.offset, range)); |
| 1316 | 1314 |
| 1317 range_header_offset += sizeof(range_header) + range.length; | 1315 range_header_offset += sizeof(range_header) + range.length; |
| 1318 | 1316 |
| 1319 DCHECK_GE(sparse_data_size + range.length, sparse_data_size); | 1317 DCHECK_GE(sparse_data_size + range.length, sparse_data_size); |
| 1320 sparse_data_size += range.length; | 1318 sparse_data_size += range.length; |
| 1321 } | 1319 } |
| 1322 | 1320 |
| 1323 *out_sparse_data_size = static_cast<int32>(sparse_data_size); | 1321 *out_sparse_data_size = static_cast<int32_t>(sparse_data_size); |
| 1324 sparse_tail_offset_ = range_header_offset; | 1322 sparse_tail_offset_ = range_header_offset; |
| 1325 | 1323 |
| 1326 return true; | 1324 return true; |
| 1327 } | 1325 } |
| 1328 | 1326 |
| 1329 bool SimpleSynchronousEntry::ReadSparseRange(const SparseRange* range, | 1327 bool SimpleSynchronousEntry::ReadSparseRange(const SparseRange* range, |
| 1330 int offset, int len, char* buf) { | 1328 int offset, int len, char* buf) { |
| 1331 DCHECK(range); | 1329 DCHECK(range); |
| 1332 DCHECK(buf); | 1330 DCHECK(buf); |
| 1333 DCHECK_LE(offset, range->length); | 1331 DCHECK_LE(offset, range->length); |
| 1334 DCHECK_LE(offset + len, range->length); | 1332 DCHECK_LE(offset + len, range->length); |
| 1335 | 1333 |
| 1336 int bytes_read = sparse_file_.Read(range->file_offset + offset, buf, len); | 1334 int bytes_read = sparse_file_.Read(range->file_offset + offset, buf, len); |
| 1337 if (bytes_read < len) { | 1335 if (bytes_read < len) { |
| 1338 DLOG(WARNING) << "Could not read sparse range."; | 1336 DLOG(WARNING) << "Could not read sparse range."; |
| 1339 return false; | 1337 return false; |
| 1340 } | 1338 } |
| 1341 | 1339 |
| 1342 // If we read the whole range and we have a crc32, check it. | 1340 // If we read the whole range and we have a crc32, check it. |
| 1343 if (offset == 0 && len == range->length && range->data_crc32 != 0) { | 1341 if (offset == 0 && len == range->length && range->data_crc32 != 0) { |
| 1344 uint32 actual_crc32 = crc32(crc32(0L, Z_NULL, 0), | 1342 uint32_t actual_crc32 = |
| 1345 reinterpret_cast<const Bytef*>(buf), | 1343 crc32(crc32(0L, Z_NULL, 0), reinterpret_cast<const Bytef*>(buf), len); |
| 1346 len); | |
| 1347 if (actual_crc32 != range->data_crc32) { | 1344 if (actual_crc32 != range->data_crc32) { |
| 1348 DLOG(WARNING) << "Sparse range crc32 mismatch."; | 1345 DLOG(WARNING) << "Sparse range crc32 mismatch."; |
| 1349 return false; | 1346 return false; |
| 1350 } | 1347 } |
| 1351 } | 1348 } |
| 1352 // TODO(ttuttle): Incremental crc32 calculation? | 1349 // TODO(ttuttle): Incremental crc32 calculation? |
| 1353 | 1350 |
| 1354 return true; | 1351 return true; |
| 1355 } | 1352 } |
| 1356 | 1353 |
| 1357 bool SimpleSynchronousEntry::WriteSparseRange(SparseRange* range, | 1354 bool SimpleSynchronousEntry::WriteSparseRange(SparseRange* range, |
| 1358 int offset, int len, | 1355 int offset, int len, |
| 1359 const char* buf) { | 1356 const char* buf) { |
| 1360 DCHECK(range); | 1357 DCHECK(range); |
| 1361 DCHECK(buf); | 1358 DCHECK(buf); |
| 1362 DCHECK_LE(offset, range->length); | 1359 DCHECK_LE(offset, range->length); |
| 1363 DCHECK_LE(offset + len, range->length); | 1360 DCHECK_LE(offset + len, range->length); |
| 1364 | 1361 |
| 1365 uint32 new_crc32 = 0; | 1362 uint32_t new_crc32 = 0; |
| 1366 if (offset == 0 && len == range->length) { | 1363 if (offset == 0 && len == range->length) { |
| 1367 new_crc32 = crc32(crc32(0L, Z_NULL, 0), | 1364 new_crc32 = crc32(crc32(0L, Z_NULL, 0), |
| 1368 reinterpret_cast<const Bytef*>(buf), | 1365 reinterpret_cast<const Bytef*>(buf), |
| 1369 len); | 1366 len); |
| 1370 } | 1367 } |
| 1371 | 1368 |
| 1372 if (new_crc32 != range->data_crc32) { | 1369 if (new_crc32 != range->data_crc32) { |
| 1373 range->data_crc32 = new_crc32; | 1370 range->data_crc32 = new_crc32; |
| 1374 | 1371 |
| 1375 SimpleFileSparseRangeHeader header; | 1372 SimpleFileSparseRangeHeader header; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1389 | 1386 |
| 1390 int bytes_written = sparse_file_.Write(range->file_offset + offset, buf, len); | 1387 int bytes_written = sparse_file_.Write(range->file_offset + offset, buf, len); |
| 1391 if (bytes_written < len) { | 1388 if (bytes_written < len) { |
| 1392 DLOG(WARNING) << "Could not write sparse range."; | 1389 DLOG(WARNING) << "Could not write sparse range."; |
| 1393 return false; | 1390 return false; |
| 1394 } | 1391 } |
| 1395 | 1392 |
| 1396 return true; | 1393 return true; |
| 1397 } | 1394 } |
| 1398 | 1395 |
| 1399 bool SimpleSynchronousEntry::AppendSparseRange(int64 offset, | 1396 bool SimpleSynchronousEntry::AppendSparseRange(int64_t offset, |
| 1400 int len, | 1397 int len, |
| 1401 const char* buf) { | 1398 const char* buf) { |
| 1402 DCHECK_GE(offset, 0); | 1399 DCHECK_GE(offset, 0); |
| 1403 DCHECK_GT(len, 0); | 1400 DCHECK_GT(len, 0); |
| 1404 DCHECK(buf); | 1401 DCHECK(buf); |
| 1405 | 1402 |
| 1406 uint32 data_crc32 = crc32(crc32(0L, Z_NULL, 0), | 1403 uint32_t data_crc32 = |
| 1407 reinterpret_cast<const Bytef*>(buf), | 1404 crc32(crc32(0L, Z_NULL, 0), reinterpret_cast<const Bytef*>(buf), len); |
| 1408 len); | |
| 1409 | 1405 |
| 1410 SimpleFileSparseRangeHeader header; | 1406 SimpleFileSparseRangeHeader header; |
| 1411 header.sparse_range_magic_number = kSimpleSparseRangeMagicNumber; | 1407 header.sparse_range_magic_number = kSimpleSparseRangeMagicNumber; |
| 1412 header.offset = offset; | 1408 header.offset = offset; |
| 1413 header.length = len; | 1409 header.length = len; |
| 1414 header.data_crc32 = data_crc32; | 1410 header.data_crc32 = data_crc32; |
| 1415 | 1411 |
| 1416 int bytes_written = sparse_file_.Write(sparse_tail_offset_, | 1412 int bytes_written = sparse_file_.Write(sparse_tail_offset_, |
| 1417 reinterpret_cast<char*>(&header), | 1413 reinterpret_cast<char*>(&header), |
| 1418 sizeof(header)); | 1414 sizeof(header)); |
| 1419 if (bytes_written != base::checked_cast<int>(sizeof(header))) { | 1415 if (bytes_written != base::checked_cast<int>(sizeof(header))) { |
| 1420 DLOG(WARNING) << "Could not append sparse range header."; | 1416 DLOG(WARNING) << "Could not append sparse range header."; |
| 1421 return false; | 1417 return false; |
| 1422 } | 1418 } |
| 1423 sparse_tail_offset_ += bytes_written; | 1419 sparse_tail_offset_ += bytes_written; |
| 1424 | 1420 |
| 1425 bytes_written = sparse_file_.Write(sparse_tail_offset_, buf, len); | 1421 bytes_written = sparse_file_.Write(sparse_tail_offset_, buf, len); |
| 1426 if (bytes_written < len) { | 1422 if (bytes_written < len) { |
| 1427 DLOG(WARNING) << "Could not append sparse range data."; | 1423 DLOG(WARNING) << "Could not append sparse range data."; |
| 1428 return false; | 1424 return false; |
| 1429 } | 1425 } |
| 1430 int64 data_file_offset = sparse_tail_offset_; | 1426 int64_t data_file_offset = sparse_tail_offset_; |
| 1431 sparse_tail_offset_ += bytes_written; | 1427 sparse_tail_offset_ += bytes_written; |
| 1432 | 1428 |
| 1433 SparseRange range; | 1429 SparseRange range; |
| 1434 range.offset = offset; | 1430 range.offset = offset; |
| 1435 range.length = len; | 1431 range.length = len; |
| 1436 range.data_crc32 = data_crc32; | 1432 range.data_crc32 = data_crc32; |
| 1437 range.file_offset = data_file_offset; | 1433 range.file_offset = data_file_offset; |
| 1438 sparse_ranges_.insert(std::make_pair(offset, range)); | 1434 sparse_ranges_.insert(std::make_pair(offset, range)); |
| 1439 | 1435 |
| 1440 return true; | 1436 return true; |
| 1441 } | 1437 } |
| 1442 | 1438 |
| 1443 } // namespace disk_cache | 1439 } // namespace disk_cache |
| OLD | NEW |