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

Side by Side Diff: net/spdy/http2_write_scheduler.h

Issue 2287783002: Remove stl_util's STLValueDeleter. (Closed)
Patch Set: fix Created 4 years, 3 months 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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 #ifndef NET_SPDY_HTTP2_WRITE_SCHEDULER_H_ 5 #ifndef NET_SPDY_HTTP2_WRITE_SCHEDULER_H_
6 #define NET_SPDY_HTTP2_WRITE_SCHEDULER_H_ 6 #define NET_SPDY_HTTP2_WRITE_SCHEDULER_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <cmath> 11 #include <cmath>
12 #include <deque> 12 #include <deque>
13 #include <map> 13 #include <map>
14 #include <memory> 14 #include <memory>
15 #include <queue> 15 #include <queue>
16 #include <set> 16 #include <set>
17 #include <tuple> 17 #include <tuple>
18 #include <unordered_map> 18 #include <unordered_map>
19 #include <utility> 19 #include <utility>
20 #include <vector> 20 #include <vector>
21 21
22 #include "base/containers/linked_list.h" 22 #include "base/containers/linked_list.h"
23 #include "base/logging.h" 23 #include "base/logging.h"
24 #include "base/macros.h" 24 #include "base/macros.h"
25 #include "base/memory/ptr_util.h"
25 #include "base/stl_util.h" 26 #include "base/stl_util.h"
cbentzel 2016/08/29 18:48:01 Do you know if this can be removed as part of this
Avi (use Gerrit) 2016/08/29 19:12:17 Missed it. Yes, it can.
26 #include "net/spdy/spdy_bug_tracker.h" 27 #include "net/spdy/spdy_bug_tracker.h"
27 #include "net/spdy/spdy_protocol.h" 28 #include "net/spdy/spdy_protocol.h"
28 #include "net/spdy/write_scheduler.h" 29 #include "net/spdy/write_scheduler.h"
29 30
30 namespace net { 31 namespace net {
31 32
32 namespace test { 33 namespace test {
33 template <typename StreamIdType> 34 template <typename StreamIdType>
34 class Http2PriorityWriteSchedulerPeer; 35 class Http2PriorityWriteSchedulerPeer;
35 } 36 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 size_t NumReadyStreams() const override; 75 size_t NumReadyStreams() const override;
75 76
76 // Return the number of streams currently in the tree. 77 // Return the number of streams currently in the tree.
77 int num_streams() const; 78 int num_streams() const;
78 79
79 private: 80 private:
80 friend class test::Http2PriorityWriteSchedulerPeer<StreamIdType>; 81 friend class test::Http2PriorityWriteSchedulerPeer<StreamIdType>;
81 82
82 struct StreamInfo; 83 struct StreamInfo;
83 using StreamInfoVector = std::vector<StreamInfo*>; 84 using StreamInfoVector = std::vector<StreamInfo*>;
84 using StreamInfoMap = std::unordered_map<StreamIdType, StreamInfo*>;
85 85
86 struct StreamInfo : public base::LinkNode<StreamInfo> { 86 struct StreamInfo : public base::LinkNode<StreamInfo> {
87 // ID for this stream. 87 // ID for this stream.
88 StreamIdType id; 88 StreamIdType id;
89 // StreamInfo for parent stream. 89 // StreamInfo for parent stream.
90 StreamInfo* parent = nullptr; 90 StreamInfo* parent = nullptr;
91 // Weights can range between 1 and 256 (inclusive). 91 // Weights can range between 1 and 256 (inclusive).
92 int weight = kHttp2DefaultStreamWeight; 92 int weight = kHttp2DefaultStreamWeight;
93 // The total weight of this stream's direct descendants. 93 // The total weight of this stream's direct descendants.
94 int total_child_weights = 0; 94 int total_child_weights = 0;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // Unless there are bugs, this should always return true. 160 // Unless there are bugs, this should always return true.
161 bool ValidateInvariantsForTests() const; 161 bool ValidateInvariantsForTests() const;
162 162
163 // Returns true if the parent stream has the given stream in its children. 163 // Returns true if the parent stream has the given stream in its children.
164 bool StreamHasChild(const StreamInfo& parent_info, 164 bool StreamHasChild(const StreamInfo& parent_info,
165 const StreamInfo* child_info) const; 165 const StreamInfo* child_info) const;
166 166
167 // Pointee owned by all_stream_infos_. 167 // Pointee owned by all_stream_infos_.
168 StreamInfo* root_stream_info_; 168 StreamInfo* root_stream_info_;
169 // Maps from stream IDs to StreamInfo objects. 169 // Maps from stream IDs to StreamInfo objects.
170 StreamInfoMap all_stream_infos_; 170 std::unordered_map<StreamIdType, std::unique_ptr<StreamInfo>>
171 base::STLValueDeleter<StreamInfoMap> all_stream_infos_deleter_; 171 all_stream_infos_;
172 // Queue containing all ready streams, ordered with streams of higher 172 // Queue containing all ready streams, ordered with streams of higher
173 // priority before streams of lower priority, and, among streams of equal 173 // priority before streams of lower priority, and, among streams of equal
174 // priority, streams with lower ordinal before those with higher 174 // priority, streams with lower ordinal before those with higher
175 // ordinal. Note that not all streams in scheduling_queue_ are eligible to be 175 // ordinal. Note that not all streams in scheduling_queue_ are eligible to be
176 // picked as the next stream: some may have ancestor stream(s) that are ready 176 // picked as the next stream: some may have ancestor stream(s) that are ready
177 // and unblocked. In these situations the occluded child streams are left in 177 // and unblocked. In these situations the occluded child streams are left in
178 // the queue, to reduce churn. 178 // the queue, to reduce churn.
179 base::LinkedList<StreamInfo> scheduling_queue_; 179 base::LinkedList<StreamInfo> scheduling_queue_;
180 // Ordinal value to assign to next node inserted into scheduling_queue_ when 180 // Ordinal value to assign to next node inserted into scheduling_queue_ when
181 // |add_to_front == true|. Decremented after each assignment. 181 // |add_to_front == true|. Decremented after each assignment.
182 int64_t head_ordinal_ = -1; 182 int64_t head_ordinal_ = -1;
183 // Ordinal value to assign to next node inserted into scheduling_queue_ when 183 // Ordinal value to assign to next node inserted into scheduling_queue_ when
184 // |add_to_front == false|. Incremented after each assignment. 184 // |add_to_front == false|. Incremented after each assignment.
185 int64_t tail_ordinal_ = 0; 185 int64_t tail_ordinal_ = 0;
186 186
187 DISALLOW_COPY_AND_ASSIGN(Http2PriorityWriteScheduler); 187 DISALLOW_COPY_AND_ASSIGN(Http2PriorityWriteScheduler);
188 }; 188 };
189 189
190 template <typename StreamIdType> 190 template <typename StreamIdType>
191 Http2PriorityWriteScheduler<StreamIdType>::Http2PriorityWriteScheduler() 191 Http2PriorityWriteScheduler<StreamIdType>::Http2PriorityWriteScheduler() {
192 : all_stream_infos_deleter_(&all_stream_infos_) { 192 std::unique_ptr<StreamInfo> root_stream_info = base::MakeUnique<StreamInfo>();
193 root_stream_info_ = new StreamInfo(); 193 root_stream_info_ = root_stream_info.get();
194 root_stream_info_->id = kHttp2RootStreamId; 194 root_stream_info->id = kHttp2RootStreamId;
195 root_stream_info_->weight = kHttp2DefaultStreamWeight; 195 root_stream_info->weight = kHttp2DefaultStreamWeight;
196 root_stream_info_->parent = nullptr; 196 root_stream_info->parent = nullptr;
197 root_stream_info_->priority = 1.0; 197 root_stream_info->priority = 1.0;
198 root_stream_info_->ready = false; 198 root_stream_info->ready = false;
199 all_stream_infos_[kHttp2RootStreamId] = root_stream_info_; 199 all_stream_infos_[kHttp2RootStreamId] = std::move(root_stream_info);
200 } 200 }
201 201
202 template <typename StreamIdType> 202 template <typename StreamIdType>
203 int Http2PriorityWriteScheduler<StreamIdType>::num_streams() const { 203 int Http2PriorityWriteScheduler<StreamIdType>::num_streams() const {
204 return all_stream_infos_.size(); 204 return all_stream_infos_.size();
205 } 205 }
206 206
207 template <typename StreamIdType> 207 template <typename StreamIdType>
208 bool Http2PriorityWriteScheduler<StreamIdType>::StreamRegistered( 208 bool Http2PriorityWriteScheduler<StreamIdType>::StreamRegistered(
209 StreamIdType stream_id) const { 209 StreamIdType stream_id) const {
(...skipping 12 matching lines...) Expand all
222 return; 222 return;
223 } 223 }
224 224
225 StreamInfo* parent = FindStream(precedence.parent_id()); 225 StreamInfo* parent = FindStream(precedence.parent_id());
226 if (parent == nullptr) { 226 if (parent == nullptr) {
227 // parent_id may legitimately not be registered yet--see b/15676312. 227 // parent_id may legitimately not be registered yet--see b/15676312.
228 DVLOG(1) << "Parent stream " << precedence.parent_id() << " not registered"; 228 DVLOG(1) << "Parent stream " << precedence.parent_id() << " not registered";
229 parent = root_stream_info_; 229 parent = root_stream_info_;
230 } 230 }
231 231
232 StreamInfo* new_stream_info = new StreamInfo; 232 std::unique_ptr<StreamInfo> new_stream_info = base::MakeUnique<StreamInfo>();
233 new_stream_info->id = stream_id; 233 StreamInfo* new_stream_info_ptr = new_stream_info.get();
234 new_stream_info->weight = precedence.weight(); 234 new_stream_info_ptr->id = stream_id;
235 new_stream_info->parent = parent; 235 new_stream_info_ptr->weight = precedence.weight();
236 all_stream_infos_[stream_id] = new_stream_info; 236 new_stream_info_ptr->parent = parent;
237 all_stream_infos_[stream_id] = std::move(new_stream_info);
237 if (precedence.is_exclusive()) { 238 if (precedence.is_exclusive()) {
238 // Move the parent's current children below the new stream. 239 // Move the parent's current children below the new stream.
239 using std::swap; 240 using std::swap;
240 swap(new_stream_info->children, parent->children); 241 swap(new_stream_info_ptr->children, parent->children);
cbentzel 2016/08/29 18:48:01 This might just be me - but seems a little strange
Avi (use Gerrit) 2016/08/29 19:12:17 I wasn't sure if the order mattered, especially if
cbentzel 2016/08/29 19:19:19 Agreed. I don't know that area of code well, addin
241 new_stream_info->total_child_weights = parent->total_child_weights; 242 new_stream_info_ptr->total_child_weights = parent->total_child_weights;
242 // Update each child's parent. 243 // Update each child's parent.
243 for (StreamInfo* child : new_stream_info->children) { 244 for (StreamInfo* child : new_stream_info_ptr->children) {
244 child->parent = new_stream_info; 245 child->parent = new_stream_info_ptr;
245 } 246 }
246 // Clear parent's old child data. 247 // Clear parent's old child data.
247 DCHECK(parent->children.empty()); 248 DCHECK(parent->children.empty());
248 parent->total_child_weights = 0; 249 parent->total_child_weights = 0;
249 } 250 }
250 // Add new stream to parent. 251 // Add new stream to parent.
251 parent->children.push_back(new_stream_info); 252 parent->children.push_back(new_stream_info_ptr);
252 parent->total_child_weights += precedence.weight(); 253 parent->total_child_weights += precedence.weight();
253 254
254 // Update all priorities under parent, since addition of a stream affects 255 // Update all priorities under parent, since addition of a stream affects
255 // sibling priorities as well. 256 // sibling priorities as well.
256 UpdatePrioritiesUnder(parent); 257 UpdatePrioritiesUnder(parent);
257 258
258 // Stream starts with ready == false, so no need to schedule it yet. 259 // Stream starts with ready == false, so no need to schedule it yet.
259 DCHECK(!new_stream_info->ready); 260 DCHECK(!new_stream_info_ptr->ready);
260 } 261 }
261 262
262 template <typename StreamIdType> 263 template <typename StreamIdType>
263 void Http2PriorityWriteScheduler<StreamIdType>::UnregisterStream( 264 void Http2PriorityWriteScheduler<StreamIdType>::UnregisterStream(
264 StreamIdType stream_id) { 265 StreamIdType stream_id) {
265 if (stream_id == kHttp2RootStreamId) { 266 if (stream_id == kHttp2RootStreamId) {
266 SPDY_BUG << "Cannot unregister root stream"; 267 SPDY_BUG << "Cannot unregister root stream";
267 return; 268 return;
268 } 269 }
269 // Remove the stream from table. 270 // Remove the stream from table.
270 typename StreamInfoMap::iterator it = all_stream_infos_.find(stream_id); 271 auto it = all_stream_infos_.find(stream_id);
271 if (it == all_stream_infos_.end()) { 272 if (it == all_stream_infos_.end()) {
272 SPDY_BUG << "Stream " << stream_id << " not registered"; 273 SPDY_BUG << "Stream " << stream_id << " not registered";
273 return; 274 return;
274 } 275 }
275 std::unique_ptr<StreamInfo> stream_info(std::move(it->second)); 276 std::unique_ptr<StreamInfo> stream_info(std::move(it->second));
276 all_stream_infos_.erase(it); 277 all_stream_infos_.erase(it);
277 // If ready (and hence scheduled), unschedule. 278 // If ready (and hence scheduled), unschedule.
278 if (stream_info->ready) { 279 if (stream_info->ready) {
279 Unschedule(stream_info.get()); 280 Unschedule(stream_info.get());
280 } 281 }
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 return true; 569 return true;
569 } 570 }
570 } 571 }
571 return false; 572 return false;
572 } 573 }
573 574
574 template <typename StreamIdType> 575 template <typename StreamIdType>
575 const typename Http2PriorityWriteScheduler<StreamIdType>::StreamInfo* 576 const typename Http2PriorityWriteScheduler<StreamIdType>::StreamInfo*
576 Http2PriorityWriteScheduler<StreamIdType>::FindStream( 577 Http2PriorityWriteScheduler<StreamIdType>::FindStream(
577 StreamIdType stream_id) const { 578 StreamIdType stream_id) const {
578 typename StreamInfoMap::const_iterator it = all_stream_infos_.find(stream_id); 579 auto it = all_stream_infos_.find(stream_id);
579 return it == all_stream_infos_.end() ? nullptr : it->second; 580 return it == all_stream_infos_.end() ? nullptr : it->second.get();
580 } 581 }
581 582
582 template <typename StreamIdType> 583 template <typename StreamIdType>
583 typename Http2PriorityWriteScheduler<StreamIdType>::StreamInfo* 584 typename Http2PriorityWriteScheduler<StreamIdType>::StreamInfo*
584 Http2PriorityWriteScheduler<StreamIdType>::FindStream(StreamIdType stream_id) { 585 Http2PriorityWriteScheduler<StreamIdType>::FindStream(StreamIdType stream_id) {
585 typename StreamInfoMap::iterator it = all_stream_infos_.find(stream_id); 586 auto it = all_stream_infos_.find(stream_id);
586 return it == all_stream_infos_.end() ? nullptr : it->second; 587 return it == all_stream_infos_.end() ? nullptr : it->second.get();
587 } 588 }
588 589
589 template <typename StreamIdType> 590 template <typename StreamIdType>
590 void Http2PriorityWriteScheduler<StreamIdType>::UpdatePrioritiesUnder( 591 void Http2PriorityWriteScheduler<StreamIdType>::UpdatePrioritiesUnder(
591 StreamInfo* stream_info) { 592 StreamInfo* stream_info) {
592 for (StreamInfo* child : stream_info->children) { 593 for (StreamInfo* child : stream_info->children) {
593 child->priority = stream_info->priority * 594 child->priority = stream_info->priority *
594 (static_cast<float>(child->weight) / 595 (static_cast<float>(child->weight) /
595 static_cast<float>(stream_info->total_child_weights)); 596 static_cast<float>(stream_info->total_child_weights));
596 if (child->ready) { 597 if (child->ready) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 template <typename StreamIdType> 681 template <typename StreamIdType>
681 bool Http2PriorityWriteScheduler<StreamIdType>::ValidateInvariantsForTests() 682 bool Http2PriorityWriteScheduler<StreamIdType>::ValidateInvariantsForTests()
682 const { 683 const {
683 int total_streams = 0; 684 int total_streams = 0;
684 int streams_visited = 0; 685 int streams_visited = 0;
685 // Iterate through all streams in the map. 686 // Iterate through all streams in the map.
686 for (const auto& kv : all_stream_infos_) { 687 for (const auto& kv : all_stream_infos_) {
687 ++total_streams; 688 ++total_streams;
688 ++streams_visited; 689 ++streams_visited;
689 StreamIdType stream_id = kv.first; 690 StreamIdType stream_id = kv.first;
690 const StreamInfo& stream_info = *kv.second; 691 const StreamInfo& stream_info = *kv.second.get();
691 692
692 // Verify each StreamInfo mapped under the proper stream ID. 693 // Verify each StreamInfo mapped under the proper stream ID.
693 if (stream_id != stream_info.id) { 694 if (stream_id != stream_info.id) {
694 DLOG(INFO) << "Stream ID " << stream_id << " maps to StreamInfo with ID " 695 DLOG(INFO) << "Stream ID " << stream_id << " maps to StreamInfo with ID "
695 << stream_info.id; 696 << stream_info.id;
696 return false; 697 return false;
697 } 698 }
698 699
699 // All streams except the root should have a parent, and should appear in 700 // All streams except the root should have a parent, and should appear in
700 // the children of that parent. 701 // the children of that parent.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 } 741 }
741 // Validate the validation function; we should have visited each stream twice 742 // Validate the validation function; we should have visited each stream twice
742 // (except for the root) 743 // (except for the root)
743 DCHECK(streams_visited == 2 * num_streams() - 1); 744 DCHECK(streams_visited == 2 * num_streams() - 1);
744 return true; 745 return true;
745 } 746 }
746 747
747 } // namespace net 748 } // namespace net
748 749
749 #endif // NET_SPDY_HTTP2_WRITE_SCHEDULER_H_ 750 #endif // NET_SPDY_HTTP2_WRITE_SCHEDULER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698