| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/chromeos/drive/drive_prefetcher.h" | 5 #include "chrome/browser/chromeos/drive/drive_prefetcher.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
| 11 #include "chrome/browser/chromeos/drive/drive.pb.h" | |
| 12 #include "chrome/browser/chromeos/drive/drive_file_system_interface.h" | 11 #include "chrome/browser/chromeos/drive/drive_file_system_interface.h" |
| 13 #include "chrome/browser/chromeos/drive/drive_file_system_util.h" | 12 #include "chrome/browser/chromeos/drive/drive_file_system_util.h" |
| 14 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
| 15 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 16 | 15 |
| 17 using content::BrowserThread; | 16 using content::BrowserThread; |
| 18 | 17 |
| 19 namespace drive { | 18 namespace drive { |
| 20 | 19 |
| 21 namespace { | 20 namespace { |
| 22 | 21 |
| 23 const int kInitialPrefetchCount = 100; | 22 const int kInitialPrefetchCount = 100; |
| 24 const int64 kPrefetchFileSizeLimit = 10 << 20; // 10MB | 23 const int64 kPrefetchFileSizeLimit = 10 << 20; // 10MB |
| 25 | 24 |
| 26 // Returns true if prefetching is disabled by a command line option. | 25 // Returns true if prefetching is disabled by a command line option. |
| 27 bool IsPrefetchDisabled() { | 26 bool IsPrefetchDisabled() { |
| 28 return CommandLine::ForCurrentProcess()->HasSwitch( | 27 return CommandLine::ForCurrentProcess()->HasSwitch( |
| 29 switches::kDisableDrivePrefetch); | 28 switches::kDisableDrivePrefetch); |
| 30 } | 29 } |
| 31 | 30 |
| 31 // Returns true if |left| has lower priority than |right|. |
| 32 bool ComparePrefetchPriority(const DriveEntryProto& left, |
| 33 const DriveEntryProto& right) { |
| 34 // First, compare last access time. The older entry has less priority. |
| 35 if (left.file_info().last_accessed() != right.file_info().last_accessed()) |
| 36 return left.file_info().last_accessed() < right.file_info().last_accessed(); |
| 37 |
| 38 // When the entries have the same last access time (which happens quite often |
| 39 // because Drive server doesn't set the field until an entry is viewed via |
| 40 // drive.google.com), we use last modified time as the tie breaker. |
| 41 if (left.file_info().last_modified() != right.file_info().last_modified()) |
| 42 return left.file_info().last_modified() < right.file_info().last_modified(); |
| 43 |
| 44 // Two entries have the same priority. To make this function a valid |
| 45 // comparator for std::set, we need to differentiate them anyhow. |
| 46 return left.resource_id() < right.resource_id(); |
| 47 } |
| 48 |
| 32 } | 49 } |
| 33 | 50 |
| 34 DrivePrefetcherOptions::DrivePrefetcherOptions() | 51 DrivePrefetcherOptions::DrivePrefetcherOptions() |
| 35 : initial_prefetch_count(kInitialPrefetchCount), | 52 : initial_prefetch_count(kInitialPrefetchCount), |
| 36 prefetch_file_size_limit(kPrefetchFileSizeLimit) { | 53 prefetch_file_size_limit(kPrefetchFileSizeLimit) { |
| 37 } | 54 } |
| 38 | 55 |
| 39 DrivePrefetcher::DrivePrefetcher(DriveFileSystemInterface* file_system, | 56 DrivePrefetcher::DrivePrefetcher(DriveFileSystemInterface* file_system, |
| 40 const DrivePrefetcherOptions& options) | 57 const DrivePrefetcherOptions& options) |
| 41 : number_of_inflight_prefetches_(0), | 58 : latest_files_(&ComparePrefetchPriority), |
| 59 number_of_inflight_prefetches_(0), |
| 42 number_of_inflight_traversals_(0), | 60 number_of_inflight_traversals_(0), |
| 43 should_suspend_prefetch_(true), | 61 should_suspend_prefetch_(true), |
| 44 initial_prefetch_count_(options.initial_prefetch_count), | 62 initial_prefetch_count_(options.initial_prefetch_count), |
| 45 prefetch_file_size_limit_(options.prefetch_file_size_limit), | 63 prefetch_file_size_limit_(options.prefetch_file_size_limit), |
| 46 file_system_(file_system), | 64 file_system_(file_system), |
| 47 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 65 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 49 file_system_->AddObserver(this); | 67 file_system_->AddObserver(this); |
| 50 } | 68 } |
| 51 | 69 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 DoPrefetch(); // Start next prefetch. | 142 DoPrefetch(); // Start next prefetch. |
| 125 } | 143 } |
| 126 | 144 |
| 127 void DrivePrefetcher::ReconstructQueue() { | 145 void DrivePrefetcher::ReconstructQueue() { |
| 128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 129 | 147 |
| 130 // Put the files with latest timestamp into the queue. | 148 // Put the files with latest timestamp into the queue. |
| 131 queue_.clear(); | 149 queue_.clear(); |
| 132 for (LatestFileSet::reverse_iterator it = latest_files_.rbegin(); | 150 for (LatestFileSet::reverse_iterator it = latest_files_.rbegin(); |
| 133 it != latest_files_.rend(); ++it) { | 151 it != latest_files_.rend(); ++it) { |
| 134 queue_.push_back(it->second); | 152 queue_.push_back(it->resource_id()); |
| 135 } | 153 } |
| 136 } | 154 } |
| 137 | 155 |
| 138 void DrivePrefetcher::VisitFile(const DriveEntryProto& entry) { | 156 void DrivePrefetcher::VisitFile(const DriveEntryProto& entry) { |
| 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 140 | 158 |
| 141 int64 last_access = entry.file_info().last_accessed(); | |
| 142 const std::string& resource_id = entry.resource_id(); | |
| 143 | |
| 144 // Excessively large files will not be fetched. | 159 // Excessively large files will not be fetched. |
| 145 if (entry.file_info().size() > prefetch_file_size_limit_) | 160 if (entry.file_info().size() > prefetch_file_size_limit_) |
| 146 return; | 161 return; |
| 147 | 162 |
| 148 // Remember the file in the set ordered by the |last_accessed| field. | 163 // Remember the file in the set ordered by the |last_accessed| field. |
| 149 latest_files_.insert(std::make_pair(last_access, resource_id)); | 164 latest_files_.insert(entry); |
| 150 // If the set become too big, forget the oldest entry. | 165 // If the set become too big, forget the oldest entry. |
| 151 if (latest_files_.size() > static_cast<size_t>(initial_prefetch_count_)) | 166 if (latest_files_.size() > static_cast<size_t>(initial_prefetch_count_)) |
| 152 latest_files_.erase(latest_files_.begin()); | 167 latest_files_.erase(latest_files_.begin()); |
| 153 } | 168 } |
| 154 | 169 |
| 155 void DrivePrefetcher::VisitDirectory(const FilePath& directory_path) { | 170 void DrivePrefetcher::VisitDirectory(const FilePath& directory_path) { |
| 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 157 | 172 |
| 158 ++number_of_inflight_traversals_; | 173 ++number_of_inflight_traversals_; |
| 159 file_system_->ReadDirectoryByPath( | 174 file_system_->ReadDirectoryByPath( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 DCHECK(number_of_inflight_traversals_ > 0); | 213 DCHECK(number_of_inflight_traversals_ > 0); |
| 199 | 214 |
| 200 --number_of_inflight_traversals_; | 215 --number_of_inflight_traversals_; |
| 201 if (number_of_inflight_traversals_ == 0) { | 216 if (number_of_inflight_traversals_ == 0) { |
| 202 ReconstructQueue(); | 217 ReconstructQueue(); |
| 203 DoPrefetch(); // Start prefetching. | 218 DoPrefetch(); // Start prefetching. |
| 204 } | 219 } |
| 205 } | 220 } |
| 206 | 221 |
| 207 } // namespace drive | 222 } // namespace drive |
| OLD | NEW |