123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685 |
- /* LIBDGL -- a Directed Graph Library implementation
- * Copyright (C) 2002 Roberto Micarelli
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- /*
- * best view with tabstop=4
- */
- /*
- * Edge Traversing
- */
- int DGL_EDGE_T_INITIALIZE_FUNC(dglGraph_s * pGraph, dglEdgeTraverser_s * pT,
- dglEdgePrioritizer_s * pEP)
- {
- #if defined(_DGL_V1)
- pGraph->iErrno = DGL_ERR_NotSupported;
- return -pGraph->iErrno;
- #else
- if (pGraph->Flags & DGL_GS_FLAT) {
- if (pEP && pEP->pvAVL) {
- if ((pT->pvAVLT = malloc(sizeof(struct avl_traverser))) == NULL) {
- pGraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pGraph->iErrno;
- }
- avl_t_init(pT->pvAVLT, pEP->pvAVL);
- pT->pnEdge = NULL;
- pT->pEdgePrioritizer = pEP;
- }
- else {
- pT->pvAVLT = NULL;
- pT->pnEdge = NULL;
- pT->pEdgePrioritizer = NULL;
- }
- }
- else {
- if ((pT->pvAVLT = malloc(sizeof(struct avl_traverser))) == NULL) {
- pGraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pGraph->iErrno;
- }
- if (pEP && pEP->pvAVL) {
- avl_t_init(pT->pvAVLT, pEP->pvAVL);
- pT->pnEdge = NULL;
- pT->pEdgePrioritizer = pEP;
- }
- else {
- avl_t_init(pT->pvAVLT, pGraph->pEdgeTree);
- pT->pnEdge = NULL;
- pT->pEdgePrioritizer = NULL;
- }
- }
- pT->pGraph = pGraph;
- return 0;
- #endif
- }
- void DGL_EDGE_T_RELEASE_FUNC(dglEdgeTraverser_s * pT)
- {
- #if defined(_DGL_V1)
- pT->pGraph->iErrno = DGL_ERR_NotSupported;
- #else
- if (pT->pvAVLT)
- free(pT->pvAVLT);
- pT->pvAVLT = NULL;
- pT->pnEdge = NULL;
- pT->pEdgePrioritizer = NULL;
- #endif
- }
- dglInt32_t *DGL_EDGE_T_FIRST_FUNC(dglEdgeTraverser_s * pT)
- {
- #if defined(_DGL_V1)
- pT->pGraph->iErrno = DGL_ERR_NotSupported;
- return NULL;
- #else
- dglGraph_s *pG = pT->pGraph;
- pT->pnEdge = NULL;
- if (pT->pvAVLT && pT->pEdgePrioritizer) {
- dglEdgePrioritizer_s *pPri = pT->pEdgePrioritizer;
- dglTreeEdgePri32_s *pItem;
- pItem = avl_t_first(pT->pvAVLT, pPri->pvAVL);
- if (pItem) {
- /*
- printf("edge_t_first: cEdge=%ld\n", pItem->cnData);
- */
- pPri->cEdge = pItem->cnData;
- pPri->iEdge = 0;
- if (pPri->iEdge < pPri->cEdge) {
- pT->pnEdge =
- DGL_GET_EDGE_FUNC(pG, pItem->pnData[pPri->iEdge]);
- pPri->iEdge++;
- }
- }
- pPri->pEdgePri32Item = pItem;
- }
- else if (pT->pvAVLT) {
- dglTreeEdge_s *pEdgeItem;
- if ((pEdgeItem = avl_t_first(pT->pvAVLT, pG->pEdgeTree)) == NULL) {
- pT->pnEdge = NULL;
- }
- else {
- pT->pnEdge = pEdgeItem->pv;
- }
- }
- else {
- if (pG->cEdge > 0)
- pT->pnEdge = (dglInt32_t *) pG->pEdgeBuffer;
- else
- pT->pnEdge = NULL;
- }
- return pT->pnEdge;
- #endif
- }
- dglInt32_t *DGL_EDGE_T_NEXT_FUNC(dglEdgeTraverser_s * pT)
- {
- #if defined(_DGL_V1)
- pT->pGraph->iErrno = DGL_ERR_NotSupported;
- return NULL;
- #else
- dglGraph_s *pG = pT->pGraph;
- pT->pnEdge = NULL;
- if (pT->pvAVLT && pT->pEdgePrioritizer) {
- dglEdgePrioritizer_s *pPri = pT->pEdgePrioritizer;
- dglTreeEdgePri32_s *pItem = pPri->pEdgePri32Item;
- if (pItem && pPri->iEdge < pPri->cEdge) {
- pT->pnEdge = DGL_GET_EDGE_FUNC(pG, pItem->pnData[pPri->iEdge]);
- pPri->iEdge++;
- }
- else {
- if ((pItem = avl_t_next(pT->pvAVLT)) != NULL) {
- pPri->cEdge = pItem->cnData;
- pPri->iEdge = 0;
- if (pPri->iEdge < pPri->cEdge) {
- pT->pnEdge =
- DGL_GET_EDGE_FUNC(pG, pItem->pnData[pPri->iEdge]);
- pPri->iEdge++;
- }
- }
- pPri->pEdgePri32Item = pItem;
- }
- }
- else if (pT->pvAVLT) {
- dglTreeEdge_s *pItem;
- if ((pItem = avl_t_next(pT->pvAVLT)) != NULL) {
- pT->pnEdge = pItem->pv;
- }
- }
- else {
- pT->pnEdge += DGL_NODE_WSIZE(pG->EdgeAttrSize);
- if (pT->pnEdge >= (dglInt32_t *) (pG->pEdgeBuffer + pG->iEdgeBuffer)) {
- pT->pnEdge = NULL;
- }
- }
- return pT->pnEdge;
- #endif
- }
- /*
- * Node Traversing
- */
- int DGL_NODE_T_INITIALIZE_FUNC(dglGraph_s * pGraph, dglNodeTraverser_s * pT)
- {
- if (pGraph->Flags & DGL_GS_FLAT) {
- pT->pnNode = NULL;
- pT->pvAVLT = NULL;
- }
- else {
- if ((pT->pvAVLT = malloc(sizeof(struct avl_traverser))) == NULL) {
- pGraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pGraph->iErrno;
- }
- avl_t_init(pT->pvAVLT, pGraph->pNodeTree);
- pT->pnNode = NULL;
- }
- pT->pGraph = pGraph;
- return 0;
- }
- void DGL_NODE_T_RELEASE_FUNC(dglNodeTraverser_s * pT)
- {
- if (pT->pvAVLT)
- free(pT->pvAVLT);
- pT->pvAVLT = NULL;
- pT->pnNode = NULL;
- }
- dglInt32_t *DGL_NODE_T_FIRST_FUNC(dglNodeTraverser_s * pT)
- {
- DGL_T_NODEITEM_TYPE *pNodeItem;
- if (pT->pvAVLT) {
- if ((pNodeItem =
- avl_t_first(pT->pvAVLT, pT->pGraph->pNodeTree)) == NULL)
- pT->pnNode = NULL;
- else
- pT->pnNode = DGL_T_NODEITEM_NodePTR(pNodeItem);
- }
- else {
- if (pT->pGraph->cNode > 0)
- pT->pnNode = (dglInt32_t *) pT->pGraph->pNodeBuffer;
- else
- pT->pnNode = NULL;
- }
- return pT->pnNode;
- }
- dglInt32_t *DGL_NODE_T_NEXT_FUNC(dglNodeTraverser_s * pT)
- {
- DGL_T_NODEITEM_TYPE *pNodeItem;
- if (pT->pvAVLT) {
- if ((pNodeItem = avl_t_next(pT->pvAVLT)) == NULL)
- pT->pnNode = NULL;
- else
- pT->pnNode = DGL_T_NODEITEM_NodePTR(pNodeItem);
- }
- else {
- pT->pnNode += DGL_NODE_WSIZE(pT->pGraph->NodeAttrSize);
- if (pT->pnNode >=
- (dglInt32_t *) (pT->pGraph->pNodeBuffer +
- pT->pGraph->iNodeBuffer))
- pT->pnNode = NULL;
- }
- return pT->pnNode;
- }
- dglInt32_t *DGL_NODE_T_FIND_FUNC(dglNodeTraverser_s * pT, dglInt32_t nNodeId)
- {
- DGL_T_NODEITEM_TYPE *pNodeItem, findItem;
- if (pT->pvAVLT) {
- findItem.nKey = nNodeId;
- if ((pNodeItem =
- avl_t_find(pT->pvAVLT, pT->pGraph->pNodeTree,
- &findItem)) == NULL)
- pT->pnNode = NULL;
- else
- pT->pnNode = DGL_T_NODEITEM_NodePTR(pNodeItem);
- }
- else {
- pT->pnNode = DGL_GET_NODE_FUNC(pT->pGraph, nNodeId);
- }
- return pT->pnNode;
- }
- /*
- * Edgeset Traversing
- */
- int DGL_EDGESET_T_INITIALIZE_FUNC(dglGraph_s * pGraph,
- dglEdgesetTraverser_s * pT,
- dglInt32_t * pnEdgeset)
- {
- pT->pGraph = pGraph;
- pT->pnEdgeset = pnEdgeset;
- pT->cEdge = (pnEdgeset) ? *pnEdgeset : 0;
- pT->iEdge = 0;
- return 0;
- }
- void DGL_EDGESET_T_RELEASE_FUNC(dglEdgesetTraverser_s * pT)
- {
- }
- dglInt32_t *DGL_EDGESET_T_FIRST_FUNC(dglEdgesetTraverser_s * pT)
- {
- #if defined(_DGL_V2)
- dglInt32_t *pnOffset;
- dglTreeEdge_s *pEdgeItem, EdgeItem;
- #endif
- if (pT->cEdge == 0)
- return NULL;
- pT->iEdge = 1;
- #if defined(_DGL_V1)
- return pT->pnEdgeset + 1;
- #endif
- #if defined(_DGL_V2)
- pnOffset = pT->pnEdgeset + 1;
- if (pT->pGraph->Flags & DGL_GS_FLAT) {
- pT->pvCurrentItem = NULL;
- return DGL_EDGEBUFFER_SHIFT(pT->pGraph, *pnOffset);
- }
- else {
- EdgeItem.nKey = *pnOffset;
- if ((pEdgeItem = avl_find(pT->pGraph->pEdgeTree, &EdgeItem)) != NULL) {
- pT->pvCurrentItem = pEdgeItem;
- return pEdgeItem->pv;
- }
- }
- #endif
- return NULL;
- }
- dglInt32_t *DGL_EDGESET_T_NEXT_FUNC(dglEdgesetTraverser_s * pT)
- {
- #if defined(_DGL_V2)
- dglInt32_t *pnOffset;
- dglTreeEdge_s *pEdgeItem, EdgeItem;
- #endif
- if (pT->cEdge > 0 && pT->iEdge < pT->cEdge) {
- #if defined(_DGL_V1)
- return DGL_EDGESET_EDGE_PTR(pT->pnEdgeset, pT->iEdge++,
- pT->pGraph->EdgeAttrSize);
- #endif
- #if defined(_DGL_V2)
- pnOffset = pT->pnEdgeset + 1 + pT->iEdge++;
- if (pT->pGraph->Flags & DGL_GS_FLAT) {
- return DGL_EDGEBUFFER_SHIFT(pT->pGraph, *pnOffset);
- }
- else {
- EdgeItem.nKey = *pnOffset;
- if ((pEdgeItem =
- avl_find(pT->pGraph->pEdgeTree, &EdgeItem)) != NULL) {
- pT->pvCurrentItem = pEdgeItem;
- return pEdgeItem->pv;
- }
- }
- #endif
- }
- return NULL;
- }
- /*
- * Flatten the graph
- */
- int DGL_FLATTEN_FUNC(dglGraph_s * pgraph)
- {
- register DGL_T_NODEITEM_TYPE *ptreenode;
- #if defined(_DGL_V2)
- register dglTreeEdge_s *ptreeEdge;
- int i;
- #endif
- register dglInt32_t *pEdge;
- register dglInt32_t *pnode;
- register dglInt32_t *pnodescan;
- dglInt32_t *pOutEdgeset;
- dglInt32_t *pInEdgeset;
- int cOutEdgeset;
- int cInEdgeset;
- struct avl_traverser avlTraverser;
- if (pgraph->Flags & DGL_GS_FLAT) {
- pgraph->iErrno = DGL_ERR_BadOnFlatGraph;
- return -pgraph->iErrno;
- }
- pgraph->pNodeBuffer = NULL; /* should be already */
- pgraph->iNodeBuffer = 0;
- pgraph->pEdgeBuffer = NULL;
- pgraph->iEdgeBuffer = 0;
- #if defined(_DGL_V2)
- /*
- printf("flatten: traversing edges\n");
- */
- avl_t_init(&avlTraverser, pgraph->pEdgeTree);
- for (ptreeEdge = avl_t_first(&avlTraverser, pgraph->pEdgeTree);
- ptreeEdge; ptreeEdge = avl_t_next(&avlTraverser)
- ) {
- pEdge = ptreeEdge->pv;
- /*
- printf( "flatten: add edge %ld to edge buffer\n", DGL_EDGE_ID(pEdge) );
- */
- pgraph->pEdgeBuffer = realloc(pgraph->pEdgeBuffer,
- pgraph->iEdgeBuffer +
- DGL_EDGE_SIZEOF(pgraph->EdgeAttrSize)
- );
- if (pgraph->pEdgeBuffer == NULL) {
- pgraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pgraph->iErrno;
- }
- memcpy(pgraph->pEdgeBuffer + pgraph->iEdgeBuffer, pEdge,
- DGL_EDGE_SIZEOF(pgraph->EdgeAttrSize));
- pgraph->iEdgeBuffer += DGL_EDGE_SIZEOF(pgraph->EdgeAttrSize);
- }
- #endif
- /*
- printf("flatten: traversing nodes\n");
- */
- avl_t_init(&avlTraverser, pgraph->pNodeTree);
- for (ptreenode = avl_t_first(&avlTraverser, pgraph->pNodeTree);
- ptreenode; ptreenode = avl_t_next(&avlTraverser)
- ) {
- pnode = DGL_T_NODEITEM_NodePTR(ptreenode);
- pOutEdgeset = DGL_T_NODEITEM_OutEdgesetPTR(ptreenode);
- pInEdgeset = DGL_T_NODEITEM_InEdgesetPTR(ptreenode);
- if (!(DGL_NODE_STATUS(pnode) & DGL_NS_ALONE)) {
- cOutEdgeset = (pOutEdgeset) ?
- DGL_EDGESET_SIZEOF(DGL_EDGESET_EDGECOUNT(pOutEdgeset),
- pgraph->EdgeAttrSize) : sizeof(dglInt32_t);
- #if !defined(_DGL_V1)
- cInEdgeset = (pInEdgeset) ?
- DGL_EDGESET_SIZEOF(DGL_EDGESET_EDGECOUNT(pInEdgeset),
- pgraph->EdgeAttrSize) : sizeof(dglInt32_t);
- #else
- cInEdgeset = 0;
- #endif
- pgraph->pEdgeBuffer = realloc(pgraph->pEdgeBuffer,
- pgraph->iEdgeBuffer + cOutEdgeset +
- cInEdgeset);
- if (pgraph->pEdgeBuffer == NULL) {
- pgraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pgraph->iErrno;
- }
- {
- dglInt32_t nDummy = 0;
- memcpy(pgraph->pEdgeBuffer + pgraph->iEdgeBuffer,
- (pOutEdgeset) ? pOutEdgeset : &nDummy, cOutEdgeset);
- #if !defined(_DGL_V1)
- memcpy(pgraph->pEdgeBuffer + pgraph->iEdgeBuffer +
- cOutEdgeset, (pInEdgeset) ? pInEdgeset : &nDummy,
- cInEdgeset);
- #endif
- }
- DGL_NODE_EDGESET_OFFSET(pnode) = pgraph->iEdgeBuffer;
- pgraph->iEdgeBuffer += cOutEdgeset + cInEdgeset;
- }
- pgraph->pNodeBuffer =
- realloc(pgraph->pNodeBuffer,
- pgraph->iNodeBuffer +
- DGL_NODE_SIZEOF(pgraph->NodeAttrSize));
- if (pgraph->pNodeBuffer == NULL) {
- pgraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pgraph->iErrno;
- }
- memcpy(pgraph->pNodeBuffer + pgraph->iNodeBuffer, pnode,
- DGL_NODE_SIZEOF(pgraph->NodeAttrSize));
- pgraph->iNodeBuffer += DGL_NODE_SIZEOF(pgraph->NodeAttrSize);
- }
- #if defined(_DGL_V2)
- if (pgraph->pEdgeTree) {
- avl_destroy(pgraph->pEdgeTree, dglTreeEdgeCancel);
- pgraph->pEdgeTree = NULL;
- }
- #endif
- if (pgraph->pNodeTree) {
- avl_destroy(pgraph->pNodeTree, dglTreeNodeCancel);
- pgraph->pNodeTree = NULL;
- }
- pgraph->Flags |= DGL_GS_FLAT; /* flattened */
- /*
- * convert node-id to node-offset
- */
- DGL_FOREACH_NODE(pgraph, pnodescan) {
- if (!(DGL_NODE_STATUS(pnodescan) & DGL_NS_ALONE)) {
- pOutEdgeset =
- DGL_EDGEBUFFER_SHIFT(pgraph,
- DGL_NODE_EDGESET_OFFSET(pnodescan));
- #if defined(_DGL_V2)
- for (i = 0; i < pOutEdgeset[0]; i++) {
- /*
- printf("flatten: node %ld: scan out edge %ld/%ld - %ld\n", DGL_NODE_ID(pnodescan), i+1, pOutEdgeset[0], pOutEdgeset[i+1]);
- */
- pEdge = DGL_GET_EDGE_FUNC(pgraph, pOutEdgeset[i + 1]);
- if (pEdge == NULL) {
- pgraph->iErrno = DGL_ERR_UnexpectedNullPointer;
- return -pgraph->iErrno;
- }
- /*
- printf(" retrieved id %ld\n", DGL_EDGE_ID(pEdge) );
- */
- pOutEdgeset[i + 1] = DGL_EDGEBUFFER_OFFSET(pgraph, pEdge);
- }
- pInEdgeset = pOutEdgeset + pOutEdgeset[0] + 1;
- for (i = 0; i < pInEdgeset[0]; i++) {
- /*
- printf("flatten: node %ld: scan in edge %ld/%ld - %ld\n",
- DGL_NODE_ID(pnodescan), i+1, pInEdgeset[0], pInEdgeset[i+1]);
- */
- pEdge = DGL_GET_EDGE_FUNC(pgraph, pInEdgeset[i + 1]);
- if (pEdge == NULL) {
- pgraph->iErrno = DGL_ERR_UnexpectedNullPointer;
- return -pgraph->iErrno;
- }
- /*
- printf(" retrieved id %ld\n", DGL_EDGE_ID(pEdge) );
- */
- pInEdgeset[i + 1] = DGL_EDGEBUFFER_OFFSET(pgraph, pEdge);
- }
- #endif
- #if defined(_DGL_V2)
- {
- int iEdge;
- DGL_FOREACH_EDGE(pgraph, pOutEdgeset, pEdge, iEdge)
- #else
- DGL_FOREACH_EDGE(pgraph, pOutEdgeset, pEdge)
- #endif
- {
- if ((pnode =
- DGL_GET_NODE_FUNC(pgraph,
- DGL_EDGE_HEADNODE_OFFSET(pEdge))) ==
- NULL) {
- pgraph->iErrno = DGL_ERR_HeadNodeNotFound;
- return -pgraph->iErrno;
- }
- DGL_EDGE_HEADNODE_OFFSET(pEdge) =
- DGL_NODEBUFFER_OFFSET(pgraph, pnode);
- if ((pnode =
- DGL_GET_NODE_FUNC(pgraph,
- DGL_EDGE_TAILNODE_OFFSET(pEdge))) ==
- NULL) {
- pgraph->iErrno = DGL_ERR_TailNodeNotFound;
- return -pgraph->iErrno;
- }
- DGL_EDGE_TAILNODE_OFFSET(pEdge) =
- DGL_NODEBUFFER_OFFSET(pgraph, pnode);
- }
- #if defined(_DGL_V2)
- }
- #endif
- }
- }
- return 0;
- }
- int DGL_UNFLATTEN_FUNC(dglGraph_s * pgraph)
- {
- register dglInt32_t *pHead;
- register dglInt32_t *pTail;
- register dglInt32_t *pEdge;
- register dglInt32_t *pEdgeset;
- int nret;
- if (!(pgraph->Flags & DGL_GS_FLAT)) {
- pgraph->iErrno = DGL_ERR_BadOnTreeGraph;
- return -pgraph->iErrno;
- }
- /*
- * unflag it now to avoid DGL_ADD_EDGE_FUNC() failure
- */
- pgraph->Flags &= ~DGL_GS_FLAT;
- pgraph->cNode = 0;
- pgraph->cEdge = 0;
- pgraph->cHead = 0;
- pgraph->cTail = 0;
- pgraph->cAlone = 0;
- pgraph->nnCost = (dglInt64_t) 0;
- if (pgraph->pNodeTree == NULL)
- pgraph->pNodeTree =
- avl_create(DGL_T_NODEITEM_Compare, NULL, dglTreeGetAllocator());
- if (pgraph->pNodeTree == NULL) {
- pgraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pgraph->iErrno;
- }
- #if defined(_DGL_V1)
- pgraph->pEdgeTree = NULL;
- #else
- if (pgraph->pEdgeTree == NULL)
- pgraph->pEdgeTree =
- avl_create(dglTreeEdgeCompare, NULL, dglTreeGetAllocator());
- if (pgraph->pEdgeTree == NULL) {
- pgraph->iErrno = DGL_ERR_MemoryExhausted;
- return -pgraph->iErrno;
- }
- #endif
- DGL_FOREACH_NODE(pgraph, pHead) {
- if (DGL_NODE_STATUS(pHead) & DGL_NS_HEAD) {
- pEdgeset =
- DGL_EDGEBUFFER_SHIFT(pgraph, DGL_NODE_EDGESET_OFFSET(pHead));
- #if defined(_DGL_V2)
- {
- int iEdge;
- DGL_FOREACH_EDGE(pgraph, pEdgeset, pEdge, iEdge)
- #else
- DGL_FOREACH_EDGE(pgraph, pEdgeset, pEdge)
- #endif
- {
- pTail =
- DGL_NODEBUFFER_SHIFT(pgraph,
- DGL_EDGE_TAILNODE_OFFSET(pEdge));
- nret = DGL_ADD_EDGE_FUNC(pgraph,
- DGL_NODE_ID(pHead),
- DGL_NODE_ID(pTail),
- DGL_EDGE_COST(pEdge),
- DGL_EDGE_ID(pEdge),
- DGL_NODE_ATTR_PTR(pHead),
- DGL_NODE_ATTR_PTR(pTail),
- DGL_EDGE_ATTR_PTR(pEdge), 0);
- if (nret < 0) {
- goto error;
- }
- }
- #if defined(_DGL_V2)
- }
- #endif
- }
- else
- if (DGL_NODE_STATUS(pHead) & DGL_NS_ALONE) {
- nret = DGL_ADD_NODE_FUNC(pgraph,
- DGL_NODE_ID(pHead), DGL_NODE_ATTR_PTR(pHead), 0);
- if (nret < 0) {
- goto error;
- }
- }
- }
- /* move away flat-state data
- */
- if (pgraph->pNodeBuffer)
- free(pgraph->pNodeBuffer);
- if (pgraph->pEdgeBuffer)
- free(pgraph->pEdgeBuffer);
- pgraph->pNodeBuffer = NULL;
- pgraph->pEdgeBuffer = NULL;
- return 0;
- error:
- if (pgraph->pNodeTree)
- avl_destroy(pgraph->pNodeTree, dglTreeNodeCancel);
- if (pgraph->pEdgeTree)
- avl_destroy(pgraph->pEdgeTree, dglTreeEdgeCancel);
- pgraph->pNodeTree = NULL;
- pgraph->pEdgeTree = NULL;
- pgraph->Flags |= DGL_GS_FLAT;
- return nret;
- }
|