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

Side by Side Diff: storage/browser/blob/blob_memory_controller.cc

Issue 2550113003: Revert of [BlobStorage] Implementing disk. (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « storage/browser/blob/blob_memory_controller.h ('k') | storage/browser/blob/blob_reader.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "storage/browser/blob/blob_memory_controller.h" 5 #include "storage/browser/blob/blob_memory_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <numeric>
9 8
10 #include "base/callback.h" 9 #include "base/callback.h"
11 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
12 #include "base/containers/small_map.h" 11 #include "base/containers/small_map.h"
13 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
14 #include "base/guid.h" 13 #include "base/guid.h"
15 #include "base/location.h" 14 #include "base/location.h"
16 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
18 #include "base/numerics/safe_conversions.h" 17 #include "base/numerics/safe_conversions.h"
(...skipping 20 matching lines...) Expand all
39 namespace { 38 namespace {
40 using FileCreationInfo = BlobMemoryController::FileCreationInfo; 39 using FileCreationInfo = BlobMemoryController::FileCreationInfo;
41 using MemoryAllocation = BlobMemoryController::MemoryAllocation; 40 using MemoryAllocation = BlobMemoryController::MemoryAllocation;
42 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask; 41 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask;
43 42
44 File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) { 43 File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) {
45 File::Error error = File::FILE_OK; 44 File::Error error = File::FILE_OK;
46 base::CreateDirectoryAndGetError(blob_storage_dir, &error); 45 base::CreateDirectoryAndGetError(blob_storage_dir, &error);
47 UMA_HISTOGRAM_ENUMERATION("Storage.Blob.CreateDirectoryResult", -error, 46 UMA_HISTOGRAM_ENUMERATION("Storage.Blob.CreateDirectoryResult", -error,
48 -File::FILE_ERROR_MAX); 47 -File::FILE_ERROR_MAX);
49 DLOG_IF(ERROR, error != File::FILE_OK)
50 << "Error creating blob storage directory: " << error;
51 return error; 48 return error;
52 } 49 }
53 50
54 void DestructFile(File infos_without_references) {} 51 void DestructFile(File infos_without_references) {}
55 52
56 // Used for new unpopulated file items. Caller must populate file reference in 53 // Used for new unpopulated file items. Caller must populate file reference in
57 // returned FileCreationInfos. 54 // returned FileCreationInfos.
58 std::pair<std::vector<FileCreationInfo>, File::Error> CreateEmptyFiles( 55 std::pair<std::vector<FileCreationInfo>, File::Error> CreateEmptyFiles(
59 const FilePath& blob_storage_dir, 56 const FilePath& blob_storage_dir,
60 scoped_refptr<base::TaskRunner> file_task_runner, 57 scoped_refptr<base::TaskRunner> file_task_runner,
61 std::vector<base::FilePath> file_paths) { 58 std::vector<base::FilePath> file_paths) {
62 base::ThreadRestrictions::AssertIOAllowed(); 59 base::ThreadRestrictions::AssertIOAllowed();
63 60
64 File::Error dir_create_status = CreateBlobDirectory(blob_storage_dir); 61 File::Error dir_create_status = CreateBlobDirectory(blob_storage_dir);
65 if (dir_create_status != File::FILE_OK) 62 if (dir_create_status != File::FILE_OK)
66 return std::make_pair(std::vector<FileCreationInfo>(), dir_create_status); 63 return std::make_pair(std::vector<FileCreationInfo>(), dir_create_status);
67 64
68 std::vector<FileCreationInfo> result; 65 std::vector<FileCreationInfo> result;
69 for (const base::FilePath& file_path : file_paths) { 66 for (const base::FilePath& file_path : file_paths) {
70 FileCreationInfo creation_info; 67 FileCreationInfo creation_info;
71 // Try to open our file. 68 // Try to open our file.
72 File file(file_path, File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE); 69 File file(file_path, File::FLAG_CREATE_ALWAYS | File::FLAG_WRITE);
73 creation_info.path = std::move(file_path); 70 creation_info.path = std::move(file_path);
74 creation_info.file_deletion_runner = file_task_runner; 71 creation_info.file_deletion_runner = file_task_runner;
75 creation_info.error = file.error_details(); 72 creation_info.error = file.error_details();
76 if (creation_info.error != File::FILE_OK) { 73 if (creation_info.error != File::FILE_OK) {
77 return std::make_pair(std::vector<FileCreationInfo>(), 74 return std::make_pair(std::vector<FileCreationInfo>(),
78 creation_info.error); 75 creation_info.error);
79 } 76 }
77
78 // Grab the file info to get the "last modified" time and store the file.
79 File::Info file_info;
80 bool success = file.GetInfo(&file_info);
81 creation_info.error = success ? File::FILE_OK : File::FILE_ERROR_FAILED;
82 if (!success) {
83 return std::make_pair(std::vector<FileCreationInfo>(),
84 creation_info.error);
85 }
80 creation_info.file = std::move(file); 86 creation_info.file = std::move(file);
81 87
82 result.push_back(std::move(creation_info)); 88 result.push_back(std::move(creation_info));
83 } 89 }
84 return std::make_pair(std::move(result), File::FILE_OK); 90 return std::make_pair(std::move(result), File::FILE_OK);
85 } 91 }
86 92
87 // Used to evict multiple memory items out to a single file. Caller must 93 // Used to evict multiple memory items out to a single file. Caller must
88 // populate file reference in returned FileCreationInfo. 94 // populate file reference in returned FileCreationInfo.
89 FileCreationInfo CreateFileAndWriteItems( 95 FileCreationInfo CreateFileAndWriteItems(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 file.WriteAtCurrentPos(element->bytes() + (length - bytes_left), 127 file.WriteAtCurrentPos(element->bytes() + (length - bytes_left),
122 base::saturated_cast<int>(bytes_left)); 128 base::saturated_cast<int>(bytes_left));
123 if (bytes_written < 0) 129 if (bytes_written < 0)
124 break; 130 break;
125 DCHECK_LE(static_cast<size_t>(bytes_written), bytes_left); 131 DCHECK_LE(static_cast<size_t>(bytes_written), bytes_left);
126 bytes_left -= bytes_written; 132 bytes_left -= bytes_written;
127 } 133 }
128 if (bytes_written < 0) 134 if (bytes_written < 0)
129 break; 135 break;
130 } 136 }
131 if (!file.Flush()) {
132 creation_info.error = File::FILE_ERROR_FAILED;
133 return creation_info;
134 }
135 137
136 File::Info info; 138 File::Info info;
137 bool success = file.GetInfo(&info); 139 bool success = file.GetInfo(&info);
138 creation_info.error = 140 creation_info.error =
139 bytes_written < 0 || !success ? File::FILE_ERROR_FAILED : File::FILE_OK; 141 bytes_written < 0 || !success ? File::FILE_ERROR_FAILED : File::FILE_OK;
140 creation_info.last_modified = info.last_modified; 142 creation_info.last_modified = info.last_modified;
141 return creation_info; 143 return creation_info;
142 } 144 }
143 145
144 uint64_t GetTotalSizeAndFileSizes( 146 uint64_t GetTotalSizeAndFileSizes(
145 const std::vector<scoped_refptr<ShareableBlobDataItem>>& 147 const std::vector<scoped_refptr<ShareableBlobDataItem>>&
146 unreserved_file_items, 148 unreserved_file_items,
147 std::vector<uint64_t>* file_sizes_output) { 149 std::vector<uint64_t>* file_sizes_output) {
148 uint64_t total_size_output = 0; 150 uint64_t total_size_output = 0;
149 base::SmallMap<std::map<uint64_t, uint64_t>> file_id_to_sizes; 151 base::SmallMap<std::map<uint64_t, uint64_t>> file_id_to_sizes;
150 for (const auto& item : unreserved_file_items) { 152 for (const auto& item : unreserved_file_items) {
151 const DataElement& element = item->item()->data_element(); 153 const DataElement& element = item->item()->data_element();
152 uint64_t file_id = BlobDataBuilder::GetFutureFileID(element); 154 uint64_t file_id = BlobDataBuilder::GetFutureFileID(element);
153 auto it = file_id_to_sizes.find(file_id); 155 auto it = file_id_to_sizes.find(file_id);
154 if (it != file_id_to_sizes.end()) 156 if (it != file_id_to_sizes.end())
155 it->second = std::max(it->second, element.offset() + element.length()); 157 it->second = std::max(it->second, element.offset() + element.length());
156 else 158 else
157 file_id_to_sizes[file_id] = element.offset() + element.length(); 159 file_id_to_sizes[file_id] = element.offset() + element.length();
158 total_size_output += element.length(); 160 total_size_output += element.length();
159 } 161 }
160 for (const auto& size_pair : file_id_to_sizes) { 162 for (const auto& size_pair : file_id_to_sizes) {
161 file_sizes_output->push_back(size_pair.second); 163 file_sizes_output->push_back(size_pair.second);
162 } 164 }
163 DCHECK_EQ(std::accumulate(file_sizes_output->begin(),
164 file_sizes_output->end(), 0ull),
165 total_size_output)
166 << "Illegal builder configuration, temporary files must be totally used.";
167 return total_size_output; 165 return total_size_output;
168 } 166 }
169 167
170 } // namespace 168 } // namespace
171 169
172 FileCreationInfo::FileCreationInfo() {} 170 FileCreationInfo::FileCreationInfo() {}
173 FileCreationInfo::~FileCreationInfo() { 171 FileCreationInfo::~FileCreationInfo() {
174 if (file.IsValid()) { 172 if (file.IsValid()) {
175 DCHECK(file_deletion_runner); 173 DCHECK(file_deletion_runner);
176 file_deletion_runner->PostTask( 174 file_deletion_runner->PostTask(
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 base::PostTaskAndReplyWithResult( 291 base::PostTaskAndReplyWithResult(
294 controller_->file_runner_.get(), FROM_HERE, 292 controller_->file_runner_.get(), FROM_HERE,
295 base::Bind(&CreateEmptyFiles, controller_->blob_storage_dir_, 293 base::Bind(&CreateEmptyFiles, controller_->blob_storage_dir_,
296 controller_->file_runner_, base::Passed(&file_paths)), 294 controller_->file_runner_, base::Passed(&file_paths)),
297 base::Bind(&FileQuotaAllocationTask::OnCreateEmptyFiles, 295 base::Bind(&FileQuotaAllocationTask::OnCreateEmptyFiles,
298 weak_factory_.GetWeakPtr(), base::Passed(&references))); 296 weak_factory_.GetWeakPtr(), base::Passed(&references)));
299 controller_->RecordTracingCounters(); 297 controller_->RecordTracingCounters();
300 } 298 }
301 ~FileQuotaAllocationTask() override {} 299 ~FileQuotaAllocationTask() override {}
302 300
303 void RunDoneCallback(std::vector<FileCreationInfo> file_info, bool success) { 301 void RunDoneCallback(bool success, std::vector<FileCreationInfo> file_info) {
304 // Make sure we clear the weak pointers we gave to the caller beforehand. 302 // Make sure we clear the weak pointers we gave to the caller beforehand.
305 weak_factory_.InvalidateWeakPtrs(); 303 weak_factory_.InvalidateWeakPtrs();
306 304
307 // We want to destroy this object on the exit of this method if we were 305 // We want to destroy this object on the exit of this method if we were
308 // successful. 306 // successful.
309 std::unique_ptr<FileQuotaAllocationTask> this_object; 307 std::unique_ptr<FileQuotaAllocationTask> this_object;
310 if (success) { 308 if (success) {
311 for (auto& item : pending_items_) { 309 for (auto& item : pending_items_) {
312 item->set_state(ShareableBlobDataItem::QUOTA_GRANTED); 310 item->set_state(ShareableBlobDataItem::QUOTA_GRANTED);
313 } 311 }
314 this_object = std::move(*my_list_position_); 312 this_object = std::move(*my_list_position_);
315 controller_->pending_file_quota_tasks_.erase(my_list_position_); 313 controller_->pending_file_quota_tasks_.erase(my_list_position_);
316 } 314 }
317 315
318 done_callback_.Run(std::move(file_info), success); 316 done_callback_.Run(success, std::move(file_info));
319 } 317 }
320 318
321 base::WeakPtr<QuotaAllocationTask> GetWeakPtr() { 319 base::WeakPtr<QuotaAllocationTask> GetWeakPtr() {
322 return weak_factory_.GetWeakPtr(); 320 return weak_factory_.GetWeakPtr();
323 } 321 }
324 322
325 void Cancel() override { 323 void Cancel() override {
326 // This call destroys this object. We rely on ShareableFileReference's 324 // This call destroys this object. We rely on ShareableFileReference's
327 // final release callback for disk_usage_ accounting. 325 // final release callback for disk_usage_ accounting.
328 controller_->pending_file_quota_tasks_.erase(my_list_position_); 326 controller_->pending_file_quota_tasks_.erase(my_list_position_);
329 } 327 }
330 328
331 void OnCreateEmptyFiles( 329 void OnCreateEmptyFiles(
332 std::vector<scoped_refptr<ShareableFileReference>> references, 330 std::vector<scoped_refptr<ShareableFileReference>> references,
333 std::pair<std::vector<FileCreationInfo>, File::Error> files_and_error) { 331 std::pair<std::vector<FileCreationInfo>, File::Error> files_and_error) {
334 auto& files = files_and_error.first; 332 auto& files = files_and_error.first;
335 if (files.empty()) { 333 if (files.empty()) {
336 DCHECK_GE(controller_->disk_used_, allocation_size_); 334 DCHECK_GE(controller_->disk_used_, allocation_size_);
337 controller_->disk_used_ -= allocation_size_; 335 controller_->disk_used_ -= allocation_size_;
338 // This will call our callback and delete the object correctly. 336 // This will call our callback and delete the object correctly.
339 controller_->DisableFilePaging(files_and_error.second); 337 controller_->DisableFilePaging(files_and_error.second);
340 return; 338 return;
341 } 339 }
342 DCHECK_EQ(files.size(), references.size()); 340 DCHECK_EQ(files.size(), references.size());
343 for (size_t i = 0; i < files.size(); i++) { 341 for (size_t i = 0; i < files.size(); i++) {
344 files[i].file_reference = std::move(references[i]); 342 files[i].file_reference = std::move(references[i]);
345 } 343 }
346 RunDoneCallback(std::move(files), true); 344 RunDoneCallback(true, std::move(files));
347 } 345 }
348 346
349 // The my_list_position_ iterator is stored so that we can remove ourself 347 // The my_list_position_ iterator is stored so that we can remove ourself
350 // from the task list when we are cancelled. 348 // from the task list when we are cancelled.
351 void set_my_list_position( 349 void set_my_list_position(
352 PendingFileQuotaTaskList::iterator my_list_position) { 350 PendingFileQuotaTaskList::iterator my_list_position) {
353 my_list_position_ = my_list_position; 351 my_list_position_ = my_list_position;
354 } 352 }
355 353
356 private: 354 private:
(...skipping 17 matching lines...) Expand all
374 file_runner_(std::move(file_runner)), 372 file_runner_(std::move(file_runner)),
375 populated_memory_items_( 373 populated_memory_items_(
376 base::MRUCache<uint64_t, ShareableBlobDataItem*>::NO_AUTO_EVICT), 374 base::MRUCache<uint64_t, ShareableBlobDataItem*>::NO_AUTO_EVICT),
377 weak_factory_(this) {} 375 weak_factory_(this) {}
378 376
379 BlobMemoryController::~BlobMemoryController() {} 377 BlobMemoryController::~BlobMemoryController() {}
380 378
381 void BlobMemoryController::DisableFilePaging(base::File::Error reason) { 379 void BlobMemoryController::DisableFilePaging(base::File::Error reason) {
382 UMA_HISTOGRAM_ENUMERATION("Storage.Blob.PagingDisabled", -reason, 380 UMA_HISTOGRAM_ENUMERATION("Storage.Blob.PagingDisabled", -reason,
383 -File::FILE_ERROR_MAX); 381 -File::FILE_ERROR_MAX);
384 DLOG(ERROR) << "Blob storage paging disabled, reason: " << reason;
385 file_paging_enabled_ = false; 382 file_paging_enabled_ = false;
386 in_flight_memory_used_ = 0; 383 in_flight_memory_used_ = 0;
387 items_paging_to_file_.clear(); 384 items_paging_to_file_.clear();
388 pending_evictions_ = 0; 385 pending_evictions_ = 0;
389 pending_memory_quota_total_size_ = 0; 386 pending_memory_quota_total_size_ = 0;
390 populated_memory_items_.Clear(); 387 populated_memory_items_.Clear();
391 populated_memory_items_bytes_ = 0; 388 populated_memory_items_bytes_ = 0;
392 file_runner_ = nullptr; 389 file_runner_ = nullptr;
393 390
394 PendingMemoryQuotaTaskList old_memory_tasks; 391 PendingMemoryQuotaTaskList old_memory_tasks;
395 PendingFileQuotaTaskList old_file_tasks; 392 PendingFileQuotaTaskList old_file_tasks;
396 std::swap(old_memory_tasks, pending_memory_quota_tasks_); 393 std::swap(old_memory_tasks, pending_memory_quota_tasks_);
397 std::swap(old_file_tasks, pending_file_quota_tasks_); 394 std::swap(old_file_tasks, pending_file_quota_tasks_);
398 395
399 // Don't call the callbacks until we have a consistent state. 396 // Don't call the callbacks until we have a consistent state.
400 for (auto& memory_request : old_memory_tasks) { 397 for (auto& memory_request : old_memory_tasks) {
401 memory_request->RunDoneCallback(false); 398 memory_request->RunDoneCallback(false);
402 } 399 }
403 for (auto& file_request : old_file_tasks) { 400 for (auto& file_request : old_file_tasks) {
404 file_request->RunDoneCallback(std::vector<FileCreationInfo>(), false); 401 file_request->RunDoneCallback(false, std::vector<FileCreationInfo>());
405 } 402 }
406 } 403 }
407 404
408 BlobMemoryController::Strategy BlobMemoryController::DetermineStrategy( 405 BlobMemoryController::Strategy BlobMemoryController::DetermineStrategy(
409 size_t preemptive_transported_bytes, 406 size_t preemptive_transported_bytes,
410 uint64_t total_transportation_bytes) const { 407 uint64_t total_transportation_bytes) const {
411 if (total_transportation_bytes == 0) 408 if (total_transportation_bytes == 0)
412 return Strategy::NONE_NEEDED; 409 return Strategy::NONE_NEEDED;
413 if (!CanReserveQuota(total_transportation_bytes)) 410 if (!CanReserveQuota(total_transportation_bytes))
414 return Strategy::TOO_LARGE; 411 return Strategy::TOO_LARGE;
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 MaybeGrantPendingMemoryRequests(); 738 MaybeGrantPendingMemoryRequests();
742 } 739 }
743 740
744 void BlobMemoryController::OnBlobFileDelete(uint64_t size, 741 void BlobMemoryController::OnBlobFileDelete(uint64_t size,
745 const FilePath& path) { 742 const FilePath& path) {
746 DCHECK_LE(size, disk_used_); 743 DCHECK_LE(size, disk_used_);
747 disk_used_ -= size; 744 disk_used_ -= size;
748 } 745 }
749 746
750 } // namespace storage 747 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/blob/blob_memory_controller.h ('k') | storage/browser/blob/blob_reader.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698