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_index.h" | 5 #include "net/disk_cache/simple/simple_index.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 // static | 166 // static |
167 void SimpleIndex::InsertInEntrySet( | 167 void SimpleIndex::InsertInEntrySet( |
168 const disk_cache::EntryMetadata& entry_metadata, | 168 const disk_cache::EntryMetadata& entry_metadata, |
169 EntrySet* entry_set) { | 169 EntrySet* entry_set) { |
170 DCHECK(entry_set); | 170 DCHECK(entry_set); |
171 entry_set->insert( | 171 entry_set->insert( |
172 std::make_pair(entry_metadata.GetHashKey(), entry_metadata)); | 172 std::make_pair(entry_metadata.GetHashKey(), entry_metadata)); |
173 } | 173 } |
174 | 174 |
175 void SimpleIndex::PostponeWritingToDisk() { | 175 void SimpleIndex::PostponeWritingToDisk() { |
| 176 if (!initialized_) |
| 177 return; |
176 const base::TimeDelta file_age = base::Time::Now() - last_write_to_disk_; | 178 const base::TimeDelta file_age = base::Time::Now() - last_write_to_disk_; |
177 if (file_age > base::TimeDelta::FromSeconds(kMaxWriteToDiskDelaySecs) && | 179 if (file_age > base::TimeDelta::FromSeconds(kMaxWriteToDiskDelaySecs) && |
178 write_to_disk_timer_.IsRunning()) { | 180 write_to_disk_timer_.IsRunning()) { |
179 // If the index file is too old and there is a timer programmed to run a | 181 // If the index file is too old and there is a timer programmed to run a |
180 // WriteToDisk soon, we don't postpone it, so we always WriteToDisk | 182 // WriteToDisk soon, we don't postpone it, so we always WriteToDisk |
181 // approximately every kMaxWriteToDiskDelaySecs. | 183 // approximately every kMaxWriteToDiskDelaySecs. |
182 return; | 184 return; |
183 } | 185 } |
184 | 186 |
185 // If the timer is already active, Start() will just Reset it, postponing it. | 187 // If the timer is already active, Start() will just Reset it, postponing it. |
186 write_to_disk_timer_.Start( | 188 write_to_disk_timer_.Start( |
187 FROM_HERE, | 189 FROM_HERE, |
188 base::TimeDelta::FromSeconds(kWriteToDiskDelaySecs), | 190 base::TimeDelta::FromSeconds(kWriteToDiskDelaySecs), |
189 base::Bind(&SimpleIndex::WriteToDisk, AsWeakPtr())); | 191 base::Bind(&SimpleIndex::WriteToDisk, AsWeakPtr())); |
190 } | 192 } |
191 | 193 |
192 // static | 194 // static |
| 195 bool SimpleIndex::IsIndexFileStale(const base::FilePath& index_filename) { |
| 196 base::PlatformFileInfo dir_info; |
| 197 base::PlatformFileInfo index_info; |
| 198 if (!file_util::GetFileInfo(index_filename.DirName(), &dir_info)) |
| 199 return false; |
| 200 DCHECK(dir_info.is_directory); |
| 201 if (!file_util::GetFileInfo(index_filename, &index_info)) |
| 202 return false; |
| 203 |
| 204 // Index file last_modified must be equal to the directory last_modified since |
| 205 // the last operation we do is ReplaceFile in the |
| 206 // SimpleIndexFile::WriteToDisk(). |
| 207 // If not true, we need to restore the index. |
| 208 return index_info.last_modified >= dir_info.last_modified; |
| 209 } |
| 210 |
| 211 // static |
193 void SimpleIndex::LoadFromDisk( | 212 void SimpleIndex::LoadFromDisk( |
194 const base::FilePath& index_filename, | 213 const base::FilePath& index_filename, |
195 base::SingleThreadTaskRunner* io_thread, | 214 base::SingleThreadTaskRunner* io_thread, |
196 const IndexCompletionCallback& completion_callback) { | 215 const IndexCompletionCallback& completion_callback) { |
197 scoped_ptr<EntrySet> index_file_entries = | 216 // TODO(felipeg): probably could load a stale index and use it for something. |
198 SimpleIndexFile::LoadFromDisk(index_filename); | 217 scoped_ptr<EntrySet> index_file_entries; |
| 218 // Only load if the index is not stale. |
| 219 if (!SimpleIndex::IsIndexFileStale(index_filename)) |
| 220 index_file_entries = SimpleIndexFile::LoadFromDisk(index_filename); |
199 | 221 |
200 bool force_index_flush = false; | 222 bool force_index_flush = false; |
201 if (!index_file_entries.get()) { | 223 if (!index_file_entries) { |
202 index_file_entries = SimpleIndex::RestoreFromDisk(index_filename); | 224 index_file_entries = SimpleIndex::RestoreFromDisk(index_filename); |
203 // When we restore from disk we write the merged index file to disk right | 225 // When we restore from disk we write the merged index file to disk right |
204 // away, this might save us from having to restore again next time. | 226 // away, this might save us from having to restore again next time. |
205 force_index_flush = true; | 227 force_index_flush = true; |
206 } | 228 } |
207 | 229 |
208 io_thread->PostTask(FROM_HERE, | 230 io_thread->PostTask(FROM_HERE, |
209 base::Bind(completion_callback, | 231 base::Bind(completion_callback, |
210 base::Passed(&index_file_entries), | 232 base::Passed(&index_file_entries), |
211 force_index_flush)); | 233 force_index_flush)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 | 296 |
275 // static | 297 // static |
276 void SimpleIndex::WriteToDiskInternal(const base::FilePath& index_filename, | 298 void SimpleIndex::WriteToDiskInternal(const base::FilePath& index_filename, |
277 scoped_ptr<Pickle> pickle) { | 299 scoped_ptr<Pickle> pickle) { |
278 SimpleIndexFile::WriteToDisk(index_filename, *pickle); | 300 SimpleIndexFile::WriteToDisk(index_filename, *pickle); |
279 } | 301 } |
280 | 302 |
281 void SimpleIndex::MergeInitializingSet(scoped_ptr<EntrySet> index_file_entries, | 303 void SimpleIndex::MergeInitializingSet(scoped_ptr<EntrySet> index_file_entries, |
282 bool force_index_flush) { | 304 bool force_index_flush) { |
283 DCHECK(io_thread_checker_.CalledOnValidThread()); | 305 DCHECK(io_thread_checker_.CalledOnValidThread()); |
| 306 DCHECK(index_file_entries); |
284 // First, remove the entries that are in the |removed_entries_| from both | 307 // First, remove the entries that are in the |removed_entries_| from both |
285 // sets. | 308 // sets. |
286 for (base::hash_set<uint64>::const_iterator it = | 309 for (base::hash_set<uint64>::const_iterator it = |
287 removed_entries_.begin(); it != removed_entries_.end(); ++it) { | 310 removed_entries_.begin(); it != removed_entries_.end(); ++it) { |
288 entries_set_.erase(*it); | 311 entries_set_.erase(*it); |
289 index_file_entries->erase(*it); | 312 index_file_entries->erase(*it); |
290 } | 313 } |
291 | 314 |
292 // Recalculate the cache size while merging the two sets. | 315 // Recalculate the cache size while merging the two sets. |
293 cache_size_ = 0; | 316 cache_size_ = 0; |
(...skipping 30 matching lines...) Expand all Loading... |
324 cache_size_); | 347 cache_size_); |
325 scoped_ptr<Pickle> pickle = SimpleIndexFile::Serialize(index_metadata, | 348 scoped_ptr<Pickle> pickle = SimpleIndexFile::Serialize(index_metadata, |
326 entries_set_); | 349 entries_set_); |
327 cache_thread_->PostTask(FROM_HERE, base::Bind( | 350 cache_thread_->PostTask(FROM_HERE, base::Bind( |
328 &SimpleIndex::WriteToDiskInternal, | 351 &SimpleIndex::WriteToDiskInternal, |
329 index_filename_, | 352 index_filename_, |
330 base::Passed(&pickle))); | 353 base::Passed(&pickle))); |
331 } | 354 } |
332 | 355 |
333 } // namespace disk_cache | 356 } // namespace disk_cache |
OLD | NEW |