updated hash methods. just increasing the size of the hash helps a lot with loading larger networks. perhaps hash could be extended to dynamically size based on network size.

This commit is contained in:
Sam Hatchett
2014-01-31 11:16:07 -05:00
parent 93036690a0
commit caa794447c
6 changed files with 126 additions and 116 deletions

View File

@@ -54,7 +54,7 @@
2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; 2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; };
2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; };
2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; };
226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; settings = {ATTRIBUTES = (Public, ); }; }; 226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@@ -484,6 +484,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.8; MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx; SDKROOT = macosx;
SKIP_INSTALL = YES;
}; };
name = Debug; name = Debug;
}; };
@@ -503,6 +504,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.8; MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx; SDKROOT = macosx;
SKIP_INSTALL = YES;
}; };
name = Release; name = Release;
}; };

View File

@@ -96,9 +96,9 @@ This module calls the following functions that reside in other modules:
writelogo() writelogo()
writereport() writereport()
HASH.C HASH.C
HTcreate() ENHashTablecreate()
HTfind() ENHashTableFind()
HTfree() ENHashTableFree()
The macro ERRCODE(x) is defined in TYPES.H. It says if the current 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 value of the error code variable (errcode) is not fatal (< 100) then
@@ -2802,8 +2802,8 @@ void initpointers()
XLNZ = NULL; XLNZ = NULL;
NZSUB = NULL; NZSUB = NULL;
LNZ = NULL; LNZ = NULL;
Nht = NULL; NodeHashTable = NULL;
Lht = NULL; LinkHashTable = NULL;
initrules(); initrules();
} }
@@ -2821,10 +2821,10 @@ int allocdata()
int errcode = 0; int errcode = 0;
/* Allocate node & link ID hash tables */ /* Allocate node & link ID hash tables */
Nht = HTcreate(); NodeHashTable = ENHashTableCreate();
Lht = HTcreate(); LinkHashTable = ENHashTableCreate();
ERRCODE(MEMCHECK(Nht)); ERRCODE(MEMCHECK(NodeHashTable));
ERRCODE(MEMCHECK(Lht)); ERRCODE(MEMCHECK(LinkHashTable));
/* Allocate memory for network nodes */ /* Allocate memory for network nodes */
/************************************************************* /*************************************************************
@@ -3023,8 +3023,8 @@ void freedata()
freerules(); freerules();
/* Free hash table memory */ /* Free hash table memory */
if (Nht != NULL) HTfree(Nht); if (NodeHashTable != NULL) ENHashTableFree(NodeHashTable);
if (Lht != NULL) HTfree(Lht); if (LinkHashTable != NULL) ENHashTableFree(LinkHashTable);
} }
@@ -3138,7 +3138,7 @@ int findnode(char *id)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
return(HTfind(Nht,id)); return(ENHashTableFind(NodeHashTable,id));
} }
@@ -3151,7 +3151,7 @@ int findlink(char *id)
**---------------------------------------------------------------- **----------------------------------------------------------------
*/ */
{ {
return(HTfind(Lht,id)); return(ENHashTableFind(LinkHashTable,id));
} }

View File

