void UpwardPlanRep::initMe() { m_Gamma.init(*this); isAugmented = false; FaceSinkGraph fsg(m_Gamma, s_hat); SList<face> extFaces; fsg.possibleExternalFaces(extFaces); OGDF_ASSERT(!extFaces.empty()); face f_ext = nullptr; for(face f : extFaces) { if (f_ext == nullptr) f_ext = f; else { if (f_ext->size() < f->size()) f_ext = f; } } m_Gamma.setExternalFace(f_ext); for(adjEntry adj : s_hat->adjEntries) { if (m_Gamma.rightFace(adj) == m_Gamma.externalFace()) { extFaceHandle = adj; break; } } computeSinkSwitches(); }
// // createSkeleton: creates a skeleton graph // DynamicSkeleton& DynamicSPQRTree::createSkeleton(node vT) const { DynamicSkeleton& S = *OGDF_NEW DynamicSkeleton(this, vT); SList<node> inMapV; for (edge eH : m_tNode_hEdges[vT]) { node sH = eH->source(); node tH = eH->target(); edge& eM = m_skelEdge[eH]; node& sM = m_mapV[sH]; node& tM = m_mapV[tH]; if (!sM) { sM = S.m_M.newNode(); S.m_origNode[sM] = sH; inMapV.pushBack(sH); } if (!tM) { tM = S.m_M.newNode(); S.m_origNode[tM] = tH; inMapV.pushBack(tH); } eM = S.m_M.newEdge(sM, tM); S.m_origEdge[eM] = eH; } while (!inMapV.empty()) m_mapV[inMapV.popFrontRet()] = nullptr; S.m_referenceEdge = m_tNode_hRefEdge[vT]; if (S.m_referenceEdge) S.m_referenceEdge = m_skelEdge[S.m_referenceEdge]; m_sk[vT] = &S; return S; }
void DynamicSPQRForest::createSPQR (node vB) const { Graph GC; NodeArray<node> origNode(GC,0); EdgeArray<edge> origEdge(GC,0); SListConstIterator<edge> iH; for (iH=m_bNode_hEdges[vB].begin(); iH.valid(); ++iH) m_htogc[(*iH)->source()] = m_htogc[(*iH)->target()] = 0; for (iH=m_bNode_hEdges[vB].begin(); iH.valid(); ++iH) { edge eH = *iH; node sH = eH->source(); node tH = eH->target(); node& sGC = m_htogc[sH]; node& tGC = m_htogc[tH]; if (!sGC) { sGC = GC.newNode(); origNode[sGC] = sH; } if (!tGC) { tGC = GC.newNode(); origNode[tGC] = tH; } origEdge[GC.newEdge(sGC,tGC)] = eH; } TricComp tricComp(GC); const GraphCopySimple& GCC = *tricComp.m_pGC; EdgeArray<node> partnerNode(GCC,0); EdgeArray<edge> partnerEdge(GCC,0); for (int i=0; i<tricComp.m_numComp; ++i) { const TricComp::CompStruct &C = tricComp.m_component[i]; if (C.m_edges.empty()) continue; node vT = m_T.newNode(); m_tNode_owner[vT] = vT; switch(C.m_type) { case TricComp::bond: m_tNode_type[vT] = PComp; m_bNode_numP[vB]++; break; case TricComp::polygon: m_tNode_type[vT] = SComp; m_bNode_numS[vB]++; break; case TricComp::triconnected: m_tNode_type[vT] = RComp; m_bNode_numR[vB]++; break; } for (ListConstIterator<edge> iGCC=C.m_edges.begin(); iGCC.valid(); ++iGCC) { edge eGCC = *iGCC; edge eH = GCC.original(eGCC); if (eH) eH = origEdge[eH]; else { node uH = origNode[GCC.original(eGCC->source())]; node vH = origNode[GCC.original(eGCC->target())]; eH = m_H.newEdge(uH,vH); if (!partnerNode[eGCC]) { partnerNode[eGCC] = vT; partnerEdge[eGCC] = eH; } else { m_T.newEdge(partnerNode[eGCC],vT); m_hEdge_twinEdge[eH] = partnerEdge[eGCC]; m_hEdge_twinEdge[partnerEdge[eGCC]] = eH; } } m_hEdge_position[eH] = m_tNode_hEdges[vT].pushBack(eH); m_hEdge_tNode[eH] = vT; } } m_bNode_SPQR[vB] = m_hEdge_tNode[origEdge[GC.firstEdge()]]; m_tNode_hRefEdge[m_bNode_SPQR[vB]] = 0; SList<node> lT; lT.pushBack(m_bNode_SPQR[vB]); lT.pushBack(0); while (!lT.empty()) { node vT = lT.popFrontRet(); node wT = lT.popFrontRet(); for (ListConstIterator<edge> iH=m_tNode_hEdges[vT].begin(); iH.valid(); ++iH) { edge eH = *iH; edge fH = m_hEdge_twinEdge[eH]; if (!fH) continue; node uT = m_hEdge_tNode[fH]; if (uT==wT) m_tNode_hRefEdge[vT] = eH; else { lT.pushBack(uT); lT.pushBack(vT); } } } }
uint32_t Scheduler::Run() { ThreadLocalInfo& info = GetLocalInfo(); info.current_task = NULL; uint32_t do_max_count = runnale_task_count_; uint32_t do_count = 0; Debug("Run --------------------------"); // 每次Run执行的协程数量不能多于当前runnable协程数量 // 以防wait状态的协程得不到执行。 while (do_count < do_max_count) { uint32_t cnt = std::max((uint32_t)1, std::min( do_max_count / GetOptions().chunk_count, GetOptions().max_chunk_size)); Debug("want pop %u tasks.", cnt); SList<Task> slist = run_task_.pop(cnt); Debug("really pop %u tasks.", cnt); if (slist.empty()) break; SList<Task>::iterator it = slist.begin(); while (it != slist.end()) { Task* tk = &*it; info.current_task = tk; Debug("enter task(%llu)", tk->id_); swapcontext(&info.scheduler, &tk->ctx_); ++do_count; Debug("exit task(%llu) state=%d", tk->id_, tk->state_); info.current_task = NULL; switch (tk->state_) { case TaskState::runnable: ++it; break; case TaskState::io_block: case TaskState::sync_block: --runnale_task_count_; it = slist.erase(it); wait_task_.push(tk); break; case TaskState::done: default: --task_count_; --runnale_task_count_; it = slist.erase(it); delete tk; break; } } Debug("push %d task return to runnable list", slist.size()); run_task_.push(slist); } static thread_local epoll_event evs[1024]; int n = epoll_wait(epoll_fd, evs, 1024, 1); Debug("do_count=%u, do epoll event, n = %d", do_count, n); for (int i = 0; i < n; ++i) { Task* tk = (Task*)evs[i].data.ptr; if (tk->unlink()) AddTask(tk); } return do_count; }
edge DynamicSPQRTree::updateInsertedEdge(edge eG) { SList<node> marked; node sH = m_gNode_hNode[eG->source()]; node tH = m_gNode_hNode[eG->target()]; for (adjEntry aH : sH->adjEdges) { edge fH = aH->theEdge(); node vT = spqrproper(fH); if (fH->opposite(sH) == tH) { if (m_tNode_type[vT] == PComp) { DynamicSPQRForest::updateInsertedEdge(eG); if (m_sk[vT]) { edge eH = m_gEdge_hEdge[eG]; edge fM = m_skelEdge[fH]; node sM = fM->source(); node tM = fM->target(); if (eH->source() == m_sk[vT]->m_origNode[tM]) { node uM = sM; sM = tM; tM = uM; } m_skelEdge[eH] = m_sk[vT]->getGraph().newEdge(sM, tM); m_sk[vT]->m_origEdge[m_skelEdge[eH]] = eH; } return eG; } else if (!m_hEdge_twinEdge[fH]) { DynamicSPQRForest::updateInsertedEdge(eG); if (m_sk[vT]) { edge gH = m_hEdge_twinEdge[m_tNode_hEdges[m_hEdge_tNode[fH]].front()]; m_skelEdge[gH] = m_skelEdge[fH]; m_sk[vT]->m_origEdge[m_skelEdge[gH]] = gH; } return eG; } else { m_tNode_isMarked[vT] = true; marked.pushBack(vT); } } else { m_tNode_isMarked[vT] = true; marked.pushBack(vT); } } int count = 0; node found[2]; for (adjEntry aH : tH->adjEdges) { edge fH = aH->theEdge(); node vT = spqrproper(fH); if (!m_tNode_isMarked[vT]) continue; found[count++] = vT; m_tNode_isMarked[vT] = false; } while (!marked.empty()) m_tNode_isMarked[marked.popFrontRet()] = false; if (count == 0) { node rT; SList<node>& pT = findPathSPQR(sH, tH, rT); for (node vT : pT) { if (m_sk[vT]) { delete m_sk[vT]; m_sk[vT] = nullptr; } } delete &pT; } else if (count == 1) { node vT = found[0]; if (m_sk[vT]) { delete m_sk[vT]; m_sk[vT] = nullptr; } } return DynamicSPQRForest::updateInsertedEdge(eG); }
void GEMLayout::call(GraphAttributes &AG) { const Graph &G = AG.constGraph(); if(G.empty()) return; // all edges straight-line AG.clearAllBends(); GraphCopy GC; GC.createEmpty(G); // compute connected component of G NodeArray<int> component(G); int numCC = connectedComponents(G,component); // intialize the array of lists of nodes contained in a CC Array<List<node> > nodesInCC(numCC); for(node v : G.nodes) nodesInCC[component[v]].pushBack(v); EdgeArray<edge> auxCopy(G); Array<DPoint> boundingBox(numCC); int i; for(i = 0; i < numCC; ++i) { GC.initByNodes(nodesInCC[i],auxCopy); GraphCopyAttributes AGC(GC,AG); for(node vCopy : GC.nodes) { node vOrig = GC.original(vCopy); AGC.x(vCopy) = AG.x(vOrig); AGC.y(vCopy) = AG.y(vOrig); } SList<node> permutation; // initialize node data m_impulseX.init(GC,0); m_impulseY.init(GC,0); m_skewGauge.init(GC,0); m_localTemperature.init(GC,m_initialTemperature); // initialize other data m_globalTemperature = m_initialTemperature; m_barycenterX = 0; m_barycenterY = 0; for(node v : GC.nodes) { m_barycenterX += weight(v) * AGC.x(v); m_barycenterY += weight(v) * AGC.y(v); } m_cos = cos(m_oscillationAngle / 2.0); m_sin = sin(Math::pi / 2 + m_rotationAngle / 2.0); // main loop int counter = m_numberOfRounds; while(OGDF_GEOM_ET.greater(m_globalTemperature,m_minimalTemperature) && counter--) { // choose nodes by random permutations if(permutation.empty()) { for(node v : GC.nodes) permutation.pushBack(v); permutation.permute(m_rng); } node v = permutation.popFrontRet(); // compute the impulse of node v computeImpulse(GC,AGC,v); // update node v updateNode(GC,AGC,v); } node vFirst = GC.firstNode(); double minX = AGC.x(vFirst), maxX = AGC.x(vFirst), minY = AGC.y(vFirst), maxY = AGC.y(vFirst); for(node vCopy : GC.nodes) { node v = GC.original(vCopy); AG.x(v) = AGC.x(vCopy); AG.y(v) = AGC.y(vCopy); if(AG.x(v)-AG.width (v)/2 < minX) minX = AG.x(v)-AG.width(v) /2; if(AG.x(v)+AG.width (v)/2 > maxX) maxX = AG.x(v)+AG.width(v) /2; if(AG.y(v)-AG.height(v)/2 < minY) minY = AG.y(v)-AG.height(v)/2; if(AG.y(v)+AG.height(v)/2 > maxY) maxY = AG.y(v)+AG.height(v)/2; } minX -= m_minDistCC; minY -= m_minDistCC; for(node vCopy : GC.nodes) { node v = GC.original(vCopy); AG.x(v) -= minX; AG.y(v) -= minY; } boundingBox[i] = DPoint(maxX - minX, maxY - minY); } Array<DPoint> offset(numCC); TileToRowsCCPacker packer; packer.call(boundingBox,offset,m_pageRatio); // The arrangement is given by offset to the origin of the coordinate // system. We still have to shift each node and edge by the offset // of its connected component. for(i = 0; i < numCC; ++i) { const List<node> &nodes = nodesInCC[i]; const double dx = offset[i].m_x; const double dy = offset[i].m_y; // iterate over all nodes in ith CC ListConstIterator<node> it; for(node v : nodes) { AG.x(v) += dx; AG.y(v) += dy; } } // free node data m_impulseX.init(); m_impulseY.init(); m_skewGauge.init(); m_localTemperature.init(); }