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

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

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

Powered by Google App Engine
This is Rietveld 408576698