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

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: removed VLOG(0), oops 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, 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::TimeTicks 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::TimeTicks::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::TimeTicks now = base::TimeTicks::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)
168 : frame_(frame),
169 lru_(new MultiBuffer::GlobalLRU()),
170 block_shift_(kBlockSizeShift),
171 weak_factory_(this) {}
xhwang 2015/11/25 01:01:44 You can use Delegated Constructors here: https://
hubbe 2015/11/25 01:15:09 Lots of fancy new features. :) Done.
172
173 UrlIndex::UrlIndex(blink::WebFrame* frame, int block_shift)
174 : frame_(frame),
175 lru_(new MultiBuffer::GlobalLRU()),
176 block_shift_(block_shift),
177 weak_factory_(this) {}
178
179 UrlIndex::~UrlIndex() {}
180
181 void UrlIndex::RemoveUrlDataIfEmpty(const scoped_refptr<UrlData>& url_data) {
182 if (!url_data->multibuffer()->map().empty())
183 return;
184
185 auto i = by_url_.find(url_data->key());
186 if (i != by_url_.end() && i->second == url_data)
187 by_url_.erase(i);
188 }
189
190 scoped_refptr<UrlData> UrlIndex::GetByUrl(const GURL& gurl,
191 UrlData::CORSMode cors_mode) {
192 auto i = by_url_.find(std::make_pair(gurl, cors_mode));
193 if (i != by_url_.end() && i->second->Valid()) {
194 return i->second;
195 }
196 return NewUrlData(gurl, cors_mode);
197 }
198
199 scoped_refptr<UrlData> UrlIndex::NewUrlData(const GURL& url,
200 UrlData::CORSMode cors_mode) {
201 return new UrlData(url, cors_mode, weak_factory_.GetWeakPtr());
202 }
203
204 scoped_refptr<UrlData> UrlIndex::TryInsert(
205 const scoped_refptr<UrlData>& url_data) {
206 scoped_refptr<UrlData>* by_url_slot;
207 bool urldata_valid = url_data->Valid();
208 if (urldata_valid) {
209 by_url_slot = &by_url_.insert(std::make_pair(url_data->key(), url_data))
210 .first->second;
211 } else {
212 std::map<UrlData::KeyType, scoped_refptr<UrlData>>::iterator iter;
213 iter = by_url_.find(url_data->key());
214 if (iter == by_url_.end())
215 return url_data;
216 by_url_slot = &iter->second;
217 }
218 if (*by_url_slot == url_data)
219 return url_data;
220
221 // TODO(hubbe): Support etag validation.
222 if (!url_data->last_modified().is_null()) {
223 if ((*by_url_slot)->last_modified() != url_data->last_modified()) {
224 if (urldata_valid)
225 *by_url_slot = url_data;
226 return url_data;
227 }
228 }
229 // Check if we should replace the in-cache url data with our url data.
230 if (urldata_valid) {
231 if ((!(*by_url_slot)->Valid() ||
232 url_data->CachedSize() > (*by_url_slot)->CachedSize())) {
233 *by_url_slot = url_data;
234 } else {
235 (*by_url_slot)->MergeFrom(url_data);
236 }
237 }
238 return *by_url_slot;
239 }
240
241 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698