Merge pull request #754 from lbutler/getclosedlink-remove-recursion

Remove recursion in getclosedlink
This commit is contained in:
Lew Rossman
2023-09-15 11:01:39 -04:00
committed by GitHub
2 changed files with 37 additions and 14 deletions

View File

@@ -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.

View File

@@ -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)