Merge pull request #754 from lbutler/getclosedlink-remove-recursion
Remove recursion in getclosedlink
This commit is contained in:
@@ -47,4 +47,5 @@ This document describes the changes and updates that have been made in version 2
|
||||
- `EN_STATUS_REPORT` can now be used with `EN_getoption` and `EN_setoption` to get or set the type of status report that EPANET will generate (`EN_NO_REPORT`, `EN_NORMAL_REPORT` or `EN_FULL_REPORT`).
|
||||
- A possible parser error that could result in a Trace Node ID in an input file not being recognized was fixed.
|
||||
- Additional API functions for enabling/disabling controls and rules were added.
|
||||
- Updated the internal function `getclosedlink` in report.c to use a loop instead of recursion to prevent a stack overflow during the analysis of very large disconnections.
|
||||
|
||||
50
src/report.c
50
src/report.c
@@ -45,7 +45,7 @@ static void writeenergy(Project *);
|
||||
static int writeresults(Project *);
|
||||
static int disconnected(Project *);
|
||||
static void marknodes(Project *, int, int *, char *);
|
||||
static void getclosedlink(Project *, int, char *);
|
||||
static void getclosedlink(Project *, int, char *, int *);
|
||||
static void writelimits(Project *, int, int);
|
||||
static int checklimits(Report *, double *, int, int);
|
||||
static char *fillstr(char *, char, int);
|
||||
@@ -1287,7 +1287,7 @@ int disconnected(Project *pr)
|
||||
clocktime(rpt->Atime, time->Htime));
|
||||
writeline(pr, pr->Msg);
|
||||
}
|
||||
getclosedlink(pr, j, marked);
|
||||
getclosedlink(pr, j, marked, nodelist);
|
||||
}
|
||||
|
||||
// Free allocated memory
|
||||
@@ -1350,11 +1350,12 @@ void marknodes(Project *pr, int m, int *nodelist, char *marked)
|
||||
}
|
||||
}
|
||||
|
||||
void getclosedlink(Project *pr, int i, char *marked)
|
||||
void getclosedlink(Project *pr, int i, char *marked, int *stack)
|
||||
/*
|
||||
**----------------------------------------------------------------
|
||||
** Input: i = junction index
|
||||
** marked[] = marks nodes already examined
|
||||
** stack[] = stack to hold nodes to examine
|
||||
** Output: None.
|
||||
** Purpose: Determines if a closed link connects to junction i.
|
||||
**----------------------------------------------------------------
|
||||
@@ -1365,20 +1366,41 @@ void getclosedlink(Project *pr, int i, char *marked)
|
||||
int j, k;
|
||||
Padjlist alink;
|
||||
|
||||
int top = 0;
|
||||
|
||||
// Mark the current junction as examined and push onto stack
|
||||
marked[i] = 2;
|
||||
for (alink = net->Adjlist[i]; alink != NULL; alink = alink->next)
|
||||
{
|
||||
k = alink->link;
|
||||
j = alink->node;
|
||||
if (marked[j] == 2) continue;
|
||||
if (marked[j] == 1)
|
||||
{
|
||||
sprintf(pr->Msg, WARN03c, net->Link[k].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return;
|
||||
stack[top] = i;
|
||||
|
||||
while (top >= 0) {
|
||||
i = stack[top--];
|
||||
alink = net->Adjlist[i];
|
||||
|
||||
// Iterate through each link adjacent to the current node
|
||||
while (alink != NULL) {
|
||||
k = alink->link;
|
||||
j = alink->node;
|
||||
|
||||
// Skip nodes that have already been examined
|
||||
if (marked[j] == 2) {
|
||||
alink = alink->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a closed link is found, return and display a warning message
|
||||
if (marked[j] == 1) {
|
||||
sprintf(pr->Msg, WARN03c, net->Link[k].ID);
|
||||
writeline(pr, pr->Msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark the node as examined and push it onto the stack
|
||||
marked[j] = 2;
|
||||
stack[++top] = j;
|
||||
alink = alink->next;
|
||||
}
|
||||
else getclosedlink(pr, j, marked);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void writelimits(Project *pr, int j1, int j2)
|
||||
|
||||
Reference in New Issue
Block a user