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`).
|
- `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.
|
- 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.
|
- 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.
|
||||||
|
|
||||||
40
src/report.c
40
src/report.c
@@ -45,7 +45,7 @@ static void writeenergy(Project *);
|
|||||||
static int writeresults(Project *);
|
static int writeresults(Project *);
|
||||||
static int disconnected(Project *);
|
static int disconnected(Project *);
|
||||||
static void marknodes(Project *, int, int *, char *);
|
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 void writelimits(Project *, int, int);
|
||||||
static int checklimits(Report *, double *, int, int);
|
static int checklimits(Report *, double *, int, int);
|
||||||
static char *fillstr(char *, char, int);
|
static char *fillstr(char *, char, int);
|
||||||
@@ -1287,7 +1287,7 @@ int disconnected(Project *pr)
|
|||||||
clocktime(rpt->Atime, time->Htime));
|
clocktime(rpt->Atime, time->Htime));
|
||||||
writeline(pr, pr->Msg);
|
writeline(pr, pr->Msg);
|
||||||
}
|
}
|
||||||
getclosedlink(pr, j, marked);
|
getclosedlink(pr, j, marked, nodelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free allocated memory
|
// 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
|
** Input: i = junction index
|
||||||
** marked[] = marks nodes already examined
|
** marked[] = marks nodes already examined
|
||||||
|
** stack[] = stack to hold nodes to examine
|
||||||
** Output: None.
|
** Output: None.
|
||||||
** Purpose: Determines if a closed link connects to junction i.
|
** 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;
|
int j, k;
|
||||||
Padjlist alink;
|
Padjlist alink;
|
||||||
|
|
||||||
|
int top = 0;
|
||||||
|
|
||||||
|
// Mark the current junction as examined and push onto stack
|
||||||
marked[i] = 2;
|
marked[i] = 2;
|
||||||
for (alink = net->Adjlist[i]; alink != NULL; alink = alink->next)
|
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;
|
k = alink->link;
|
||||||
j = alink->node;
|
j = alink->node;
|
||||||
if (marked[j] == 2) continue;
|
|
||||||
if (marked[j] == 1)
|
// 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);
|
sprintf(pr->Msg, WARN03c, net->Link[k].ID);
|
||||||
writeline(pr, pr->Msg);
|
writeline(pr, pr->Msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else getclosedlink(pr, j, marked);
|
|
||||||
|
// Mark the node as examined and push it onto the stack
|
||||||
|
marked[j] = 2;
|
||||||
|
stack[++top] = j;
|
||||||
|
alink = alink->next;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void writelimits(Project *pr, int j1, int j2)
|
void writelimits(Project *pr, int j1, int j2)
|
||||||
|
|||||||
Reference in New Issue
Block a user