Fixed bug in hash.c
A bug in the delete function in hash.c was preventing the unit test of the new set ID API functions from running properly. In fixing this bug the entire hash table code was refactored to make it look more like the mempool service routines. Also the need to copy the string passed into the table's insert function was eliminated.
This commit is contained in:
67
src/epanet.c
67
src/epanet.c
@@ -89,9 +89,9 @@ This module calls the following functions that reside in other modules:
|
||||
writelogo()
|
||||
writereport()
|
||||
HASH.C
|
||||
ENHashTablecreate()
|
||||
ENHashTableFind()
|
||||
ENHashTableFree()
|
||||
hashtable_create()
|
||||
hashtable_find()
|
||||
hashtable_free()
|
||||
|
||||
The macro ERRCODE(x) is defined in TYPES.H. It says if the current
|
||||
value of the error code variable (errcode) is not fatal (< 100) then
|
||||
@@ -855,9 +855,8 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph)
|
||||
writetime(p, FMT105);
|
||||
}
|
||||
freedata(p);
|
||||
|
||||
|
||||
out = &p->out_files;
|
||||
|
||||
if (out->TmpOutFile != out->OutFile) {
|
||||
if (out->TmpOutFile != NULL) {
|
||||
fclose(out->TmpOutFile);
|
||||
@@ -887,7 +886,7 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph)
|
||||
remove(out->HydFname);
|
||||
if (out->Outflag == SCRATCH)
|
||||
remove(out->OutFname);
|
||||
|
||||
|
||||
p->Openflag = FALSE;
|
||||
p->hydraulics.OpenHflag = FALSE;
|
||||
p->save_options.SaveHflag = FALSE;
|
||||
@@ -2916,15 +2915,15 @@ int DLLEXPORT EN_setnodeid(EN_ProjectHandle ph, int index, char *newid)
|
||||
if (strcspn(newid, " ;") < n) return set_error(p->error_handle, 209);
|
||||
|
||||
// Check if another node with same name exists
|
||||
if (ENHashTableFind(net->NodeHashTable, newid) > 0)
|
||||
if (hashtable_find(net->NodeHashTable, newid) > 0)
|
||||
{
|
||||
return set_error(p->error_handle, 215);
|
||||
}
|
||||
|
||||
// Replace the existing node ID with the new value
|
||||
ENHashTableDelete(net->NodeHashTable, net->Node[index].ID);
|
||||
hashtable_delete(net->NodeHashTable, net->Node[index].ID);
|
||||
strncpy(net->Node[index].ID, newid, MAXID);
|
||||
ENHashTableInsert(net->NodeHashTable, net->Node[index].ID, index);
|
||||
hashtable_insert(net->NodeHashTable, net->Node[index].ID, index);
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -3210,15 +3209,15 @@ int DLLEXPORT EN_setlinkid(EN_ProjectHandle ph, int index, char *newid)
|
||||
if (strcspn(newid, " ;") < n) return set_error(p->error_handle, 211);
|
||||
|
||||
// Check if another link with same name exists
|
||||
if (ENHashTableFind(net->LinkHashTable, newid) > 0)
|
||||
if (hashtable_find(net->LinkHashTable, newid) > 0)
|
||||
{
|
||||
return set_error(p->error_handle, 215);
|
||||
}
|
||||
|
||||
// Replace the existing link ID with the new value
|
||||
ENHashTableDelete(net->LinkHashTable, net->Link[index].ID);
|
||||
hashtable_delete(net->LinkHashTable, net->Link[index].ID);
|
||||
strncpy(net->Link[index].ID, newid, MAXID);
|
||||
ENHashTableInsert(net->LinkHashTable, net->Link[index].ID, index);
|
||||
hashtable_insert(net->LinkHashTable, net->Link[index].ID, index);
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -4325,8 +4324,8 @@ int allocdata(EN_Project *p)
|
||||
parser_data_t *par;
|
||||
|
||||
/* Allocate node & link ID hash tables */
|
||||
p->network.NodeHashTable = ENHashTableCreate();
|
||||
p->network.LinkHashTable = ENHashTableCreate();
|
||||
p->network.NodeHashTable = hashtable_create();
|
||||
p->network.LinkHashTable = hashtable_create();
|
||||
ERRCODE(MEMCHECK(p->network.NodeHashTable));
|
||||
ERRCODE(MEMCHECK(p->network.LinkHashTable));
|
||||
|
||||
@@ -4498,14 +4497,14 @@ void freedata(EN_Project *p)
|
||||
}
|
||||
free(net->Node);
|
||||
}
|
||||
|
||||
|
||||
/* Free memory for other network objects */
|
||||
free(net->Link);
|
||||
free(net->Tank);
|
||||
free(net->Pump);
|
||||
free(net->Valve);
|
||||
free(net->Control);
|
||||
|
||||
|
||||
/* Free memory for time patterns */
|
||||
if (net->Pattern != NULL) {
|
||||
for (j = 0; j <= par->MaxPats; j++)
|
||||
@@ -4521,20 +4520,19 @@ void freedata(EN_Project *p)
|
||||
}
|
||||
free(net->Curve);
|
||||
}
|
||||
|
||||
|
||||
/* Free memory for node coordinates */
|
||||
if (p->parser.Coordflag == TRUE) {
|
||||
free(net->Coord);
|
||||
}
|
||||
|
||||
|
||||
/* Free memory for rule base (see RULES.C) */
|
||||
freerules(p);
|
||||
|
||||
|
||||
/* Free hash table memory */
|
||||
if (net->NodeHashTable != NULL)
|
||||
ENHashTableFree(net->NodeHashTable);
|
||||
if (net->LinkHashTable != NULL)
|
||||
ENHashTableFree(net->LinkHashTable);
|
||||
if (net->NodeHashTable != NULL) hashtable_free(net->NodeHashTable);
|
||||
|
||||
if (net->LinkHashTable != NULL) hashtable_free(net->LinkHashTable);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4637,7 +4635,7 @@ int findnode(EN_Network *n, char *id)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
return (ENHashTableFind(n->NodeHashTable, id));
|
||||
return (hashtable_find(n->NodeHashTable, id));
|
||||
}
|
||||
|
||||
int findlink(EN_Network *n, char *id)
|
||||
@@ -4649,7 +4647,7 @@ int findlink(EN_Network *n, char *id)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
return (ENHashTableFind(n->LinkHashTable, id));
|
||||
return (hashtable_find(n->LinkHashTable, id));
|
||||
}
|
||||
|
||||
int findtank(EN_Network *n, int index)
|
||||
@@ -5055,7 +5053,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
|
||||
|
||||
// shift rest of Node array
|
||||
for (index = net->Nnodes; index >= net->Njuncs; index--) {
|
||||
ENHashTableUpdate(net->NodeHashTable, net->Node[index].ID, index + 1);
|
||||
hashtable_update(net->NodeHashTable, net->Node[index].ID, index + 1);
|
||||
net->Node[index + 1] = net->Node[index];
|
||||
net->Coord[index + 1] = net->Coord[index];
|
||||
}
|
||||
@@ -5171,7 +5169,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
|
||||
coord->Y = 0;
|
||||
|
||||
/* Insert new node into hash table */
|
||||
ENHashTableInsert(net->NodeHashTable, node->ID, nIdx); /* see HASH.C */
|
||||
hashtable_insert(net->NodeHashTable, node->ID, nIdx); /* see HASH.C */
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -5194,8 +5192,8 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch
|
||||
return set_error(p->error_handle, 215);
|
||||
|
||||
/* Lookup the from and to nodes */
|
||||
N1 = ENHashTableFind(net->NodeHashTable, fromNode);
|
||||
N2 = ENHashTableFind(net->NodeHashTable, toNode);
|
||||
N1 = hashtable_find(net->NodeHashTable, fromNode);
|
||||
N2 = hashtable_find(net->NodeHashTable, toNode);
|
||||
|
||||
if (N1 == 0 || N2 == 0) {
|
||||
return set_error(p->error_handle, 203);
|
||||
@@ -5277,7 +5275,7 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch
|
||||
link->Rpt = 0;
|
||||
strcpy(link->Comment, "");
|
||||
|
||||
ENHashTableInsert(net->LinkHashTable, link->ID, n);
|
||||
hashtable_insert(net->LinkHashTable, link->ID, n);
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -5300,15 +5298,14 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) {
|
||||
link = &net->Link[index];
|
||||
|
||||
// remove from hash table
|
||||
ENHashTableDelete(net->LinkHashTable, link->ID);
|
||||
ENHashTableFind(net->LinkHashTable, link->ID);
|
||||
hashtable_delete(net->LinkHashTable, link->ID);
|
||||
|
||||
// shift link and pump arrays to re-sort link indices
|
||||
net->Nlinks--;
|
||||
for (i = index; i <= net->Nlinks - 1; i++) {
|
||||
net->Link[i] = net->Link[i + 1];
|
||||
// update hashtable
|
||||
ENHashTableUpdate(net->LinkHashTable, net->Link[i].ID, i);
|
||||
hashtable_update(net->LinkHashTable, net->Link[i].ID, i);
|
||||
}
|
||||
for (i = 1; i <= net->Npumps; i++) {
|
||||
if (net->Pump[i].Link > index) {
|
||||
@@ -5361,14 +5358,14 @@ int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) {
|
||||
// TODO: check for existing controls/rules that reference this node?
|
||||
|
||||
// remove from hash table
|
||||
ENHashTableDelete(net->NodeHashTable, net->Node[index].ID);
|
||||
hashtable_delete(net->NodeHashTable, net->Node[index].ID);
|
||||
|
||||
// shift node and coord array to remove node
|
||||
for (i = index; i <= net->Nnodes - 1; i++) {
|
||||
net->Node[i] = net->Node[i + 1];
|
||||
net->Coord[i] = net->Coord[i + 1];
|
||||
// update hashtable
|
||||
ENHashTableUpdate(net->NodeHashTable, net->Node[i].ID, i);
|
||||
hashtable_update(net->NodeHashTable, net->Node[i].ID, i);
|
||||
}
|
||||
|
||||
// update tank array
|
||||
|
||||
Reference in New Issue
Block a user