Skip to content

Commit

Permalink
Reduce reallocs in EN_addnode & EN_addlink
Browse files Browse the repository at this point in the history
  • Loading branch information
LRossman committed Nov 24, 2023
1 parent 5fd17af commit dac67d4
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 26 deletions.
42 changes: 26 additions & 16 deletions src/epanet.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#define snprintf _snprintf
#endif

const int DELTA_CAPACITY = 50;

/********************************************************************
Project Functions
Expand Down Expand Up @@ -1858,15 +1860,19 @@ int DLLEXPORT EN_addnode(EN_Project p, const char *id, int nodeType, int *index)
if (nodeType < EN_JUNCTION || nodeType > EN_TANK) return 251;

// Grow node-related arrays to accomodate the new node
size = (net->Nnodes + 2) * sizeof(Snode);
net->Node = (Snode *)realloc(net->Node, size);
size = (net->Nnodes + 2) * sizeof(double);
hyd->NodeDemand = (double *)realloc(hyd->NodeDemand, size);
qual->NodeQual = (double *)realloc(qual->NodeQual, size);
hyd->NodeHead = (double *)realloc(hyd->NodeHead, size);
hyd->DemandFlow = (double *)realloc(hyd->DemandFlow, size);
hyd->EmitterFlow = (double *)realloc(hyd->EmitterFlow, size);

if (net->Nnodes == net->NodeCapacity)
{
net->NodeCapacity += DELTA_CAPACITY;
size = (net->NodeCapacity + 1) * sizeof(Snode);
net->Node = (Snode *)realloc(net->Node, size);
size = (net->NodeCapacity + 1) * sizeof(double);
hyd->NodeDemand = (double *)realloc(hyd->NodeDemand, size);
qual->NodeQual = (double *)realloc(qual->NodeQual, size);
hyd->NodeHead = (double *)realloc(hyd->NodeHead, size);
hyd->DemandFlow = (double *)realloc(hyd->DemandFlow, size);
hyd->EmitterFlow = (double *)realloc(hyd->EmitterFlow, size);
}

// Actions taken when a new Junction is added
if (nodeType == EN_JUNCTION)
{
Expand Down Expand Up @@ -3247,16 +3253,20 @@ int DLLEXPORT EN_addlink(EN_Project p, const char *id, int linkType,
}

// Grow link-related arrays to accomodate the new link
if (net->Nlinks == net->LinkCapacity)
{
net->LinkCapacity += DELTA_CAPACITY;
size = (net->LinkCapacity + 1) * sizeof(Slink);
net->Link = (Slink *)realloc(net->Link, size);
size = (net->LinkCapacity + 1) * sizeof(double);
hyd->LinkFlow = (double *)realloc(hyd->LinkFlow, size);
hyd->LinkSetting = (double *)realloc(hyd->LinkSetting, size);
size = (net->LinkCapacity + 1) * sizeof(StatusType);
hyd->LinkStatus = (StatusType *)realloc(hyd->LinkStatus, size);
}
net->Nlinks++;
p->parser.MaxLinks = net->Nlinks;
n = net->Nlinks;
size = (n + 1) * sizeof(Slink);
net->Link = (Slink *)realloc(net->Link, size);
size = (n + 1) * sizeof(double);
hyd->LinkFlow = (double *)realloc(hyd->LinkFlow, size);
hyd->LinkSetting = (double *)realloc(hyd->LinkSetting, size);
size = (n + 1) * sizeof(StatusType);
hyd->LinkStatus = (StatusType *)realloc(hyd->LinkStatus, size);

// Set properties for the new link
link = &net->Link[n];
Expand Down
17 changes: 12 additions & 5 deletions src/project.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ void initpointers(Project *pr)
nw->Nrules = 0;
nw->Npats = 0;
nw->Ncurves = 0;

nw->NodeCapacity = 0;
nw->LinkCapacity = 0;

pr->hydraul.NodeDemand = NULL;
pr->hydraul.NodeHead = NULL;
Expand Down Expand Up @@ -387,6 +390,7 @@ int allocdata(Project *pr)
//*************************************************************
if (!errcode)
{
pr->network.NodeCapacity = pr->parser.MaxNodes;
n = pr->parser.MaxNodes + 1;
pr->network.Node = (Snode *)calloc(n, sizeof(Snode));
pr->hydraul.NodeDemand = (double *)calloc(n, sizeof(double));
Expand All @@ -405,6 +409,7 @@ int allocdata(Project *pr)
// Allocate memory for network links
if (!errcode)
{
pr->network.LinkCapacity = pr->parser.MaxLinks;
n = pr->parser.MaxLinks + 1;
pr->network.Link = (Slink *)calloc(n, sizeof(Slink));
pr->hydraul.LinkFlow = (double *)calloc(n, sizeof(double));
Expand Down Expand Up @@ -489,6 +494,7 @@ void freedata(Project *pr)
free(pr->network.Node[j].Comment);
}
free(pr->network.Node);
pr->network.NodeCapacity = 0;
}

// Free memory for link data
Expand All @@ -499,14 +505,15 @@ void freedata(Project *pr)
freelinkvertices(&pr->network.Link[j]);
free(pr->network.Link[j].Comment);
}
free(pr->network.Link);
pr->network.LinkCapacity = 0;
}
free(pr->network.Link);

// Free memory for other network objects
free(pr->network.Tank);
free(pr->network.Pump);
free(pr->network.Valve);
free(pr->network.Control);
if (pr->network.Tank != NULL) free(pr->network.Tank);
if (pr->network.Pump != NULL) free(pr->network.Pump);
if (pr->network.Valve != NULL) free(pr->network.Valve);
if (pr->network.Control != NULL) free(pr->network.Control);

// Free memory for time patterns
if (pr->network.Pattern != NULL)
Expand Down
5 changes: 4 additions & 1 deletion src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,10 @@ typedef struct {
Ncontrols, // Number of simple controls
Nrules, // Number of control rules
Npats, // Number of time patterns
Ncurves; // Number of data curves
Ncurves, // Number of data curves

NodeCapacity,
LinkCapacity;

Snode *Node; // Node array
Slink *Link; // Link array
Expand Down
5 changes: 1 addition & 4 deletions src/validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ void reindextanks(Project *pr)
Parser *parser = &pr->parser;
Quality *qual = &pr->quality;
Scontrol *control;
int i, j, ndiff, n1, n2, size;
int i, j, ndiff, n1, n2;

// ndiff = # unused entries in Node array before first tank node
ndiff = parser->MaxJuncs - net->Njuncs;
Expand Down Expand Up @@ -395,11 +395,8 @@ void reindextanks(Project *pr)
if (qual->TraceNode == n1) qual->TraceNode = n2;
}

// Reallocate the Node array (shouldn't fail as new size < old size)
parser->MaxJuncs = net->Njuncs;
parser->MaxNodes = net->Njuncs + net->Ntanks;
size = (net->Nnodes + 2) * sizeof(Snode);
net->Node = (Snode *)realloc(net->Node, size);
}
}

0 comments on commit dac67d4

Please sign in to comment.