HTTP2PriorityQueue::Handle HTTP2PriorityQueue::addTransaction(HTTPCodec::StreamID id, http2::PriorityUpdate pri, HTTPTransaction *txn, bool permanent, uint64_t* depth) { CHECK_NE(id, 0); CHECK_NE(id, pri.streamDependency) << "Tried to create a loop in the tree"; CHECK(!txn || !permanent); Node *existingNode = find(id); if (existingNode) { CHECK(txn); CHECK(!permanent); existingNode->convertVirtualNode(txn); updatePriority(existingNode, pri); return existingNode; } if (!txn) { if (numVirtualNodes_ >= maxVirtualNodes_) { return nullptr; } numVirtualNodes_++; } Node* parent = &root_; if (depth) { *depth = 0; } if (pri.streamDependency != 0) { Node* dep = find(pri.streamDependency, depth); if (dep == nullptr) { // specified a missing parent (timed out an idle node)? VLOG(4) << "assigning default priority to txn=" << id; } else { parent = dep; } } VLOG(4) << "Adding id=" << id << " with parent=" << parent->getID() << " and weight=" << ((uint16_t)pri.weight + 1); auto node = folly::make_unique<Node>(*this, parent, id, pri.weight, txn); if (permanent) { node->setPermanent(); } else if (!txn) { scheduleNodeExpiration(node.get()); } auto result = parent->emplaceNode(std::move(node), pri.exclusive); pendingWeightChange_ = true; return result; }
ClusterEditingSolutionLight InducedCostHeuristicLight::solve() { // execute algorithm if (verbosity >= 1) std::cout<<"Running heuristic." << "."<<std::endl; if (verbosity >= 2) std::cout<<"Size of graph: " << graph.numNodes() << " nodes."<<std::endl; int totalEdges = edgeHeap.numUnprocessed(); for (unsigned int i = 0; i < graph.numEdges() + 1; i++) { Edge eIcf = edgeHeap.getMaxIcfEdge(); Edge eIcp = edgeHeap.getMaxIcpEdge(); if (eIcf == LightCompleteGraph::InvalidEdge || eIcp == LightCompleteGraph::InvalidEdge) { break; } EdgeWeight mIcf = edgeHeap.getIcf(eIcf); EdgeWeight mIcp = edgeHeap.getIcp(eIcp); if (mIcf >= mIcp) { // set eIcf to permanent setPermanent(eIcf); edgeHeap.removeEdge(eIcf); // resolve implications std::vector<NodeId> uClique(graph.getCliqueOf(eIcf.u)); std::vector<NodeId> vClique(graph.getCliqueOf(eIcf.v)); for (NodeId x : uClique) { for (NodeId y : vClique) { if (x == y) continue; Edge e = Edge(x,y); setPermanent(e); edgeHeap.removeEdge(e); } } } else { // set eIcp fo forbidden setForbidden(eIcp); edgeHeap.removeEdge(eIcp); // resolve implications std::vector<NodeId> uClique(graph.getCliqueOf(eIcp.u)); std::vector<NodeId> vClique(graph.getCliqueOf(eIcp.v)); for (NodeId x : uClique) { for (NodeId y : vClique) { if (x == y) continue; Edge e = Edge(x,y); setForbidden(e); edgeHeap.removeEdge(e); } } } if (verbosity >= 1 && i % 100 == 0) { std::cout<<"Completed "<<((totalEdges - edgeHeap.numUnprocessed())*100 / totalEdges)<<"%\r"<<std::flush; } } // calculate clustering if (verbosity >= 1) std::cout<<"Constructing result."<<std::endl; std::vector<std::vector<NodeId>> clusters; std::vector<int> clusterOfNode(graph.numNodes(), -1); for (NodeId u = 0; u < graph.numNodes(); u++) { // add cluster if not explored yet if (verbosity >= 1) std::cout<<"Completed "<<(u*100/graph.numNodes())<<"%\r"<<std::flush; if (clusterOfNode[u] == -1) { int c = clusters.size(); clusterOfNode[u] = c; clusters.push_back(std::vector<NodeId>(1, u)); for (NodeId v = u+1; v < graph.numNodes(); v++) { if (graph.getWeight(Edge(u, v)) == LightCompleteGraph::Permanent) { if (clusterOfNode[v] != -1) { std::cerr << "Conflicting clustering assignment for node " << v << std::endl; } clusterOfNode[v] = c; clusters[c].push_back(v); } } } } if (verbosity >= 2) { int sum = 0; for (std::vector<NodeId>& cluster : clusters) { sum += cluster.size(); } std::cout<<"Found " << clusters.size() << " clusters with a total of "<< sum << " nodes." << std::endl; } return ClusterEditingSolutionLight(totalCost, clusters); }