@@ -1,22 +1,22 @@
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
** hash.c ** hash.c
** **
** Implementation of a simple Hash Table for string storage & retrieval ** Implementation of a simple Hash Table for string storage & retrieval
** **
** Written by L. Rossman ** Written by L. Rossman
** Last Updated on 6/19/03 ** Last Updated on 6/19/03
** **
** The hash table data structure (HTable) is defined in "hash.h". ** The hash table data structure (HTable) is defined in "hash.h".
** Interface Functions: ** Interface Functions:
** HTcreate() - creates a hash table ** HTcreate() - creates a hash table
** HTinsert() - inserts a string & its index value into a hash table ** HTinsert() - inserts a string & its index value into a hash table
** HTfind() - retrieves the index value of a string from a table ** HTfind() - retrieves the index value of a string from a table
** HTfree() - frees a hash table ** HTfree() - frees a hash table
** **
********************************************************************* *********************************************************************
** NOTE: This is a modified version of the original HASH.C module. ** NOTE: This is a modified version of the original HASH.C module.
********************************************************************* *********************************************************************
*/ */
#ifndef __APPLE__ #ifndef __APPLE__
#include <malloc.h> #include <malloc.h>
@@ -26,89 +26,97 @@
#include <string.h> #include <string.h>
#include "hash.h" #include "hash.h"
/* Use Fletcher's checksum to compute 2-byte hash of string */ unsigned int _enHash(char *str);
unsigned int hash(char *str) unsigned int _enHash(char *str)
{ {
unsigned int sum1= 0, check1; unsigned int hash = 5381;
unsigned long sum2= 0L; int c;
while( '\0' != *str ) while ((c = *str++)) {
{ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
sum1 += (*str); }
str++; unsigned int retHash = hash % ENHASHTABLEMAXSIZE;
if ( 255 <= sum1 ) sum1 -= 255; return retHash;
sum2 += sum1; }
ENHashTable *ENHashTableCreate()
{
int i;
ENHashTable *ht = (ENHashTable *) calloc(ENHASHTABLEMAXSIZE, sizeof(ENHashTable));
if (ht != NULL) {
for (i=0; i<ENHASHTABLEMAXSIZE; i++) {
ht[i] = NULL;
} }
check1= sum2; }
check1 %= 255; return(ht);
check1= 255 - (sum1+check1) % 255;
sum1= 255 - (sum1+check1) % 255;
return( ( ( check1 << 8 ) | sum1 ) % HTMAXSIZE);
} }
HTtable *HTcreate() int ENHashTableInsert(ENHashTable *ht, char *key, int data)
{ {
int i; unsigned int i = _enHash(key);
HTtable *ht = (HTtable *) calloc(HTMAXSIZE, sizeof(HTtable)); ENHashEntry *entry;
if (ht != NULL) for (i=0; i<HTMAXSIZE; i++) ht[i] = NULL; if ( i >= ENHASHTABLEMAXSIZE ) {
return(ht); return(0);
}
entry = (ENHashEntry *) malloc(sizeof(ENHashEntry));
if (entry == NULL) {
return(0);
}
entry->key = key;
entry->data = data;
entry->next = ht[i];
ht[i] = entry;
return(1);
} }
int HTinsert(HTtable *ht, char *key, int data) int ENHashTableFind(ENHashTable *ht, char *key)
{ {
unsigned int i = hash(key); unsigned int i = _enHash(key);
struct HTentry *entry; ENHashEntry *entry;
if ( i >= HTMAXSIZE ) return(0); if ( i >= ENHASHTABLEMAXSIZE ) {
entry = (struct HTentry *) malloc(sizeof(struct HTentry)); return(NOTFOUND);
if (entry == NULL) return(0); }
entry->key = key; entry = ht[i];
entry->data = data; while (entry != NULL)
entry->next = ht[i]; {
ht[i] = entry; if ( strcmp(entry->key,key) == 0 ) {
return(1); return(entry->data);
}
entry = entry->next;
}
return(NOTFOUND);
} }
int HTfind(HTtable *ht, char *key) char *ENHashTableFindKey(ENHashTable *ht, char *key)
{ {
unsigned int i = hash(key); unsigned int i = _enHash(key);
struct HTentry *entry; ENHashEntry *entry;
if ( i >= HTMAXSIZE ) return(NOTFOUND); if ( i >= ENHASHTABLEMAXSIZE ) {
entry = ht[i]; return(NULL);
while (entry != NULL) }
{ entry = ht[i];
if ( strcmp(entry->key,key) == 0 ) return(entry->data); while (entry != NULL)
entry = entry->next; {
} if ( strcmp(entry->key,key) == 0 ) {
return(NOTFOUND); return(entry->key);
}
entry = entry->next;
}
return(NULL);
} }
char *HTfindKey(HTtable *ht, char *key) void ENHashTableFree(ENHashTable *ht)
{ {
unsigned int i = hash(key); ENHashEntry *entry, *nextentry;
struct HTentry *entry; int i;
if ( i >= HTMAXSIZE ) return(NULL); for (i=0; i<ENHASHTABLEMAXSIZE; i++)
entry = ht[i]; {
while (entry != NULL) entry = ht[i];
{ while (entry != NULL)
if ( strcmp(entry->key,key) == 0 ) return(entry->key); {
entry = entry->next; nextentry = entry->next;
} free(entry);
return(NULL); entry = nextentry;
} }
}
void HTfree(HTtable *ht) free(ht);
{
struct HTentry *entry,
*nextentry;
int i;
for (i=0; i<HTMAXSIZE; i++)
{
entry = ht[i];
while (entry != NULL)
{
nextentry = entry->next;
free(entry);
entry = nextentry;
}
}
free(ht);
} }

