/* 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 */ #include #include #include #include #include #include #include #include "type.h" #include "tree.h" #include "graph.h" #include "graph_v2.h" #include "helpers.h" /* Template expansion */ #include "v2-defs.h" #include "sp-template.c" #include "nodemgmt-template.c" #include "edgemgmt-template.c" #include "misc-template.c" /* algorithms for TREE state */ #define DGL_DEFINE_TREE_PROCS 1 #include "v2-defs.h" #include "sp-template.c" #include "span-template.c" #undef DGL_DEFINE_TREE_PROCS /* algorithms for FLAT state */ #define DGL_DEFINE_FLAT_PROCS 1 #include "v2-defs.h" #include "sp-template.c" #include "span-template.c" #undef DGL_DEFINE_FLAT_PROCS int dgl_dijkstra_V2(dglGraph_s * pgraph, dglSPReport_s ** ppReport, dglInt32_t * pDistance, dglInt32_t nStart, dglInt32_t nDestination, dglSPClip_fn fnClip, void *pvClipArg, dglSPCache_s * pCache) { if (pgraph->Flags & DGL_GS_FLAT) { return dgl_dijkstra_V2_FLAT(pgraph, ppReport, pDistance, nStart, nDestination, fnClip, pvClipArg, pCache); } else { return dgl_dijkstra_V2_TREE(pgraph, ppReport, pDistance, nStart, nDestination, fnClip, pvClipArg, pCache); } } int dgl_depthfirst_spanning_V2(dglGraph_s * pgraphIn, dglGraph_s * pgraphOut, dglInt32_t nVertex, void *pvVisited, dglSpanClip_fn fnClip, void *pvClipArg) { if (pgraphIn->Flags & DGL_GS_FLAT) { return dgl_span_depthfirst_spanning_V2_FLAT(pgraphIn, pgraphOut, nVertex, pvVisited, fnClip, pvClipArg); } else { return dgl_span_depthfirst_spanning_V2_TREE(pgraphIn, pgraphOut, nVertex, pvVisited, fnClip, pvClipArg); } } int dgl_minimum_spanning_V2(dglGraph_s * pgraphIn, dglGraph_s * pgraphOut, dglInt32_t nVertex, dglSpanClip_fn fnClip, void *pvClipArg) { if (pgraphIn->Flags & DGL_GS_FLAT) { return dgl_span_minimum_spanning_V2_FLAT(pgraphIn, pgraphOut, nVertex, fnClip, pvClipArg); } else { return dgl_span_minimum_spanning_V2_TREE(pgraphIn, pgraphOut, nVertex, fnClip, pvClipArg); } } int dgl_initialize_V2(dglGraph_s * pgraph) { if (pgraph->pNodeTree == NULL) pgraph->pNodeTree = avl_create(dglTreeNode2Compare, NULL, dglTreeGetAllocator()); if (pgraph->pNodeTree == NULL) { pgraph->iErrno = DGL_ERR_MemoryExhausted; return -pgraph->iErrno; } if (pgraph->pEdgeTree == NULL) pgraph->pEdgeTree = avl_create(dglTreeEdgeCompare, NULL, dglTreeGetAllocator()); if (pgraph->pEdgeTree == NULL) { pgraph->iErrno = DGL_ERR_MemoryExhausted; return -pgraph->iErrno; } return 0; } int dgl_release_V2(dglGraph_s * pgraph) { pgraph->iErrno = 0; if (pgraph->pNodeTree) avl_destroy(pgraph->pNodeTree, dglTreeNodeCancel); if (pgraph->pEdgeTree) avl_destroy(pgraph->pEdgeTree, dglTreeEdgeCancel); if (pgraph->pNodeBuffer) free(pgraph->pNodeBuffer); if (pgraph->pEdgeBuffer) free(pgraph->pEdgeBuffer); if (pgraph->edgePrioritizer.pvAVL) avl_destroy(pgraph->edgePrioritizer.pvAVL, dglTreeEdgePri32Cancel); if (pgraph->nodePrioritizer.pvAVL) avl_destroy(pgraph->nodePrioritizer.pvAVL, dglTreeNodePri32Cancel); return 0; } int dgl_write_V2(dglGraph_s * pgraph, int fd) { long nret, cnt, tot; pgraph->iErrno = 0; if (write(fd, &pgraph->Version, 1) != 1) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->Endian, 1) != 1) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->NodeAttrSize, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->EdgeAttrSize, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } for (cnt = 0; cnt < 16; cnt++) { if (write(fd, &pgraph->aOpaqueSet[cnt], sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } } if (write(fd, &pgraph->nnCost, sizeof(dglInt64_t)) != sizeof(dglInt64_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->cNode, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->cHead, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->cTail, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->cAlone, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->cEdge, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->iNodeBuffer, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } if (write(fd, &pgraph->iEdgeBuffer, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } for (tot = 0, cnt = pgraph->iNodeBuffer; tot < cnt; tot += nret) { if ((nret = write(fd, &pgraph->pNodeBuffer[tot], cnt - tot)) <= 0) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } } for (tot = 0, cnt = pgraph->iEdgeBuffer; tot < cnt; tot += nret) { if ((nret = write(fd, &pgraph->pEdgeBuffer[tot], cnt - tot)) <= 0) { pgraph->iErrno = DGL_ERR_Write; return -pgraph->iErrno; } } return 0; } int dgl_read_V2(dglGraph_s * pgraph, int fd, int version) { long nret, cnt, tot; dglByte_t Endian; dglInt32_t NodeAttrSize, EdgeAttrSize; int i, cn, fSwap; dglInt32_t *pn; if (read(fd, &Endian, 1) != 1) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } fSwap = 0; #ifdef DGL_ENDIAN_BIG if (Endian == DGL_ENDIAN_LITTLE) fSwap = 1; #else if (Endian == DGL_ENDIAN_BIG) fSwap = 1; #endif if (read(fd, &NodeAttrSize, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&NodeAttrSize); if (read(fd, &EdgeAttrSize, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&EdgeAttrSize); if ((nret = dglInitialize(pgraph, version, NodeAttrSize, EdgeAttrSize, NULL)) < 0) { return nret; } for (cnt = 0; cnt < 16; cnt++) { if ((nret = read(fd, &pgraph->aOpaqueSet[cnt], sizeof(dglInt32_t))) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->aOpaqueSet[cnt]); } if (read(fd, &pgraph->nnCost, sizeof(dglInt64_t)) != sizeof(dglInt64_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt64Bytes(&pgraph->nnCost); if (read(fd, &pgraph->cNode, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->cNode); if (read(fd, &pgraph->cHead, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->cHead); if (read(fd, &pgraph->cTail, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->cTail); if (read(fd, &pgraph->cAlone, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->cAlone); if (read(fd, &pgraph->cEdge, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->cEdge); if (read(fd, &pgraph->iNodeBuffer, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->iNodeBuffer); if (read(fd, &pgraph->iEdgeBuffer, sizeof(dglInt32_t)) != sizeof(dglInt32_t)) { pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } if (fSwap) dgl_swapInt32Bytes(&pgraph->iEdgeBuffer); if ((pgraph->pNodeBuffer = malloc(pgraph->iNodeBuffer)) == NULL) { pgraph->iErrno = DGL_ERR_MemoryExhausted; return -pgraph->iErrno; } if ((pgraph->pEdgeBuffer = malloc(pgraph->iEdgeBuffer)) == NULL) { free(pgraph->pNodeBuffer); pgraph->iErrno = DGL_ERR_MemoryExhausted; return -pgraph->iErrno; } for (tot = 0, cnt = pgraph->iNodeBuffer; tot < cnt; tot += nret) { if ((nret = read(fd, &pgraph->pNodeBuffer[tot], cnt - tot)) <= 0) { free(pgraph->pNodeBuffer); free(pgraph->pEdgeBuffer); pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } } if (fSwap) { pn = (dglInt32_t *) pgraph->pNodeBuffer; cn = pgraph->iNodeBuffer / sizeof(dglInt32_t); for (i = 0; i < cn; i++) { dgl_swapInt32Bytes(&pn[i]); } } for (tot = 0, cnt = pgraph->iEdgeBuffer; tot < cnt; tot += nret) { if ((nret = read(fd, &pgraph->pEdgeBuffer[tot], cnt - tot)) <= 0) { free(pgraph->pNodeBuffer); free(pgraph->pEdgeBuffer); pgraph->iErrno = DGL_ERR_Read; return -pgraph->iErrno; } } if (fSwap) { pn = (dglInt32_t *) pgraph->pEdgeBuffer; cn = pgraph->iEdgeBuffer / sizeof(dglInt32_t); for (i = 0; i < cn; i++) { dgl_swapInt32Bytes(&pn[i]); } } pgraph->Flags |= 0x1; /* flat-state */ return 0; }