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

Side by Side Diff: media/blink/url_index.cc

Issue 1399603003: Tie multibuffers to URLs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@media_cache
Patch Set: formatted Created 5 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 | « media/blink/url_index.h ('k') | media/blink/url_index_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <set>
6 #include <utility>
7
8 #include "base/bind.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/time/time.h"
11 #include "media/blink/resource_multibuffer_data_provider.h"
12 #include "media/blink/url_index.h"
13
14 namespace media {
15
16 const int kBlockSizeShift = 15; // 1<<15 == 32kb
17 const int kUrlMappingTimeoutSeconds = 300;
18
19 ResourceMultiBuffer::ResourceMultiBuffer(UrlData* url_data, int block_shift)
20 : MultiBuffer(block_shift, url_data->url_index_->lru_),
21 url_data_(url_data) {}
22
23 ResourceMultiBuffer::~ResourceMultiBuffer() {}
24
25 scoped_ptr<MultiBuffer::DataProvider> ResourceMultiBuffer::CreateWriter(
26 const MultiBufferBlockId& pos) {
27 ResourceMultiBufferDataProvider* ret =
28 new ResourceMultiBufferDataProvider(url_data_, pos);
29 ret->Start();
30 return scoped_ptr<MultiBuffer::DataProvider>(ret);
31 }
32
33 bool ResourceMultiBuffer::RangeSupported() const {
34 return url_data_->range_supported_;
35 }
36
37 void ResourceMultiBuffer::OnEmpty() {
38 url_data_->OnEmpty();
39 }
40
41 UrlData::UrlData(const GURL& url,
42 CORSMode cors_mode,
43 const base::WeakPtr<UrlIndex>& url_index)
44 : url_(url),
45 cors_mode_(cors_mode),
46 url_index_(url_index),
47 length_(kPositionNotSpecified),
48 range_supported_(false),
49 cacheable_(false),
50 last_used_(),
51 multibuffer_(this, url_index_->block_shift_),
52 frame_(url_index->frame()) {}
53
54 UrlData::~UrlData() {}
55
56 std::pair<GURL, UrlData::CORSMode> UrlData::key() const {
57 DCHECK(thread_checker_.CalledOnValidThread());
58 return std::make_pair(url(), cors_mode());
59 }
60
61 void UrlData::set_valid_until(base::Time valid_until) {
62 DCHECK(thread_checker_.CalledOnValidThread());
63 valid_until_ = valid_until;
64 }
65
66 void UrlData::MergeFrom(const scoped_refptr<UrlData>& other) {
67 // We're merging from another UrlData that refers to the *same*
68 // resource, so when we merge the metadata, we can use the most
69 // optimistic values.
70 DCHECK(thread_checker_.CalledOnValidThread());
71 valid_until_ = std::max(valid_until_, other->valid_until_);
72 // set_length() will not override the length if already known.
73 set_length(other->length_);
74 cacheable_ |= other->cacheable_;
75 range_supported_ |= other->range_supported_;
76 if (last_modified_.is_null()) {
77 last_modified_ = other->last_modified_;
78 }
79 multibuffer()->MergeFrom(other->multibuffer());
80 }
81
82 void UrlData::set_cacheable(bool cacheable) {
83 DCHECK(thread_checker_.CalledOnValidThread());
84 cacheable_ = cacheable;
85 }
86
87 void UrlData::set_length(int64 length) {
88 DCHECK(thread_checker_.CalledOnValidThread());
89 if (length != kPositionNotSpecified) {
90 length_ = length;
91 }
92 }
93
94 void UrlData::RedirectTo(const scoped_refptr<UrlData>& url_data) {
95 DCHECK(thread_checker_.CalledOnValidThread());
96 // Copy any cached data over to the new location.
97 url_data->multibuffer()->MergeFrom(multibuffer());
98
99 std::vector<RedirectCB> redirect_callbacks;
100 redirect_callbacks.swap(redirect_callbacks_);
101 for (const RedirectCB& cb : redirect_callbacks) {
102 cb.Run(url_data);
103 }
104 }
105
106 void UrlData::Fail() {
107 DCHECK(thread_checker_.CalledOnValidThread());
108 // Handled similar to a redirect.
109 std::vector<RedirectCB> redirect_callbacks;
110 redirect_callbacks.swap(redirect_callbacks_);
111 for (const RedirectCB& cb : redirect_callbacks) {
112 cb.Run(nullptr);
113 }
114 }
115
116 void UrlData::OnRedirect(const RedirectCB& cb) {
117 DCHECK(thread_checker_.CalledOnValidThread());
118 redirect_callbacks_.push_back(cb);
119 }
120
121 void UrlData::Use() {
122 DCHECK(thread_checker_.CalledOnValidThread());
123 last_used_ = base::Time::Now();
124 }
125
126 void UrlData::OnEmpty() {
127 DCHECK(thread_checker_.CalledOnValidThread());
128 base::MessageLoop::current()->PostTask(
129 FROM_HERE, base::Bind(&UrlIndex::RemoveUrlDataIfEmpty, url_index_,
130 scoped_refptr<UrlData>(this)));
131 }
132
133 bool UrlData::Valid() const {
134 DCHECK(thread_checker_.CalledOnValidThread());
135 base::Time now = base::Time::Now();
136 if (!range_supported_)
137 return false;
138 // When ranges are not supported, we cannot re-use cached data.
139 if (valid_until_ > now)
140 return true;
141 if (now - last_used_ <
142 base::TimeDelta::FromSeconds(kUrlMappingTimeoutSeconds))
143 return true;
144 return false;
145 }
146
147 void UrlData::set_last_modified(base::Time last_modified) {
148 DCHECK(thread_checker_.CalledOnValidThread());
149 last_modified_ = last_modified;
150 }
151
152 void UrlData::set_range_supported() {
153 DCHECK(thread_checker_.CalledOnValidThread());
154 range_supported_ = true;
155 }
156
157 ResourceMultiBuffer* UrlData::multibuffer() {
158 DCHECK(thread_checker_.CalledOnValidThread());
159 return &multibuffer_;
160 }
161
162 size_t UrlData::CachedSize() {
163 DCHECK(thread_checker_.CalledOnValidThread());
164 return multibuffer()->map().size();
165 }
166
167 UrlIndex::UrlIndex(blink::WebFrame* frame) : UrlIndex(frame, kBlockSizeShift) {}
168
169 UrlIndex::UrlIndex(blink::WebFrame* frame, int block_shift)
170 : frame_(frame),
171 lru_(new MultiBuffer::GlobalLRU()),
172 block_shift_(block_shift),
173 weak_factory_(this) {}
174
175 UrlIndex::~UrlIndex() {}
176
177 void UrlIndex::RemoveUrlDataIfEmpty(const scoped_refptr<UrlData>& url_data) {
178 if (!url_data->multibuffer()->map().empty())
179 return;
180
181 auto i = by_url_.find(url_data->key());
182 if (i != by_url_.end() && i->second == url_data)
183 by_url_.erase(i);
184 }
185
186 scoped_refptr<UrlData> UrlIndex::GetByUrl(const GURL& gurl,
187 UrlData::CORSMode cors_mode) {
188 auto i = by_url_.find(std::make_pair(gurl, cors_mode));
189 if (i != by_url_.end() && i->second->Valid()) {
190 return i->second;
191 }
192 return NewUrlData(gurl, cors_mode);
193 }
194
195 scoped_refptr<UrlData> UrlIndex::NewUrlData(const GURL& url,
196 UrlData::CORSMode cors_mode) {
197 return new UrlData(url, cors_mode, weak_factory_.GetWeakPtr());
198 }
199
200 scoped_refptr<UrlData> UrlIndex::TryInsert(
201 const scoped_refptr<UrlData>& url_data) {
202 scoped_refptr<UrlData>* by_url_slot;
203 bool urldata_valid = url_data->Valid();
204 if (urldata_valid) {
205 by_url_slot = &by_url_.insert(std::make_pair(url_data->key(), url_data))
206 .first->second;
207 } else {
208 std::map<UrlData::KeyType, scoped_refptr<UrlData>>::iterator iter;
209 iter = by_url_.find(url_data->key());
210 if (iter == by_url_.end())
211 return url_data;
212 by_url_slot = &iter->second;
213 }
214 if (*by_url_slot == url_data)
215 return url_data;
216
217 // TODO(hubbe): Support etag validation.
218 if (!url_data->last_modified().is_null()) {
219 if ((*by_url_slot)->last_modified() != url_data->last_modified()) {
220 if (urldata_valid)
221 *by_url_slot = url_data;
222 return url_data;
223 }
224 }
225 // Check if we should replace the in-cache url data with our url data.
226 if (urldata_valid) {
227 if ((!(*by_url_slot)->Valid() ||
228 url_data->CachedSize() > (*by_url_slot)->CachedSize())) {
229 *by_url_slot = url_data;
230 } else {
231 (*by_url_slot)->MergeFrom(url_data);
232 }
233 }
234 return *by_url_slot;
235 }
236
237 } // namespace media
OLDNEW
« no previous file with comments | « media/blink/url_index.h ('k') | media/blink/url_index_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698