View File

@@ -7,22 +7,22 @@
#ifndef HASH_H #ifndef HASH_H
#define HASH_H #define HASH_H
#define HTMAXSIZE 1999 #define ENHASHTABLEMAXSIZE 128000
#define NOTFOUND 0 #define NOTFOUND 0
struct HTentry typedef struct HTentryStruct
{ {
char *key; char *key;
int data; int data;
struct HTentry *next; struct HTentryStruct *next;
}; } ENHashEntry;
typedef struct HTentry *HTtable; typedef ENHashEntry *ENHashTable;
HTtable *HTcreate(void); ENHashTable *ENHashTableCreate(void);
int HTinsert(HTtable *, char *, int); int ENHashTableInsert(ENHashTable *, char *, int);
int HTfind(HTtable *, char *); int ENHashTableFind(ENHashTable *, char *);
char *HTfindKey(HTtable *, char *); char *ENHashTableFindKey(ENHashTable *, char *);
void HTfree(HTtable *); void ENHashTableFree(ENHashTable *);
#endif #endif

View File

@@ -423,7 +423,7 @@ int addnodeID(int n, char *id)
{ {
if (findnode(id)) return(0); /* see EPANET.C */ if (findnode(id)) return(0); /* see EPANET.C */
strncpy(Node[n].ID, id, MAXID); strncpy(Node[n].ID, id, MAXID);
HTinsert(Nht, Node[n].ID, n); /* see HASH.C */ ENHashTableInsert(NodeHashTable, Node[n].ID, n); /* see HASH.C */
return(1); return(1);
} }
@@ -440,7 +440,7 @@ int addlinkID(int n, char *id)
{ {
if (findlink(id)) return(0); /* see EPANET.C */ if (findlink(id)) return(0); /* see EPANET.C */
strncpy(Link[n].ID, id, MAXID); strncpy(Link[n].ID, id, MAXID);
HTinsert(Lht, Link[n].ID, n); /* see HASH.C */ ENHashTableInsert(LinkHashTable, Link[n].ID, n); /* see HASH.C */
return(1); return(1);
} }

View File

@@ -169,7 +169,7 @@ EXTERN Stank *Tank; /* Tank data */
EXTERN Spump *Pump; /* Pump data */ EXTERN Spump *Pump; /* Pump data */
EXTERN Svalve *Valve; /* Valve data */ EXTERN Svalve *Valve; /* Valve data */
EXTERN Scontrol *Control; /* Control data */ EXTERN Scontrol *Control; /* Control data */
EXTERN HTtable *Nht, *Lht; /* Hash tables for ID labels */ EXTERN ENHashTable *NodeHashTable, *LinkHashTable; /* Hash tables for ID labels */
EXTERN Padjlist *Adjlist; /* Node adjacency lists */ EXTERN Padjlist *Adjlist; /* Node adjacency lists */
EXTERN double _relativeError; EXTERN double _relativeError;
EXTERN int _iterations; /* Info about hydraulic solution */ EXTERN int _iterations; /* Info about hydraulic solution */