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

@@ -26,40 +26,41 @@
#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++;
if ( 255 <= sum1 ) sum1 -= 255;
sum2 += sum1;
} }
check1= sum2; unsigned int retHash = hash % ENHASHTABLEMAXSIZE;
check1 %= 255; return retHash;
check1= 255 - (sum1+check1) % 255;
sum1= 255 - (sum1+check1) % 255;
return( ( ( check1 << 8 ) | sum1 ) % HTMAXSIZE);
} }
HTtable *HTcreate() ENHashTable *ENHashTableCreate()
{ {
int i; int i;
HTtable *ht = (HTtable *) calloc(HTMAXSIZE, sizeof(HTtable)); ENHashTable *ht = (ENHashTable *) calloc(ENHASHTABLEMAXSIZE, sizeof(ENHashTable));
if (ht != NULL) for (i=0; i<HTMAXSIZE; i++) ht[i] = NULL; if (ht != NULL) {
for (i=0; i<ENHASHTABLEMAXSIZE; i++) {
ht[i] = NULL;
}
}
return(ht); return(ht);
} }
int HTinsert(HTtable *ht, char *key, int data) int ENHashTableInsert(ENHashTable *ht, char *key, int data)
{ {
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(0);
if (entry == NULL) return(0); }
entry = (ENHashEntry *) malloc(sizeof(ENHashEntry));
if (entry == NULL) {
return(0);
}
entry->key = key; entry->key = key;
entry->data = data; entry->data = data;
entry->next = ht[i]; entry->next = ht[i];
@@ -67,40 +68,47 @@ int HTinsert(HTtable *ht, char *key, int data)
return(1); return(1);
} }
int HTfind(HTtable *ht, char *key) 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(NOTFOUND); if ( i >= ENHASHTABLEMAXSIZE ) {
return(NOTFOUND);
}
entry = ht[i]; entry = ht[i];
while (entry != NULL) while (entry != NULL)
{ {
if ( strcmp(entry->key,key) == 0 ) return(entry->data); if ( strcmp(entry->key,key) == 0 ) {
return(entry->data);
}
entry = entry->next; entry = entry->next;
} }
return(NOTFOUND); return(NOTFOUND);
} }
char *HTfindKey(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(NULL); if ( i >= ENHASHTABLEMAXSIZE ) {
return(NULL);
}
entry = ht[i]; entry = ht[i];
while (entry != NULL) while (entry != NULL)
{ {
if ( strcmp(entry->key,key) == 0 ) return(entry->key); if ( strcmp(entry->key,key) == 0 ) {
return(entry->key);
}
entry = entry->next; entry = entry->next;
} }
return(NULL); return(NULL);
} }
void HTfree(HTtable *ht) void ENHashTableFree(ENHashTable *ht)
{ {
struct HTentry *entry, ENHashEntry *entry, *nextentry;
*nextentry;
int i; int i;
for (i=0; i<HTMAXSIZE; i++) for (i=0; i<ENHASHTABLEMAXSIZE; i++)
{ {
entry = ht[i]; entry = ht[i];
while (entry != NULL) while (entry != NULL)

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 */