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

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: comments addressed 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
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)
20 : MultiBuffer(kBlockSizeShift, 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) {}
52
53 UrlData::~UrlData() {}
54
55 std::pair<GURL, UrlData::CORSMode> UrlData::key() const {
56 DCHECK(thread_checker_.CalledOnValidThread());
57 return std::make_pair(url(), cors_mode());
58 }
59
60 void UrlData::set_valid_until(base::TimeTicks valid_until) {
61 DCHECK(thread_checker_.CalledOnValidThread());
62 valid_until_ = valid_until;
63 }
64
65 void UrlData::MergeFrom(const scoped_refptr<UrlData>& other) {
66 // We're merging from another UrlData that refers to the *same*
67 // resource, so when we merge the metadata, we can use the most
68 // optimistic values.
69 DCHECK(thread_checker_.CalledOnValidThread());
70 valid_until_ = std::max(valid_until_, other->valid_until_);
71 // set_length() will not override the length if already known.
72 set_length(other->length_);
73 cacheable_ |= other->cacheable_;
74 range_supported_ |= other->range_supported_;
75 if (last_modified_.is_null()) {
76 last_modified_ = other->last_modified_;
77 }
78 multibuffer()->MergeFrom(other->multibuffer());
79 }
80
81 void UrlData::set_cacheable(bool cacheable) {
82 DCHECK(thread_checker_.CalledOnValidThread());
83 cacheable_ = cacheable;
84 }
85
86 void UrlData::set_length(int64 length) {
87 DCHECK(thread_checker_.CalledOnValidThread());
88 if (length != kPositionNotSpecified) {
89 length_ = length;
90 }
91 }
92
93 void UrlData::RedirectTo(const scoped_refptr<UrlData>& url_data) {
94 DCHECK(thread_checker_.CalledOnValidThread());
95 // Copy any cached data over to the new location.
96 url_data->multibuffer()->MergeFrom(multibuffer());
97
98 std::vector<RedirectCB> redirect_callbacks;
99 redirect_callbacks.swap(redirect_callbacks_);
100 for (const RedirectCB& cb : redirect_callbacks) {
101 cb.Run(url_data);
102 }
103 }
104
105 void UrlData::Fail() {
106 DCHECK(thread_checker_.CalledOnValidThread());
107 // Handled similar to a redirect.
108 std::vector<RedirectCB> redirect_callbacks;
109 redirect_callbacks.swap(redirect_callbacks_);
110 for (const RedirectCB& cb : redirect_callbacks) {
111 cb.Run(nullptr);
112 }
113 }
114
115 void UrlData::OnRedirect(const RedirectCB& cb) {
116 DCHECK(thread_checker_.CalledOnValidThread());
117 redirect_callbacks_.push_back(cb);
118 }
119
120 void UrlData::Use() {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 last_used_ = base::TimeTicks::Now();
123 }
124
125 void UrlData::OnEmpty() {
126 DCHECK(thread_checker_.CalledOnValidThread());
127 base::MessageLoop::current()->PostTask(
128 FROM_HERE, base::Bind(&UrlIndex::RemoveUrlDataIfEmpty, url_index_,
129 scoped_refptr<UrlData>(this)));
xhwang 2015/11/23 23:09:21 will s/scoped_refptr<UrlData>(this))/this/ work?
hubbe 2015/11/24 22:55:11 no: ../../base/bind.h:102:3: error: static_assert
130 }
131
132 bool UrlData::Valid() const {
133 DCHECK(thread_checker_.CalledOnValidThread());
134 base::TimeTicks now = base::TimeTicks::Now();
135 if (!range_supported_)
136 return false;
137 // When ranges are not supported, we cannot re-use cached data.
138 if (valid_until_ > now)
139 return true;
140 if (now - last_used_ <
141 base::TimeDelta::FromSeconds(kUrlMappingTimeoutSeconds))
142 return true;
143 return false;
144 }
145
146 void UrlData::set_last_modified(base::Time last_modified) {
147 DCHECK(thread_checker_.CalledOnValidThread());
148 last_modified_ = last_modified;
149 }
150
151 void UrlData::set_range_supported() {
152 DCHECK(thread_checker_.CalledOnValidThread());
153 range_supported_ = true;
154 }
155
156 ResourceMultiBuffer* UrlData::multibuffer() {
157 DCHECK(thread_checker_.CalledOnValidThread());
158 return &multibuffer_;
159 }
160
161 size_t UrlData::CachedSize() {
162 DCHECK(thread_checker_.CalledOnValidThread());
163 return multibuffer()->map().size();
164 }
165
166 UrlIndex::UrlIndex(blink::WebFrame* frame)
167 : frame_(frame), lru_(new MultiBuffer::GlobalLRU()), weak_factory_(this) {}
168
169 UrlIndex::~UrlIndex() {}
170
171 void UrlIndex::RemoveUrlDataIfEmpty(const scoped_refptr<UrlData>& url_data) {
172 if (!url_data->multibuffer()->map().empty())
173 return;
174
175 auto i = by_url_.find(url_data->key());
176 if (i != by_url_.end() && i->second == url_data)
177 by_url_.erase(i);
178 }
179
180 scoped_refptr<UrlData> UrlIndex::GetByUrl(const GURL& gurl,
181 UrlData::CORSMode cors_mode) {
182 auto i = by_url_.find(std::make_pair(gurl, cors_mode));
183 if (i != by_url_.end() && i->second->Valid()) {
184 return i->second;
185 }
186 return NewUrlData(gurl, cors_mode);
187 }
188
189 scoped_refptr<UrlData> UrlIndex::NewUrlData(const GURL& url,
190 UrlData::CORSMode cors_mode) {
191 return new UrlData(url, cors_mode, weak_factory_.GetWeakPtr());
192 }
193
194 scoped_refptr<UrlData> UrlIndex::TryInsert(
195 const scoped_refptr<UrlData>& url_data) {
196 scoped_refptr<UrlData>* by_url_slot;
197 bool urldata_valid = url_data->Valid();
198 if (urldata_valid) {
199 by_url_slot = &by_url_.insert(std::make_pair(url_data->key(), url_data))
200 .first->second;
201 } else {
202 std::map<UrlData::KeyType, scoped_refptr<UrlData>>::iterator iter;
203 iter = by_url_.find(url_data->key());
204 if (iter == by_url_.end())
205 return url_data;
206 by_url_slot = &iter->second;
207 }
208 if (*by_url_slot == url_data)
209 return url_data;
210
211 // TODO(hubbe): Support etag validation.
212 if (!url_data->last_modified().is_null()) {
213 if ((*by_url_slot)->last_modified() != url_data->last_modified()) {
214 if (urldata_valid)
215 *by_url_slot = url_data;
216 return url_data;
217 }
218 }
219 // Check if we should replace the in-cache url data with our url data.
220 if (urldata_valid) {
221 if ((!(*by_url_slot)->Valid() ||
222 url_data->CachedSize() > (*by_url_slot)->CachedSize())) {
223 *by_url_slot = url_data;
224 } else {
225 (*by_url_slot)->MergeFrom(url_data);
226 }
227 }
228 return *by_url_slot;
229 }
230
231 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698