| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/browser/download/parallel_download_utils.h" | 5 #include "content/browser/download/parallel_download_utils.h" |
| 6 | 6 |
| 7 #include "base/metrics/field_trial_params.h" | 7 #include "base/metrics/field_trial_params.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "content/public/browser/download_save_info.h" | 10 #include "content/public/browser/download_save_info.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 | 35 |
| 36 // TODO(qinmin): replace this with a comparator operator in | 36 // TODO(qinmin): replace this with a comparator operator in |
| 37 // DownloadItem::ReceivedSlice. | 37 // DownloadItem::ReceivedSlice. |
| 38 bool compareReceivedSlices(const DownloadItem::ReceivedSlice& lhs, | 38 bool compareReceivedSlices(const DownloadItem::ReceivedSlice& lhs, |
| 39 const DownloadItem::ReceivedSlice& rhs) { | 39 const DownloadItem::ReceivedSlice& rhs) { |
| 40 return lhs.offset < rhs.offset; | 40 return lhs.offset < rhs.offset; |
| 41 } | 41 } |
| 42 | 42 |
| 43 } // namespace | 43 } // namespace |
| 44 | 44 |
| 45 bool ShouldUseParallelDownload(const DownloadCreateInfo& create_info) { |
| 46 // 1. Accept-Ranges, Content-Length and strong validators response headers. |
| 47 // 2. Feature |kParallelDownloading| enabled. |
| 48 // 3. Content-Length is no less than the minimum slice size configuration. |
| 49 // 3. TODO(xingliu) HTTP/1.1 protocol, not QUIC or HTTP/2. |
| 50 |
| 51 // Etag and last modified are stored into DownloadCreateInfo in |
| 52 // DownloadRequestCore only if the response header complies to the strong |
| 53 // validator rule. |
| 54 bool has_strong_validator = |
| 55 !create_info.etag.empty() || !create_info.last_modified.empty(); |
| 56 |
| 57 return has_strong_validator && create_info.accept_range && |
| 58 create_info.total_bytes >= GetMinSliceSizeConfig() && |
| 59 base::FeatureList::IsEnabled(features::kParallelDownloading); |
| 60 } |
| 61 |
| 62 std::vector<DownloadItem::ReceivedSlice> FindSlicesForRemainingContent( |
| 63 int64_t bytes_received, |
| 64 int64_t content_length, |
| 65 int request_count) { |
| 66 std::vector<DownloadItem::ReceivedSlice> slices_to_download; |
| 67 if (request_count <= 0) |
| 68 return slices_to_download; |
| 69 |
| 70 // TODO(xingliu): Consider to use minimum size of a slice. |
| 71 int64_t slice_size = content_length / request_count; |
| 72 slice_size = slice_size > 0 ? slice_size : 1; |
| 73 int64_t current_offset = bytes_received; |
| 74 for (int i = 0, num_requests = content_length / slice_size; |
| 75 i < num_requests - 1; ++i) { |
| 76 slices_to_download.emplace_back(current_offset, slice_size); |
| 77 current_offset += slice_size; |
| 78 } |
| 79 |
| 80 // Last slice is a half open slice, which results in sending range request |
| 81 // like "Range:50-" to fetch from 50 bytes to the end of the file. |
| 82 slices_to_download.emplace_back(current_offset, |
| 83 DownloadSaveInfo::kLengthFullContent); |
| 84 return slices_to_download; |
| 85 } |
| 86 |
| 45 std::vector<DownloadItem::ReceivedSlice> FindSlicesToDownload( | 87 std::vector<DownloadItem::ReceivedSlice> FindSlicesToDownload( |
| 46 const std::vector<DownloadItem::ReceivedSlice>& received_slices) { | 88 const std::vector<DownloadItem::ReceivedSlice>& received_slices) { |
| 47 std::vector<DownloadItem::ReceivedSlice> result; | 89 std::vector<DownloadItem::ReceivedSlice> result; |
| 48 if (received_slices.empty()) { | 90 if (received_slices.empty()) { |
| 49 result.emplace_back(0, DownloadSaveInfo::kLengthFullContent); | 91 result.emplace_back(0, DownloadSaveInfo::kLengthFullContent); |
| 50 return result; | 92 return result; |
| 51 } | 93 } |
| 52 | 94 |
| 53 std::vector<DownloadItem::ReceivedSlice>::const_iterator iter = | 95 std::vector<DownloadItem::ReceivedSlice>::const_iterator iter = |
| 54 received_slices.begin(); | 96 received_slices.begin(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 base::TimeDelta GetParallelRequestDelayConfig() { | 153 base::TimeDelta GetParallelRequestDelayConfig() { |
| 112 std::string finch_value = base::GetFieldTrialParamValueByFeature( | 154 std::string finch_value = base::GetFieldTrialParamValueByFeature( |
| 113 features::kParallelDownloading, kParallelRequestDelayFinchKey); | 155 features::kParallelDownloading, kParallelRequestDelayFinchKey); |
| 114 int64_t time_ms = 0; | 156 int64_t time_ms = 0; |
| 115 return base::StringToInt64(finch_value, &time_ms) | 157 return base::StringToInt64(finch_value, &time_ms) |
| 116 ? base::TimeDelta::FromMilliseconds(time_ms) | 158 ? base::TimeDelta::FromMilliseconds(time_ms) |
| 117 : base::TimeDelta::FromMilliseconds(0); | 159 : base::TimeDelta::FromMilliseconds(0); |
| 118 } | 160 } |
| 119 | 161 |
| 120 } // namespace content | 162 } // namespace content |
| OLD | NEW |