void HTTP2PriorityQueue::nextEgress(HTTP2PriorityQueue::NextEgressResult& result) { struct WeightCmp { bool operator()(const std::pair<HTTPTransaction*, double>& t1, const std::pair<HTTPTransaction*, double>& t2) { return t1.second > t2.second; } }; result.reserve(activeCount_); nextEgressResults_.reset(&result); updateEnqueuedWeight(); Node::PendingList pendingNodes; pendingNodes.emplace_back(0, &root_, 1.0); bool stop = false; while (!stop && !pendingNodes.empty()) { Node* node = pendingNodes.front().node; if (node) { stop = node->visitBFS(pendingNodes.front().ratio, nextEgressResult, false, pendingNodes, true /* enqueued children */); } pendingNodes.pop_front(); } std::sort(result.begin(), result.end(), WeightCmp()); nextEgressResults_.release(); }
void HTTP2PriorityQueue::nextEgress(HTTP2PriorityQueue::NextEgressResult& result, bool spdyMode) { struct WeightCmp { bool operator()(const std::pair<HTTPTransaction*, double>& t1, const std::pair<HTTPTransaction*, double>& t2) { return t1.second > t2.second; } }; result.reserve(activeCount_); nextEgressResults_.reset(&result); updateEnqueuedWeight(); Node::PendingList pendingNodes; Node::PendingList pendingNodesTmp; pendingNodes.emplace_back(0, &root_, 1.0); bool stop = false; do { while (!stop && !pendingNodes.empty()) { Node* node = pendingNodes.front().node; if (node) { stop = node->visitBFS(pendingNodes.front().ratio, nextEgressResult, false, pendingNodesTmp, true /* enqueued children */); } pendingNodes.pop_front(); } // In SPDY mode, we stop as soon one level of the tree produces results, // then normalize the ratios. if (spdyMode && !result.empty() && !pendingNodesTmp.empty()) { double totalRatio = 0; for (auto &txnPair: result) { totalRatio += txnPair.second; } CHECK_GT(totalRatio, 0); for (auto &txnPair: result) { txnPair.second = txnPair.second / totalRatio; } break; } std::swap(pendingNodes, pendingNodesTmp); } while (!stop && !pendingNodes.empty()); std::sort(result.begin(), result.end(), WeightCmp()); nextEgressResults_.release(); }
void HTTP2PriorityQueue::iterateBFS( const std::function<bool(HTTPCodec::StreamID, HTTPTransaction *, double)>& fn, const std::function<bool()>& stopFn, bool all) { Node::PendingList pendingNodes{{0, &root_, 1.0}}; Node::PendingList newPendingNodes; bool stop = false; updateEnqueuedWeight(); while (!stop && !stopFn() && !pendingNodes.empty()) { CHECK(newPendingNodes.empty()); while (!stop && !pendingNodes.empty()) { Node* node = findInternal(pendingNodes.front().id); if (node) { stop = node->visitBFS(pendingNodes.front().ratio, fn, all, newPendingNodes, false /* all children */); } pendingNodes.pop_front(); } std::swap(pendingNodes, newPendingNodes); } }