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; }
void HTTP2PriorityQueue::removeTransaction(HTTP2PriorityQueue::Handle handle) { Node* node = handle; pendingWeightChange_ = true; // TODO: or require the node to do it? if (node->isEnqueued()) { clearPendingEgress(handle); } if (allowDanglingNodes() && numVirtualNodes_ < maxVirtualNodes_) { node->clearTransaction(); numVirtualNodes_++; scheduleNodeExpiration(node); } else { VLOG(5) << "Deleting dangling node over max id=" << handle->getID(); node->removeFromTree(); } }