GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
edgemgmt-template.c
Go to the documentation of this file.
1/* LIBDGL -- a Directed Graph Library implementation
2 * Copyright (C) 2002 Roberto Micarelli
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/*
20 * best view with tabstop=4
21 */
22
23#include <grass/gis.h>
24
25/*
26 * Add edge can be performed on TREE state graph. If the state is FLAT
27 * return BadOnFlatGraph error.
28 */
32{
39
40#if defined(_DGL_V2)
43 /* dglTreeEdge_s findEdge; */
44#endif
45
46 if (pgraph->Flags & DGL_GS_FLAT) {
48 return -pgraph->iErrno;
49 }
50
51#ifdef DGL_STATS
52 {
53 clock_t clk = clock();
54#endif
55
56 if ((pHeadNodeItem = DGL_T_NODEITEM_Add(pgraph->pNodeTree, nHead)) ==
57 NULL ||
59 NULL) {
61 return -pgraph->iErrno;
62 }
63
64#ifdef DGL_STATS
65 pgraph->clkNodeTree += clock() - clk;
66 pgraph->cNodeTree++;
67 pgraph->cNodeTree++;
68 }
69#endif
70
72 if ((pHead = DGL_NODE_ALLOC(pgraph->NodeAttrSize)) == NULL) {
74 return -1;
75 }
78 pgraph->cNode++;
79 pgraph->cHead++;
80 }
81 else {
84 pgraph->cHead++;
85 }
86
88 if ((pTail = DGL_NODE_ALLOC(pgraph->NodeAttrSize)) == NULL) {
90 return -pgraph->iErrno;
91 }
94 pgraph->cNode++;
95 pgraph->cTail++;
96 }
97 else {
100 pgraph->cTail++;
101 }
102
105
107 DGL_NODE_STATUS(pHead) &= ~DGL_NS_ALONE;
108 pgraph->cAlone--;
109 }
110
112 DGL_NODE_STATUS(pTail) &= ~DGL_NS_ALONE;
113 pgraph->cAlone--;
114 }
115
118
121
122 if (pvHeadAttr && pgraph->NodeAttrSize) {
124 }
125
126 if (pvTailAttr && pgraph->NodeAttrSize) {
128 }
129
130 /*
131 if ( DGL_T_NODEITEM_OutEdgesetPTR(pTailNodeItem) == NULL )
132 {
133 pEdgeset = DGL_EDGESET_ALLOC( 0 , pgraph->EdgeAttrSize );
134 if ( pEdgeset == NULL ) {
135 pgraph->iErrno = DGL_ERR_MemoryExhausted;
136 return -pgraph->iErrno;
137 }
138 DGL_EDGESET_EDGECOUNT(pEdgeset) = 0;
139 DGL_T_NODEITEM_Set_OutEdgesetPTR(pTailNodeItem,pEdgeset);
140 }
141 */
142
144 pEdgeset = DGL_EDGESET_ALLOC(1, pgraph->EdgeAttrSize);
145 if (pEdgeset == NULL) {
147 return -pgraph->iErrno;
148 }
151 }
152 else {
153 pEdgeset =
155 pgraph->EdgeAttrSize);
156
157 if (pEdgeset == NULL) {
159 return -pgraph->iErrno;
160 }
162 }
163
164#if defined(_DGL_V2)
165 /*
166 if ( DGL_T_NODEITEM_InEdgesetPTR(pHeadNodeItem) == NULL )
167 {
168 pinEdgeset = DGL_EDGESET_ALLOC( 0 , pgraph->EdgeAttrSize );
169 if ( pinEdgeset == NULL ) {
170 pgraph->iErrno = DGL_ERR_MemoryExhausted;
171 return -pgraph->iErrno;
172 }
173 DGL_EDGESET_EDGECOUNT(pinEdgeset) = 0;
174 DGL_T_NODEITEM_Set_InEdgesetPTR(pHeadNodeItem,pinEdgeset);
175 }
176 */
177
179 pinEdgeset = DGL_EDGESET_ALLOC(1, pgraph->EdgeAttrSize);
180 if (pinEdgeset == NULL) {
182 return -pgraph->iErrno;
183 }
186 }
187 else {
190 pgraph->EdgeAttrSize);
191
192 if (pinEdgeset == NULL) {
194 return -pgraph->iErrno;
195 }
197 }
198
199 /*
200 * Set the edge-tree
201 */
202 /* findEdge.nKey = nEdge; */
203
204 if ((pEdgeItem = dglTreeEdgeAdd(pgraph->pEdgeTree, nEdge)) == NULL) {
206 return -pgraph->iErrno;
207 }
208 if (pEdgeItem->pv) {
210 return -pgraph->iErrno;
211 }
212 if ((pEdgeItem->pv = DGL_EDGE_ALLOC(pgraph->EdgeAttrSize)) == NULL) {
214 return -pgraph->iErrno;
215 }
216
217 /*
218 * assign edge id
219 */
224
225 /*
226 printf( "add edge: node %ld(%ld,%ld) -> %ld(%ld,%ld)\n",
227 DGL_NODE_ID(pHead), DGL_EDGESET_EDGECOUNT(pEdgeset),0,
228 DGL_NODE_ID(pTail), 0,DGL_EDGESET_EDGECOUNT(pinEdgeset));
229 */
230
231 pEdge = pEdgeItem->pv;
232#endif
233
234#if defined(_DGL_V1)
236 pgraph->EdgeAttrSize);
238#endif
239
241 nHead; /* will be an offset after flattening */
243 nTail; /* will be an offset after flattening */
244 DGL_EDGE_COST(pEdge) = nCost;
246
247#if !defined(_DGL_V1)
250 else
252#endif
253
254 pgraph->cEdge++;
255 pgraph->nnCost += (dglInt64_t)nCost;
256
257 if (pvEdgeAttr && pgraph->EdgeAttrSize) {
259 }
260
261 /*
262 * If requested add a cost-weighted entry into the edge prioritizer
263 */
264#if !defined(_DGL_V1)
265 if (pgraph->nOptions & DGL_GO_EdgePrioritize_COST) {
267 DGL_EDGE_COST(pEdge)) < 0) {
268 return -pgraph->iErrno;
269 }
270 }
271#endif
272
277 }
278
279 return 0;
280}
281
283{
284#if defined(_DGL_V1)
286 return -pgraph->iErrno;
287#else
290
291 if (pgraph->Flags & DGL_GS_FLAT) {
293 return -pgraph->iErrno;
294 }
295
296 if (pgraph->pEdgeTree == NULL) {
298 return -pgraph->iErrno;
299 }
300
301 findEdgeItem.nKey = nEdge;
302 if ((pEdgeItem = avl_find(pgraph->pEdgeTree, &findEdgeItem)) == NULL) {
304 return -pgraph->iErrno;
305 }
306
307 pEdge = pEdgeItem->pv;
308
310 DGL_EDGE_ID(pEdge)) < 0) {
311 return -pgraph->iErrno;
312 }
313
315 DGL_EDGE_ID(pEdge)) < 0) {
316 return -pgraph->iErrno;
317 }
318
319 /* prioritizer sync
320 */
321 if (pgraph->nOptions & DGL_GO_EdgePrioritize_COST) {
323 DGL_EDGE_COST(pEdge)) < 0) {
324 return -pgraph->iErrno;
325 }
326 }
327 /*
328 */
329 pgraph->cEdge--;
331
332 avl_delete(pgraph->pEdgeTree, pEdgeItem);
334 return 0;
335#endif
336}
337
339{
340#if defined(_DGL_V1)
342 return NULL;
343#else
344 register dglInt32_t top; /* top of table */
345 register dglInt32_t pos; /* current position to compare */
346 register dglInt32_t bot; /* bottom of table */
347 register dglInt32_t *pref;
348 register int cwords; /* size of a edge in words of 32 bit */
349 register dglTreeEdge_s *ptreeEdge;
351 dglInt32_t id;
352
353 pgraph->iErrno = 0;
354 if (pgraph->Flags & DGL_GS_FLAT) {
355 cwords = DGL_EDGE_WSIZE(pgraph->EdgeAttrSize);
356 /*bot = pgraph->iEdgeBuffer / DGL_EDGE_SIZEOF(pgraph->EdgeAttrSize);
357 */
358 bot = pgraph->cEdge;
359 top = 0;
360 pos = 0;
361 pref = (dglInt32_t *)pgraph->pEdgeBuffer;
362
363 /* perform a binary search
364 */
365 while (top != bot) {
366 pos = top + (bot - top) / 2;
367 id = DGL_EDGE_ID(&pref[pos * cwords]);
368 if (id == nEdge) {
369 break;
370 }
371 else if (nEdge < id) {
372 bot = pos;
373 }
374 else if (nEdge > id) {
375 top = pos + 1;
376 }
377 }
378 if (top == bot) {
379 return NULL;
380 }
381 return &pref[pos * cwords];
382 }
383 else {
384 findEdge.nKey = nEdge;
385 ptreeEdge = avl_find(pgraph->pEdgeTree, &findEdge);
386 if (ptreeEdge && ptreeEdge->pv) {
387 return ptreeEdge->pv;
388 }
389 return NULL;
390 }
391#endif
392}
#define NULL
Definition ccmath.h:32
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:46
#define DGL_NS_TAIL
Definition graph.h:60
#define DGL_NS_ALONE
Definition graph.h:61
#define DGL_GO_EdgePrioritize_COST
Definition graph.h:52
#define DGL_ERR_MemoryExhausted
Definition graph.h:254
#define DGL_ERR_BadOnFlatGraph
Definition graph.h:264
#define DGL_NS_HEAD
Definition graph.h:59
#define DGL_ERR_EdgeAlreadyExist
Definition graph.h:273
#define DGL_ERR_NotSupported
Definition graph.h:259
#define DGL_GS_FLAT
Definition graph.h:36
#define DGL_STRONGCONNECT
Definition graph.h:78
#define DGL_ERR_UnexpectedNullPointer
Definition graph.h:268
#define DGL_ERR_EdgeNotFound
Definition graph.h:270
#define DGL_ES_DIRECTED
Definition graph.h:66
int dgl_edge_prioritizer_del(dglGraph_s *pG, dglInt32_t nId, dglInt32_t nPriId)
Definition helpers.c:91
int dgl_edge_prioritizer_add(dglGraph_s *pG, dglInt32_t nId, dglInt32_t nPriId)
Definition helpers.c:132
void dglTreeEdgeCancel(void *pvEdge, void *pvParam)
Definition tree.c:152
dglTreeEdge_s * dglTreeEdgeAdd(void *pavl, dglInt32_t nKey)
Definition tree.c:171
#define avl_find
Definition tree.h:38
#define avl_delete
Definition tree.h:37
long long dglInt64_t
Definition type.h:37
long dglInt32_t
Definition type.h:36
#define DGL_EDGESET_EDGE_PTR
Definition v1-defs.h:149
#define DGL_T_NODEITEM_InEdgesetPTR(p)
Definition v1-defs.h:173
#define DGL_T_NODEITEM_TYPE
Definition v1-defs.h:168
#define DGL_NODE_STATUS
Definition v1-defs.h:126
#define DGL_T_NODEITEM_Add
Definition v1-defs.h:177
#define DGL_EDGESET_ALLOC
Definition v1-defs.h:150
#define DGL_NODE_ID
Definition v1-defs.h:127
#define DGL_EDGE_WSIZE
Definition v1-defs.h:135
#define DGL_NODE_EDGESET_OFFSET
Definition v1-defs.h:129
#define DGL_NODE_ALLOC
Definition v1-defs.h:123
#define DGL_DEL_EDGE_FUNC
Definition v1-defs.h:98
#define DGL_T_NODEITEM_Set_InEdgesetPTR(p, ptr)
Definition v1-defs.h:174
#define DGL_T_NODEITEM_OutEdgesetPTR(p)
Definition v1-defs.h:171
#define DGL_T_NODEITEM_Set_NodePTR(p, ptr)
Definition v1-defs.h:170
#define DGL_EDGE_ALLOC
Definition v1-defs.h:133
#define DGL_EDGE_TAILNODE_OFFSET
Definition v1-defs.h:141
#define DGL_EDGESET_EDGECOUNT
Definition v1-defs.h:148
#define DGL_EDGE_ATTR_PTR
Definition v1-defs.h:139
#define DGL_T_NODEITEM_Set_OutEdgesetPTR(p, ptr)
Definition v1-defs.h:172
#define DGL_EDGE_STATUS(p)
Definition v1-defs.h:136
#define DGL_GET_EDGE_FUNC
Definition v1-defs.h:97
#define DGL_T_NODEITEM_NodePTR(p)
Definition v1-defs.h:169
#define DGL_NODE_ATTR_PTR
Definition v1-defs.h:128
#define DGL_EDGE_ID
Definition v1-defs.h:138
#define DGL_EDGE_HEADNODE_OFFSET
Definition v1-defs.h:140
#define DGL_ADD_EDGE_FUNC
Definition v1-defs.h:96
#define DGL_EDGESET_REALLOC
Definition v1-defs.h:151
#define DGL_EDGE_COST
Definition v1-defs.h:137
#define DGL_DEL_NODE_INEDGE_FUNC
Definition v2-defs.h:92
#define DGL_DEL_NODE_OUTEDGE_FUNC
Definition v2-defs.h:91