diff options
Diffstat (limited to 'src/old')
-rw-r--r-- | src/old/arraylist.cpp | 100 | ||||
-rw-r--r-- | src/old/arraylist.h | 80 | ||||
-rw-r--r-- | src/old/hashfunction.cpp | 10 | ||||
-rw-r--r-- | src/old/hashfunction.h | 48 | ||||
-rw-r--r-- | src/old/hashfunctioncasestring.cpp | 39 | ||||
-rw-r--r-- | src/old/hashfunctioncasestring.h | 28 | ||||
-rw-r--r-- | src/old/hashfunctionint.cpp | 20 | ||||
-rw-r--r-- | src/old/hashfunctionint.h | 26 | ||||
-rw-r--r-- | src/old/hashfunctionstring.cpp | 51 | ||||
-rw-r--r-- | src/old/hashfunctionstring.h | 27 | ||||
-rw-r--r-- | src/old/hashtable.cpp | 424 | ||||
-rw-r--r-- | src/old/hashtable.h | 308 |
12 files changed, 0 insertions, 1161 deletions
diff --git a/src/old/arraylist.cpp b/src/old/arraylist.cpp deleted file mode 100644 index ef21426..0000000 --- a/src/old/arraylist.cpp +++ /dev/null | |||
@@ -1,100 +0,0 @@ | |||
1 | #include "arraylist.h" | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | ArrayList::ArrayList( int initSize, int growByFactor ) | ||
6 | { | ||
7 | apData = new void *[initSize]; | ||
8 | nSize = 0; | ||
9 | nCapacity = initSize; | ||
10 | nGrowByFactor = growByFactor; | ||
11 | } | ||
12 | |||
13 | ArrayList::~ArrayList( ) | ||
14 | { | ||
15 | delete[] apData; | ||
16 | } | ||
17 | |||
18 | void *ArrayList::getAt( int index ) | ||
19 | { | ||
20 | if( index < 0 || index > nSize ) | ||
21 | return NULL; | ||
22 | |||
23 | return apData[index]; | ||
24 | } | ||
25 | |||
26 | void ArrayList::append( void *data ) | ||
27 | { | ||
28 | insertBefore( data, nSize ); | ||
29 | } | ||
30 | |||
31 | void ArrayList::insertBefore( void *data, int pos ) | ||
32 | { | ||
33 | if( pos < 0 || pos > nSize ) | ||
34 | return; | ||
35 | |||
36 | checkResize(); | ||
37 | memmove( &apData[pos+1], &apData[pos], (nSize-pos)*sizeof(void*) ); | ||
38 | apData[pos] = data; | ||
39 | nSize++; | ||
40 | } | ||
41 | |||
42 | int ArrayList::getSize( ) | ||
43 | { | ||
44 | return nSize; | ||
45 | } | ||
46 | |||
47 | bool ArrayList::isEmpty( ) | ||
48 | { | ||
49 | return nSize==0; | ||
50 | } | ||
51 | |||
52 | void ArrayList::deleteAt( int index ) | ||
53 | { | ||
54 | if( index < 0 || index >= nSize ) | ||
55 | return; | ||
56 | |||
57 | memmove( &apData[index], &apData[index+1], (nSize-index-1)*sizeof(void *) ); | ||
58 | nSize--; | ||
59 | } | ||
60 | |||
61 | void ArrayList::empty() | ||
62 | { | ||
63 | // Probably the easiest as far as things go. | ||
64 | nSize = 0; | ||
65 | } | ||
66 | |||
67 | void ArrayList::resizeTo( int newSize ) | ||
68 | { | ||
69 | void **apNew = new void *[newSize]; | ||
70 | memmove( apNew, apData, nSize*sizeof(void *) ); | ||
71 | nCapacity = newSize; | ||
72 | delete[] apData; | ||
73 | apData = apNew; | ||
74 | } | ||
75 | |||
76 | void ArrayList::checkResize() | ||
77 | { | ||
78 | if( nSize >= nCapacity ) | ||
79 | { | ||
80 | resizeTo( nCapacity + nGrowByFactor ); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | void ArrayList::setSize( int newSize ) | ||
85 | { | ||
86 | if( newSize < 0 ) | ||
87 | return; | ||
88 | |||
89 | nSize = newSize; | ||
90 | checkResize(); | ||
91 | } | ||
92 | |||
93 | void ArrayList::setAt( int index, void *data ) | ||
94 | { | ||
95 | if( index < 0 || index >= nSize ) | ||
96 | return; | ||
97 | |||
98 | apData[index] = data; | ||
99 | } | ||
100 | |||
diff --git a/src/old/arraylist.h b/src/old/arraylist.h deleted file mode 100644 index 0fda34a..0000000 --- a/src/old/arraylist.h +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /** \file arraylist.h | ||
2 | * Describes the ArrayList class. | ||
3 | *@author Mike Buland | ||
4 | */ | ||
5 | #ifndef ARRAY_LIST_H | ||
6 | #define ARRAY_LIST_H | ||
7 | |||
8 | #include "list.h" | ||
9 | |||
10 | /** A simple list which uses an array. This is a great choice if you won't do | ||
11 | * a lot of adding and deleting and need a fast random access list. Otherwise | ||
12 | * use the LinkedList. | ||
13 | *@author Mike Buland | ||
14 | */ | ||
15 | class ArrayList : public List | ||
16 | { | ||
17 | public: | ||
18 | /** Creates an arraylist with some pre-defined specs spelled out. | ||
19 | *@param initSize the inital number of elements to allocate. | ||
20 | *@param growByFactor How much to increase the size of the array by | ||
21 | * each time we run out of room. | ||
22 | */ | ||
23 | ArrayList( int initSize=100, int growByFactor=10 ); | ||
24 | /** | ||
25 | * Destroy the ArrayList | ||
26 | */ | ||
27 | virtual ~ArrayList(); | ||
28 | |||
29 | void *getAt( int nIndex ); | ||
30 | void append( void *pData ); | ||
31 | void insertBefore( void *pData, int nPos = 0 ); | ||
32 | int getSize( ); | ||
33 | bool isEmpty( ); | ||
34 | void deleteAt( int nIndex ); | ||
35 | void empty(); | ||
36 | void setSize( int nNewSize ); | ||
37 | void setAt( int nIndex, void *pData ); | ||
38 | |||
39 | private: | ||
40 | /** | ||
41 | * Checks to see if the system needs to be resized, if it does, this will | ||
42 | * automatically resize based on your parameters. | ||
43 | */ | ||
44 | void checkResize(); | ||
45 | |||
46 | /** | ||
47 | * Resize the system to a specified size. If it is larger, then all data | ||
48 | * will be retained, if smaller the elements at the end will be cut off. | ||
49 | *@param newSize The number of elements to include after resizing. | ||
50 | */ | ||
51 | void resizeTo( int newSize ); | ||
52 | |||
53 | /** | ||
54 | * Actual master array of pointers. This is done to follow the List specs. | ||
55 | * All data transactions are performed with pointers or compatable | ||
56 | * primitive data-types. | ||
57 | */ | ||
58 | void **apData; | ||
59 | |||
60 | /** | ||
61 | * The number of filled in elements in the array. This is the practical | ||
62 | * real size of the ArrayList for all userspace applications. | ||
63 | */ | ||
64 | int nSize; | ||
65 | |||
66 | /** | ||
67 | * The number of elements allocated in memory. Not all of these have to be | ||
68 | * filled in, and it is usually larger than nSize so that adding and | ||
69 | * deleting elements is fast and easy. | ||
70 | */ | ||
71 | int nCapacity; | ||
72 | |||
73 | /** | ||
74 | * The amount to grow by whenever the array needs resizing. | ||
75 | */ | ||
76 | int nGrowByFactor; | ||
77 | }; | ||
78 | |||
79 | #endif | ||
80 | |||
diff --git a/src/old/hashfunction.cpp b/src/old/hashfunction.cpp deleted file mode 100644 index 51f2259..0000000 --- a/src/old/hashfunction.cpp +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #include "hashfunction.h" | ||
2 | |||
3 | HashFunction::HashFunction() | ||
4 | { | ||
5 | } | ||
6 | |||
7 | HashFunction::~HashFunction() | ||
8 | { | ||
9 | } | ||
10 | |||
diff --git a/src/old/hashfunction.h b/src/old/hashfunction.h deleted file mode 100644 index cbcf70f..0000000 --- a/src/old/hashfunction.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | #ifndef HASH_FUNCTION | ||
2 | #define HASH_FUNCTION | ||
3 | |||
4 | /** This represents the shell of a hash function. It must be aggregated in | ||
5 | * order to be used. Please read about it's two functions for specificatins | ||
6 | * relating to what values will be passed to them and what they should return | ||
7 | * for creating your own hash functions. | ||
8 | *@author Mike Buland. | ||
9 | */ | ||
10 | class HashFunction | ||
11 | { | ||
12 | public: | ||
13 | /** | ||
14 | * Standard Constructor. | ||
15 | */ | ||
16 | HashFunction(); | ||
17 | |||
18 | /** | ||
19 | * Standard Deconstructor. | ||
20 | */ | ||
21 | virtual ~HashFunction(); | ||
22 | |||
23 | /** Hashes the value represnted by id. This must return a fairly unique | ||
24 | * number in the range of 0-2^32 (or whatever the size of an unsigned long | ||
25 | * is on your system) based on the id given. The faster the number changes | ||
26 | * the better in a general sence. The return value will be the index | ||
27 | * (after probing takes place) to the data assosiated with an id, so this | ||
28 | * function should always produce the same number for any given id. | ||
29 | *@param id The identifier to use to create a unique numerical identifier. | ||
30 | *@returns A mostly unique numerical identifier generated using the given | ||
31 | * id. | ||
32 | */ | ||
33 | virtual unsigned long int hash( const void *id ) = 0; | ||
34 | |||
35 | /** This function must compare two ids in the format that this hashfunction | ||
36 | * accepts. For example, if the hash function hashes strings it should | ||
37 | * probably { return strcmp( id1, id2 ) == 0 }. | ||
38 | *@param id1 One value to use in the comparison | ||
39 | *@param id2 Another value to use in the comparison | ||
40 | *@returns True if the two values match, otherwise false. | ||
41 | */ | ||
42 | virtual bool cmpIDs( const void *id1, const void *id2 ) = 0; | ||
43 | |||
44 | // virtual void *createPersistantID( const void *id ) = 0; | ||
45 | // virtual void destroyPersistantID( const void *id ) = 0; | ||
46 | }; | ||
47 | |||
48 | #endif | ||
diff --git a/src/old/hashfunctioncasestring.cpp b/src/old/hashfunctioncasestring.cpp deleted file mode 100644 index 6361f45..0000000 --- a/src/old/hashfunctioncasestring.cpp +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <string.h> | ||
3 | #include <ctype.h> | ||
4 | #include "hashfunctioncasestring.h" | ||
5 | |||
6 | HashFunctionCaseString::HashFunctionCaseString() | ||
7 | { | ||
8 | } | ||
9 | |||
10 | HashFunctionCaseString::~HashFunctionCaseString() | ||
11 | { | ||
12 | } | ||
13 | |||
14 | unsigned long int HashFunctionCaseString::hash( const void *id ) | ||
15 | { | ||
16 | const char *str = (const char *)id; | ||
17 | unsigned long int nPos = 0; | ||
18 | for( int j = 0; str[j] != '\0'; j++ ) | ||
19 | { | ||
20 | nPos = tolower(str[j]) + (nPos << 6) + (nPos << 16) - nPos; | ||
21 | // nPos += nPos<<16|(((unsigned long int)tolower(str[j]))<<((j*7)%24)); | ||
22 | } | ||
23 | return nPos; | ||
24 | } | ||
25 | |||
26 | bool HashFunctionCaseString::cmpIDs( const void *id1, const void *id2 ) | ||
27 | { | ||
28 | const char *str1 = (const char *)id1; | ||
29 | const char *str2 = (const char *)id2; | ||
30 | |||
31 | int j; | ||
32 | for( j = 0; str1[j] != '\0' && str2[j] != '\0'; j++ ) | ||
33 | { | ||
34 | if( tolower(str1[j]) != tolower(str2[j]) ) | ||
35 | return false; | ||
36 | } | ||
37 | return (str1[j]==str2[j]); | ||
38 | } | ||
39 | |||
diff --git a/src/old/hashfunctioncasestring.h b/src/old/hashfunctioncasestring.h deleted file mode 100644 index 7816a1b..0000000 --- a/src/old/hashfunctioncasestring.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #ifndef HASH_FUNCTION_CASE_STRING | ||
2 | #define HASH_FUNCTION_CASE_STRING | ||
3 | |||
4 | #include "hashfunction.h" | ||
5 | |||
6 | /** A hash function for string data. This hash function does strings, but is | ||
7 | * actually generalized to handle any binary stream of characters terminated | ||
8 | * by a null character. This is different than HashFunctionString in that | ||
9 | * this does comparisons without regaurd to case. | ||
10 | *@author Mike Buland. | ||
11 | */ | ||
12 | class HashFunctionCaseString : public HashFunction | ||
13 | { | ||
14 | public: | ||
15 | /** | ||
16 | * Standard Constructor. | ||
17 | */ | ||
18 | HashFunctionCaseString(); | ||
19 | |||
20 | /** | ||
21 | * Standard Deconstructor. | ||
22 | */ | ||
23 | virtual ~HashFunctionCaseString(); | ||
24 | unsigned long int hash( const void *id ); | ||
25 | bool cmpIDs( const void *id1, const void *id2 ); | ||
26 | }; | ||
27 | |||
28 | #endif | ||
diff --git a/src/old/hashfunctionint.cpp b/src/old/hashfunctionint.cpp deleted file mode 100644 index 4bd0feb..0000000 --- a/src/old/hashfunctionint.cpp +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | #include "hashfunctionint.h" | ||
2 | |||
3 | HashFunctionInt::HashFunctionInt() | ||
4 | { | ||
5 | } | ||
6 | |||
7 | HashFunctionInt::~HashFunctionInt() | ||
8 | { | ||
9 | } | ||
10 | |||
11 | unsigned long int HashFunctionInt::hash( const void *id ) | ||
12 | { | ||
13 | return (unsigned long)(id); | ||
14 | } | ||
15 | |||
16 | bool HashFunctionInt::cmpIDs( const void *id1, const void *id2 ) | ||
17 | { | ||
18 | return (unsigned long)(id1) == (unsigned long)(id2); | ||
19 | } | ||
20 | |||
diff --git a/src/old/hashfunctionint.h b/src/old/hashfunctionint.h deleted file mode 100644 index 0fbc764..0000000 --- a/src/old/hashfunctionint.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | #ifndef HASH_FUNCTION_INT | ||
2 | #define HASH_FUNCTION_INT | ||
3 | |||
4 | #include "hashfunction.h" | ||
5 | |||
6 | /** A hash function for integer data. Really, this does almost nothing except | ||
7 | * ensure we're dealing with positive indicies. | ||
8 | *@author Mike Buland. | ||
9 | */ | ||
10 | class HashFunctionInt : public HashFunction | ||
11 | { | ||
12 | public: | ||
13 | /** | ||
14 | * Standard Constructor. | ||
15 | */ | ||
16 | HashFunctionInt(); | ||
17 | |||
18 | /** | ||
19 | * Standard Deconstructor. | ||
20 | */ | ||
21 | virtual ~HashFunctionInt(); | ||
22 | unsigned long int hash( const void *id ); | ||
23 | bool cmpIDs( const void *id1, const void *id2 ); | ||
24 | }; | ||
25 | |||
26 | #endif | ||
diff --git a/src/old/hashfunctionstring.cpp b/src/old/hashfunctionstring.cpp deleted file mode 100644 index bd14643..0000000 --- a/src/old/hashfunctionstring.cpp +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | #include "hashfunctionstring.h" | ||
2 | #ifndef NULL | ||
3 | #define NULL ((void *) 0) | ||
4 | #endif | ||
5 | |||
6 | HashFunctionString::HashFunctionString() | ||
7 | { | ||
8 | } | ||
9 | |||
10 | HashFunctionString::~HashFunctionString() | ||
11 | { | ||
12 | } | ||
13 | |||
14 | unsigned long int HashFunctionString::hash( const void *id ) | ||
15 | { | ||
16 | if (id == NULL) | ||
17 | { | ||
18 | return 0; | ||
19 | } | ||
20 | |||
21 | unsigned long int nPos = 0; | ||
22 | for( const char *s = (const char *)id; *s; s++ ) | ||
23 | { | ||
24 | nPos = *s + (nPos << 6) + (nPos << 16) - nPos; | ||
25 | } | ||
26 | return nPos; | ||
27 | } | ||
28 | |||
29 | bool HashFunctionString::cmpIDs( const void *id1, const void *id2 ) | ||
30 | { | ||
31 | if (id1 == NULL || id2 == NULL) | ||
32 | { | ||
33 | return false; | ||
34 | } | ||
35 | if (id1 == id2) | ||
36 | { | ||
37 | return true; | ||
38 | } | ||
39 | |||
40 | const char *str1 = (const char *)id1; | ||
41 | const char *str2 = (const char *)id2; | ||
42 | |||
43 | int j; | ||
44 | for( j = 0; str1[j] != '\0' && str2[j] != '\0'; j++ ) | ||
45 | { | ||
46 | if( str1[j] != str2[j] ) | ||
47 | return false; | ||
48 | } | ||
49 | return (str1[j]==str2[j]); | ||
50 | } | ||
51 | |||
diff --git a/src/old/hashfunctionstring.h b/src/old/hashfunctionstring.h deleted file mode 100644 index 7d2a1a6..0000000 --- a/src/old/hashfunctionstring.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | #ifndef HASH_FUNCTION_STRING | ||
2 | #define HASH_FUNCTION_STRING | ||
3 | |||
4 | #include "hashfunction.h" | ||
5 | |||
6 | /** A hash function for string data. This hash function does strings, but is | ||
7 | * actually generalized to handle any binary stream of characters terminated | ||
8 | * by a null character. | ||
9 | *@author Mike Buland. | ||
10 | */ | ||
11 | class HashFunctionString : public HashFunction | ||
12 | { | ||
13 | public: | ||
14 | /** | ||
15 | * Standard Constructor. | ||
16 | */ | ||
17 | HashFunctionString(); | ||
18 | |||
19 | /** | ||
20 | * Standard Deconstructor. | ||
21 | */ | ||
22 | virtual ~HashFunctionString(); | ||
23 | unsigned long int hash( const void *id ); | ||
24 | bool cmpIDs( const void *id1, const void *id2 ); | ||
25 | }; | ||
26 | |||
27 | #endif | ||
diff --git a/src/old/hashtable.cpp b/src/old/hashtable.cpp deleted file mode 100644 index dbcd964..0000000 --- a/src/old/hashtable.cpp +++ /dev/null | |||
@@ -1,424 +0,0 @@ | |||
1 | #include <string.h> | ||
2 | #include <stdio.h> | ||
3 | #include <math.h> | ||
4 | |||
5 | #include "hashtable.h" | ||
6 | |||
7 | HashTable::HashTable( HashFunction *hNewFunc, unsigned long int nInitSize, bool bAllowDupes ) | ||
8 | { | ||
9 | hFunc = hNewFunc; | ||
10 | nTableSize = nextPrime( nInitSize ); | ||
11 | aTable = new HashNode[nTableSize]; | ||
12 | //for( int j = 0; j < nTableSize; j++ ) if( aTable[j].id || aTable[j].data || aTable[j].bDeleted ) printf("Unclean entry\n"); | ||
13 | nSize = 0; | ||
14 | nFilled = 0; | ||
15 | this->bAllowDupes = bAllowDupes; | ||
16 | } | ||
17 | |||
18 | HashTable::~HashTable() | ||
19 | { | ||
20 | delete[] aTable; | ||
21 | delete hFunc; | ||
22 | } | ||
23 | |||
24 | void HashTable::set( int j, const void *newID, const void *newData ) | ||
25 | { | ||
26 | if( newData == NULL ) | ||
27 | { | ||
28 | printf("Inserting NULL data is indestinguishable from uninserted data!\n"); | ||
29 | } | ||
30 | aTable[j].id = newID; | ||
31 | aTable[j].data = newData; | ||
32 | } | ||
33 | |||
34 | void HashTable::clear() | ||
35 | { | ||
36 | memset( aTable, 0, sizeof(HashNode) * nTableSize ); | ||
37 | } | ||
38 | |||
39 | bool HashTable::isFilled( int j ) | ||
40 | { | ||
41 | return (aTable[j].id != NULL)||(aTable[j].bDeleted); | ||
42 | } | ||
43 | |||
44 | void HashTable::reHash( unsigned long int nNewSize ) | ||
45 | { | ||
46 | HashNode *aOldTable = aTable; | ||
47 | unsigned long int oldSize = nTableSize; | ||
48 | |||
49 | // If the table can still be used if we just get rid of deleted items, don't | ||
50 | // change the size of the table, otherwise, go ahead and use the number | ||
51 | // passed in. | ||
52 | if( nSize > nTableSize>>1 ) | ||
53 | { | ||
54 | nTableSize = nextPrime( nNewSize ); | ||
55 | } | ||
56 | |||
57 | aTable = newTable( nTableSize ); | ||
58 | //for( int j = 0; j < nTableSize; j++ ) if( aTable[j].id || aTable[j].data || aTable[j].bDeleted ) printf("Unclean entry\n"); | ||
59 | |||
60 | nSize = 0; | ||
61 | nFilled = 0; | ||
62 | |||
63 | for( unsigned long int j = 0; j < oldSize; j++ ) | ||
64 | { | ||
65 | if( aOldTable[j].id != NULL && aOldTable[j].bDeleted == false ) | ||
66 | { | ||
67 | insert( aOldTable[j].id, aOldTable[j].data ); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | delete[] aOldTable; | ||
72 | } | ||
73 | |||
74 | unsigned long int HashTable::probe( unsigned long int nStart, const void *id ) | ||
75 | { | ||
76 | int nHash = nStart; | ||
77 | nStart = nStart%nTableSize; | ||
78 | if( bAllowDupes == true ) | ||
79 | { | ||
80 | for( | ||
81 | unsigned long int j=0; | ||
82 | isFilled( nStart ) && j < 32; | ||
83 | nStart = (nStart+(1<<j))%nTableSize, j++ | ||
84 | ); | ||
85 | |||
86 | /** | ||
87 | * This is an ugly little hack. If the hash table is too full in allow- | ||
88 | * dups mode we have to fall back on a linear search, otherwise you can | ||
89 | * only get up to 32 entries with the same name. | ||
90 | */ | ||
91 | if( isFilled( nStart ) ) | ||
92 | { | ||
93 | unsigned long int nOldStart = nStart; | ||
94 | for( | ||
95 | nStart++; | ||
96 | isFilled( nStart ) && nStart != nOldStart; | ||
97 | nStart = (nStart+1)%nTableSize | ||
98 | ); | ||
99 | } | ||
100 | } | ||
101 | else | ||
102 | { | ||
103 | for( | ||
104 | unsigned long int j=0; | ||
105 | isFilled( nStart ) && j < 32; | ||
106 | nStart = (nStart+(1<<j))%nTableSize, j++ | ||
107 | ) | ||
108 | { | ||
109 | if( isFilled( nStart ) ) | ||
110 | { | ||
111 | if( hFunc->cmpIDs( aTable[nStart].id, id ) == true && | ||
112 | aTable[nStart].bDeleted == false ) | ||
113 | { | ||
114 | return nStart; | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | // This is our insurance, if the table is full, then go ahead and rehash, | ||
120 | // then try again. | ||
121 | if( isFilled( nStart ) ) | ||
122 | { | ||
123 | reHash( getCapacity()*2 ); | ||
124 | return probe( nHash, id ); | ||
125 | } | ||
126 | return nStart; | ||
127 | } | ||
128 | |||
129 | HashTable::HashNode *HashTable::newTable( unsigned long int nNewSize ) | ||
130 | { | ||
131 | return new HashNode[nNewSize]; | ||
132 | } | ||
133 | |||
134 | #ifdef HASH_DEBUG_VIS | ||
135 | void HashTable::printDebugLine( const char *exData ) | ||
136 | { | ||
137 | char *buf = new char[getCapacity()+3]; | ||
138 | int j; | ||
139 | buf[0] = '['; | ||
140 | for( j = 0; j < getCapacity(); j++ ) | ||
141 | { | ||
142 | buf[j+1] = (aTable[j].bDeleted)?('X'):((isFilled( j ))?('#'):('-')); | ||
143 | } | ||
144 | buf[j+1] = ']'; | ||
145 | buf[j+2] = '\0'; | ||
146 | printf("%s %s\n", buf, exData ); | ||
147 | delete[] buf; | ||
148 | } | ||
149 | #endif | ||
150 | |||
151 | bool HashTable::insert( const void *id, const void *data ) | ||
152 | { | ||
153 | unsigned long int nPos = probe( hFunc->hash( id ), id )%nTableSize; | ||
154 | |||
155 | if( bAllowDupes == true ) | ||
156 | { | ||
157 | if( aTable[nPos].id == NULL && aTable[nPos].bDeleted == false ) | ||
158 | { | ||
159 | set( nPos, id, data ); | ||
160 | #ifdef HASH_DEBUG_VIS | ||
161 | printDebugLine( (const char *)id ); | ||
162 | #endif | ||
163 | nSize++; | ||
164 | nFilled++; | ||
165 | return true; | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | return false; | ||
170 | } | ||
171 | } | ||
172 | else | ||
173 | { | ||
174 | if( aTable[nPos].id == NULL && aTable[nPos].bDeleted == false ) | ||
175 | { | ||
176 | set( nPos, id, data ); | ||
177 | #ifdef HASH_DEBUG_VIS | ||
178 | printDebugLine( (const char *)id ); | ||
179 | #endif | ||
180 | nSize++; | ||
181 | nFilled++; | ||
182 | return true; | ||
183 | } | ||
184 | else if( hFunc->cmpIDs( aTable[nPos].id, id ) == true ) | ||
185 | { | ||
186 | set( nPos, id, data ); | ||
187 | #ifdef HASH_DEBUG_VIS | ||
188 | printDebugLine( (const char *)id ); | ||
189 | #endif | ||
190 | return true; | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | return false; | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
199 | const void *HashTable::get( const void *id, unsigned long int nSkip ) | ||
200 | { | ||
201 | unsigned long int nPos = hFunc->hash( id )%nTableSize; | ||
202 | |||
203 | for( unsigned long int j=0; j < 32; nPos = (nPos+(1<<j))%nTableSize, j++ ) | ||
204 | { | ||
205 | if( !isFilled( nPos ) ) return NULL; | ||
206 | if( aTable[nPos].bDeleted == false ) | ||
207 | { | ||
208 | if( hFunc->cmpIDs( id, aTable[nPos].id ) ) | ||
209 | { | ||
210 | if( nSkip == 0 ) | ||
211 | { | ||
212 | return aTable[nPos].data; | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | nSkip--; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | if( bAllowDupes ) | ||
223 | { | ||
224 | unsigned long int nOldPos = nPos; | ||
225 | for( nPos++; nPos != nOldPos; nPos=(nPos+1)%nTableSize ) | ||
226 | { | ||
227 | if( !isFilled( nPos ) ) return NULL; | ||
228 | if( aTable[nPos].bDeleted == false ) | ||
229 | { | ||
230 | if( hFunc->cmpIDs( id, aTable[nPos].id ) ) | ||
231 | { | ||
232 | if( nSkip == 0 ) | ||
233 | { | ||
234 | return aTable[nPos].data; | ||
235 | } | ||
236 | else | ||
237 | { | ||
238 | nSkip--; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return NULL; | ||
246 | } | ||
247 | |||
248 | const void *HashTable::getKey( const void *id, unsigned long int nSkip ) | ||
249 | { | ||
250 | unsigned long int nPos = hFunc->hash( id )%nTableSize; | ||
251 | |||
252 | for( unsigned long int j=0; j < 32; nPos = (nPos+(1<<j))%nTableSize, j++ ) | ||
253 | { | ||
254 | if( !isFilled( nPos ) ) return NULL; | ||
255 | if( aTable[nPos].bDeleted == false ) | ||
256 | { | ||
257 | if( hFunc->cmpIDs( id, aTable[nPos].id ) ) | ||
258 | { | ||
259 | if( nSkip == 0 ) | ||
260 | { | ||
261 | return aTable[nPos].id; | ||
262 | } | ||
263 | else | ||
264 | { | ||
265 | nSkip--; | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | if( bAllowDupes ) | ||
272 | { | ||
273 | unsigned long int nOldPos = nPos; | ||
274 | for( nPos++; nPos != nOldPos; nPos=(nPos+1)%nTableSize ) | ||
275 | { | ||
276 | if( !isFilled( nPos ) ) return NULL; | ||
277 | if( aTable[nPos].bDeleted == false ) | ||
278 | { | ||
279 | if( hFunc->cmpIDs( id, aTable[nPos].id ) ) | ||
280 | { | ||
281 | if( nSkip == 0 ) | ||
282 | { | ||
283 | return aTable[nPos].id; | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | nSkip--; | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | |||
294 | return NULL; | ||
295 | } | ||
296 | |||
297 | void *HashTable::getFirstItemPos() | ||
298 | { | ||
299 | HashPos *pos = new HashPos; | ||
300 | return pos; | ||
301 | } | ||
302 | |||
303 | const void *HashTable::getItemData( void *xPos ) | ||
304 | { | ||
305 | return aTable[((HashPos *)xPos)->nPos].data; | ||
306 | } | ||
307 | |||
308 | const void *HashTable::getItemID( void *xPos ) | ||
309 | { | ||
310 | return aTable[((HashPos *)xPos)->nPos].id; | ||
311 | } | ||
312 | |||
313 | void *HashTable::getNextItemPos( void *xPos ) | ||
314 | { | ||
315 | HashPos *pos = (HashPos *)xPos; | ||
316 | if( pos->bStarted == false ) | ||
317 | { | ||
318 | pos->bStarted = true; | ||
319 | pos->nPos = 0; | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | pos->nPos++; | ||
324 | } | ||
325 | if( pos->nPos < nTableSize ) | ||
326 | { | ||
327 | for( ; pos->nPos < nTableSize; pos->nPos++ ) | ||
328 | { | ||
329 | if( isFilled( pos->nPos ) && | ||
330 | aTable[pos->nPos].bDeleted == false ) | ||
331 | { | ||
332 | return xPos; | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | |||
337 | delete pos; | ||
338 | |||
339 | return NULL; | ||
340 | } | ||
341 | |||
342 | // Big-O sqrt(n) | ||
343 | // Change this to be erethpothynies table with a storage | ||
344 | // lookup later on. | ||
345 | bool HashTable::isPrime (int num) | ||
346 | { | ||
347 | if (num == 2) // the only even prime | ||
348 | return true; | ||
349 | else if (num % 2 == 0) // other even numbers are composite | ||
350 | return false; | ||
351 | else | ||
352 | { | ||
353 | //bool prime = true; | ||
354 | int divisor = 3; | ||
355 | int upperLimit = static_cast<int>(sqrt(num) + 1); | ||
356 | while (divisor <= upperLimit) | ||
357 | { | ||
358 | if (num % divisor == 0) | ||
359 | return false; | ||
360 | // prime = false; | ||
361 | divisor +=2; | ||
362 | } | ||
363 | return true; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | // Big-O n^(3/2) | ||
368 | int HashTable::nextPrime( int base ) | ||
369 | { | ||
370 | int nPrime; | ||
371 | for( nPrime = base; isPrime( nPrime ) == false; nPrime++ ); | ||
372 | return nPrime; | ||
373 | } | ||
374 | |||
375 | unsigned long int HashTable::getCapacity() | ||
376 | { | ||
377 | return nTableSize; | ||
378 | } | ||
379 | |||
380 | unsigned long int HashTable::getSize() | ||
381 | { | ||
382 | return nSize; | ||
383 | } | ||
384 | |||
385 | double HashTable::getLoad() | ||
386 | { | ||
387 | return (double)(nFilled)/(double)(nTableSize); | ||
388 | } | ||
389 | |||
390 | const void *HashTable::operator[](const void *id) | ||
391 | { | ||
392 | return get( id ); | ||
393 | } | ||
394 | |||
395 | bool HashTable::del( const void *id, int nSkip ) | ||
396 | { | ||
397 | unsigned long int nPos = hFunc->hash( id )%nTableSize; | ||
398 | |||
399 | for( unsigned long int j=0; j < 32; nPos = (nPos+(1<<j))%nTableSize, j++ ) | ||
400 | { | ||
401 | if( !isFilled( nPos ) ) return false; | ||
402 | //printf("0x%08X \"%s\" == 0x%08X \"%s\" (%d)\n", id, id, aTable[nPos].id, aTable[nPos].id, nPos ); | ||
403 | if( hFunc->cmpIDs( id, aTable[nPos].id ) && | ||
404 | aTable[nPos].bDeleted == false ) | ||
405 | { | ||
406 | if( nSkip == 0 ) | ||
407 | { | ||
408 | aTable[nPos].bDeleted = true; | ||
409 | nSize--; | ||
410 | #ifdef HASH_DEBUG_VIS | ||
411 | printDebugLine( (const char *)id ); | ||
412 | #endif | ||
413 | return true; | ||
414 | } | ||
415 | else | ||
416 | { | ||
417 | nSkip--; | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | |||
422 | return false; | ||
423 | } | ||
424 | |||
diff --git a/src/old/hashtable.h b/src/old/hashtable.h deleted file mode 100644 index 179b694..0000000 --- a/src/old/hashtable.h +++ /dev/null | |||
@@ -1,308 +0,0 @@ | |||
1 | /**\hashtable.h | ||
2 | * Describes the HashFunction, HashFunctionString, and HashTable classes. It | ||
3 | * was just easier to put them all in one set of files. | ||
4 | *@author Mike Buland | ||
5 | */ | ||
6 | |||
7 | #ifndef HASH_TABLE_H | ||
8 | #define HASH_TABLE_H | ||
9 | |||
10 | //Uncomment this line to see a cool text-mode visualization of what's going on | ||
11 | //#define HASH_DEBUG_VIS 1 | ||
12 | |||
13 | #include <stdlib.h> | ||
14 | #include <string.h> | ||
15 | #include <ctype.h> | ||
16 | |||
17 | #include "hashfunction.h" | ||
18 | |||
19 | /** | ||
20 | * A simple yet flexable hash-table. This uses several tricks to help ensure | ||
21 | * that the table is always running at maximum efficiency. You no longer have | ||
22 | * to specify a "danger fill level" when more space is needed a rehash is | ||
23 | * automatically trigered. Deleting elements is fully supported, as well as | ||
24 | * duplicate elements. To work with and allow duplicates simple construct your | ||
25 | * HashTable the way you normally would, but when deleting or getting elements | ||
26 | * you can specify a skip value. This effectively allows you to treat elements | ||
27 | * with duplicate ID's as though they were in a zero-based array. The first | ||
28 | * element inserted with a given ID would be at skip zero, the next at skip 1 | ||
29 | * and so on. This allows you to quickly search for elements with duplicate | ||
30 | * names, just stop when you get a null for a skip number, i.e. | ||
31 | * <pre> | ||
32 | * for( int j = 0;; j++ ) | ||
33 | * { | ||
34 | * void *pData = hash.get( myID, j ); | ||
35 | * if( !pData ) break; | ||
36 | * // Do something interesting with pData | ||
37 | * } | ||
38 | * </pre> | ||
39 | * There are new features in this HashTable that also allow for memory saving | ||
40 | * when dealing with systems where many elements are being deleted from the | ||
41 | * table. In those cases the elements deleted cannot be simply deleted, instead | ||
42 | * they have to be marked as deleted and hidden from the user, but maintained in | ||
43 | * the table so that future hashing operations don't fail. When rehashing | ||
44 | * occurs all elements marked as deleted are quietly removed. In these cases, | ||
45 | * if the number of deleted items would free enough space in the table for the | ||
46 | * table to be used efficiently without resizing, it is left the same size and | ||
47 | * rehashing is performed effectively in place, allowing the deleted items to | ||
48 | * be removed. | ||
49 | * <br> | ||
50 | * For info on adding new hashing algorithms, please see the HashFunction class. | ||
51 | *@author Mike Buland | ||
52 | *@todo Fix probing for tables that allow duplicates, and delete an item, then | ||
53 | * insert an item with the same name. | ||
54 | */ | ||
55 | class HashTable | ||
56 | { | ||
57 | public: | ||
58 | /** Constructs a hash table. | ||
59 | *@param hNewFunc A pointer to a hashfunction class to use. If this is | ||
60 | * null the default general string type will be used. | ||
61 | *@param nInitSize The initial size of the hashtable. | ||
62 | *@param bAllowDupes Setting this value to true allows the system to | ||
63 | * insert more than one copy of any given key. This can be tricky, and | ||
64 | * will require you to use the nSkip parameter on the get function. | ||
65 | */ | ||
66 | HashTable( HashFunction *hNewFunc, unsigned long int nInitSize, bool bAllowDupes=false ); | ||
67 | |||
68 | /** | ||
69 | * Destroys the hashtable, cleaning up all internal storage, but not stored | ||
70 | * elements. Also deletes the HashFunction passed in in the constructor. | ||
71 | */ | ||
72 | virtual ~HashTable(); | ||
73 | |||
74 | /** Inserts an item into the hashtable. This function will trigger a | ||
75 | * rehash if adding another item would force the table's load factor over | ||
76 | * the danger level. | ||
77 | *@param id used to find the data later. | ||
78 | *@param data The data item to insert into the table with the identifier | ||
79 | * id | ||
80 | *@returns True if insertion was successfull, and false if it failed. | ||
81 | */ | ||
82 | bool insert( const void *id, const void *data ); | ||
83 | |||
84 | /** Gets an item in the hashtable based on the id of that item. If there | ||
85 | * is more than one item with the same id you can use the nSkip parameter | ||
86 | * to access all of them. | ||
87 | *@param id The id of the item you're trying to find. | ||
88 | *@param nSkip The number of items with that id to skip before returning | ||
89 | * with the requested item. | ||
90 | *@returns A pointer to the data stored at the given id. | ||
91 | */ | ||
92 | const void *get( const void *id, unsigned long int nSkip=0 ); | ||
93 | |||
94 | const void *getKey( const void *id, unsigned long int nSkip=0 ); | ||
95 | |||
96 | /** Gets the total capacity of the hashtable. This is actually the number | ||
97 | * of total positions available inside the hashtable at the moment. This | ||
98 | * will change when the hashtable's load exceeds the danger level. | ||
99 | * Please note that this is NOT the actual amount of space available. | ||
100 | * In reality you can only access about 45-50 percent of that space. | ||
101 | *@returns The total capacity. | ||
102 | */ | ||
103 | unsigned long int getCapacity(); | ||
104 | |||
105 | /** Gets the number of filled in items in the hash table. This is roughly | ||
106 | * equivelent to the getSize function assosiated with the Lists. | ||
107 | *@returns The number of filled in items in the hash table. | ||
108 | */ | ||
109 | unsigned long int getSize(); | ||
110 | |||
111 | /** Gets the load (percentage) of filled in items in the table. This is | ||
112 | * technically the size divided by the capacity, but is definately usefull | ||
113 | * since it's required to check if it's time to rehash. | ||
114 | *@returns The table load in the range 0.0 to 1.0 | ||
115 | */ | ||
116 | double getLoad(); | ||
117 | |||
118 | /** Sets up an xPos object for use indexing the items in the table. Call | ||
119 | * this first and follow the directions for getNextItemPos below to | ||
120 | * iterate through every item in the table, while avoiding the empty | ||
121 | * spaces. | ||
122 | *@returns A pointer to a xPos object telling the hashtable where to find | ||
123 | * the item you're looking at. | ||
124 | */ | ||
125 | void *getFirstItemPos(); | ||
126 | |||
127 | /** Get the item's data that is being pointed to by xPos. This is only | ||
128 | * valid after xPos was created using getFirstItemPos and getNextItemPos | ||
129 | * was called at least once. | ||
130 | *@param xPos supplied by getFirstItemPos. | ||
131 | *@returns The key value that was used to insert the data into the table. | ||
132 | */ | ||
133 | const void *getItemData( void *xPos ); | ||
134 | |||
135 | /** Get the item's ID that is being pointed to by xPos. This is only | ||
136 | * valid after xPos was created using getFirstItemPos and getNextItemPos | ||
137 | * was called at least once. | ||
138 | *@param xPos supplied by getFirstItemPos. | ||
139 | *@returns The key value that was used to insert the data into the table. | ||
140 | */ | ||
141 | const void *getItemID( void *xPos ); | ||
142 | |||
143 | /** Used for iterating through a hash table sequentially. This will | ||
144 | * update the xPos pointer to point to the next time, all ready to | ||
145 | * be accessed with getItemID and getItemData. This must be called at | ||
146 | * least once before xPos is meaningful, and will return a NULL when it | ||
147 | * has reached the last item. | ||
148 | *@param xPos This must be an object created by a call to the function | ||
149 | * getFirstItemPos, and is only meaningful to the internal routines. | ||
150 | * Aborting a call in the middle (not running to the end of the table) | ||
151 | * may result in a memory leak at the moment. | ||
152 | *@returns xPos if still iterating through the list, otherwise it will | ||
153 | * return NULL when the end has been reached and the xPos variable has | ||
154 | * been deleted. | ||
155 | */ | ||
156 | void *getNextItemPos( void *xPos ); | ||
157 | |||
158 | /** A helpful operator to make accessing items easier. Please note that | ||
159 | * this simply returns a pointer to the data stored internally, and cannot | ||
160 | * be used like the STL operator to store new data, use insert for that. | ||
161 | *@param id The identifier used to store the requested item. | ||
162 | *@returns The data value assosiated with the given id, or NULL if it | ||
163 | * wasn't found in the table. | ||
164 | */ | ||
165 | const void *operator[](const void *id); | ||
166 | |||
167 | /** | ||
168 | * Delete the specified item from the hashtable. This actually keeps the | ||
169 | * data and marks it deleted. For all intents and purposes to the user it | ||
170 | * is deleted, except that the space is still used until a rehash is forced. | ||
171 | * This means that in hashtables where elements are being inserted and | ||
172 | * deleted frequently you may run into a higher rate of expansion. | ||
173 | *@param id The ID to delete. | ||
174 | *@param nSkip The number of similar id's to skip before deleting in a | ||
175 | * hashtable that allows duplicates. | ||
176 | *@returns True if the element was found and deleted, false otherwise. | ||
177 | */ | ||
178 | bool del( const void *id, int nSkip=0 ); | ||
179 | |||
180 | /** | ||
181 | * Deletes every entry in the hash table. See the notes on del to see what | ||
182 | * this means, except that since no data is being kept, the entire table is | ||
183 | * just marked as usable space. | ||
184 | */ | ||
185 | void clear(); | ||
186 | |||
187 | private: | ||
188 | /** | ||
189 | * Contains info related to a position in the hashtable. Used for | ||
190 | * searching through hashtables one item at a time, in order. This class | ||
191 | * should never be created by anything but a HashTable, and should never | ||
192 | * be referenced directly. Instead the hashtable returns a void pointer, | ||
193 | * which is what should be passed back in next time you use a search | ||
194 | * function. Always finish a search, since the object is deleted at the | ||
195 | * end of the search. | ||
196 | *@author Mike Buland | ||
197 | */ | ||
198 | class HashPos | ||
199 | { | ||
200 | public: | ||
201 | /** Create a blank HashPos. */ | ||
202 | HashPos() { bStarted=false; nPos = 0; }; | ||
203 | /** Has the search been started? */ | ||
204 | bool bStarted; | ||
205 | /** The position (index) into the backend storage structure. */ | ||
206 | unsigned long int nPos; | ||
207 | }; | ||
208 | |||
209 | /** | ||
210 | * All data related to a single element in the hashtable. This should | ||
211 | * really only be used and manipulated by the HashTable itself. | ||
212 | *@author Mike Buland | ||
213 | */ | ||
214 | typedef struct HashNode | ||
215 | { | ||
216 | public: | ||
217 | /** Create a new, empty HashNode. */ | ||
218 | HashNode() { id = NULL; data = NULL; bDeleted = false; }; | ||
219 | /** A pointer to the original ID that was used to key the data. */ | ||
220 | const void *id; | ||
221 | /** A pointer to the data stored along with the above ID. */ | ||
222 | const void *data; | ||
223 | /** Weather or not this data should really...exist */ | ||
224 | bool bDeleted; | ||
225 | } HashNode; | ||
226 | |||
227 | private: | ||
228 | /** | ||
229 | * Just sets the values in the element to some friendly values. | ||
230 | *@param newID The new ID to store. | ||
231 | *@param newData The new Data to store. | ||
232 | */ | ||
233 | void set( int j, const void *newID, const void *newData ); | ||
234 | /** | ||
235 | * Tells you if the node is filled or not. | ||
236 | *@returns True=an ID has been stored here, False=no ID. | ||
237 | */ | ||
238 | bool isFilled( int j ); | ||
239 | /** | ||
240 | * This actually resizes, but since every resize requires a reHash to go | ||
241 | * along with it, that's the name. This actually creates a new buffer for | ||
242 | * all of the contained data and then pulls every old element that was in | ||
243 | * the old table out and performs the hashing placement calculations again. | ||
244 | * This function skips all data that was marked as deleted, so at this | ||
245 | * point it really will be. | ||
246 | *@param nNewSize The new size to set the table to while re-hashing. | ||
247 | *@returns True if the operation was successful, false otherwise. | ||
248 | */ | ||
249 | void reHash( unsigned long int nNewSize ); | ||
250 | |||
251 | /** | ||
252 | * Helper function to allocate a new table. Really just does the memory | ||
253 | * allocation. | ||
254 | *@param nNewSize The size of the table to generate. | ||
255 | *@returns A new, blank array of HashNode objects the size you specified. | ||
256 | */ | ||
257 | HashNode *newTable( unsigned long int nNewSize ); | ||
258 | |||
259 | /** | ||
260 | * This function is used once an actual hash code is obtained. nStart is | ||
261 | * the given hash code, which is then wrapped to the size of the table. If | ||
262 | * there is data at that location, tests are performed to see if it's the | ||
263 | * right one. If it is, then it is returned, otherwise a series of further | ||
264 | * tests based on a 2^n search pattern is performed. The position of the | ||
265 | * requested data in the back-end storage is returned if found, otherwise | ||
266 | * another less useful value is returned... | ||
267 | *@param nStart The initial hashcode of the ID testing for. | ||
268 | *@param id A pointer to the id that is being searched for. | ||
269 | *@returns The real location of the data requested. | ||
270 | */ | ||
271 | unsigned long int probe( unsigned long int nStart, const void *id ); | ||
272 | |||
273 | /** | ||
274 | * Simple helper function to determine if a number is prime or not. | ||
275 | * This function runs in sqrt(n) time. | ||
276 | *@param num Number to test for prime-hood. | ||
277 | *@returns True if the number is prime, false otherwise. | ||
278 | */ | ||
279 | bool isPrime( int num ); | ||
280 | |||
281 | /** | ||
282 | * Given any number, this function finds the first number after it that is | ||
283 | * prime. Since this number is a multiple internally it's rare that the | ||
284 | * starting number would be prime. | ||
285 | *@param base The number to start the prime search on. | ||
286 | *@returns The first prime after the number given. | ||
287 | */ | ||
288 | int nextPrime( int base ); | ||
289 | |||
290 | #ifdef HASH_DEBUG_VIS | ||
291 | void printDebugLine( const char *exData ); | ||
292 | #endif | ||
293 | |||
294 | /** A pointer to the HashFunction subclass instance to use. */ | ||
295 | HashFunction *hFunc; | ||
296 | /** The complete array of HashNode objects to store data in. */ | ||
297 | HashNode *aTable; | ||
298 | /** The actual size of the table, not how many elements are in it. */ | ||
299 | unsigned long int nTableSize; | ||
300 | /** The number of elements that are in the table. */ | ||
301 | unsigned long int nSize; | ||
302 | /** The number of elements that are unavailable now. */ | ||
303 | unsigned long int nFilled; | ||
304 | /** Allow duplicate ID's in the table. */ | ||
305 | bool bAllowDupes; | ||
306 | }; | ||
307 | |||
308 | #endif | ||