• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  phashtable.h  *
3  *                                                                           *
4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 #ifndef PHASHTABLE_H
21 #define PHASHTABLE_H
22 
23 
24 
25 #include "PortPrefix.h"
26 #include "ptypes.h"
27 #include "ESR_ReturnCode.h"
28 
29 /**
30  * The default initial capacity of a hash table.
31  */
32 #define PHASH_TABLE_DEFAULT_CAPACITY 11
33 
34 /**
35  *
36  * The default maximum load factor
37  */
38 #define PHASH_TABLE_DEFAULT_MAX_LOAD_FACTOR (0.75f)
39 
40 /**
41  * Default hash function used for hashing keys.  The default function assumes
42  * the key is a 0-terminated LSTRING.
43  */
44 #define PHASH_TABLE_DEFAULT_HASH_FUNCTION NULL
45 
46 /**
47  * Default compare function used for hashing keys.  The default function
48  * assumes the key are 0-terminated LSTRING and uses LSTRCMP.
49  */
50 #define PHASH_TABLE_DEFAULT_COMP_FUNCTION NULL
51 
52 /**
53  * @addtogroup HashTableModule HashTable API functions
54  * Abstract hash table operations.  The keys of the Map are strings and values
55  * are plain void pointers.  The keys and values are only stored as pointers
56  * and it is the responsibility of the user to ensure proper memory management
57  * for the keys and values.
58  *
59  * The HashTable is implemented using an array of linked lists.  The capacity
60  * of the HashTable is the number of entries in this array.  The load factor
61  * of the HashTable is the ratio of the total number of entries in the table
62  * vs the capacity of the table.  The lower the load factor, the faster the
63  * look-up is.  However, a lower load factor calls for a bigger capacity,
64  * hence it increases the memory requirement.
65  *
66  * When the load factor exceeds the maximum load factor, the capacity of the
67  * hash table is increased and each entry is put in its new linked list based
68  * on the new capacity.
69  *
70  * @{
71  */
72 
73 /**
74  * Signature for hashing functions.
75  */
76 typedef unsigned int(*PHashFunction)(const void *key);
77 
78 /**
79  * Signature for comparison functions.  Must return 0 if key1 is identical to
80  * key2 and non-zero otherwise.  The hash function and the comparison function
81  * are related in the sense that if the comparison function for two keys
82  * return 0, then the values returned by the hash function when given these
83  * keys as arguments must be equal.
84  */
85 typedef int (*PHashCompFunction)(const LCHAR *key1, const LCHAR *key2);
86 
87 /** Typedef */
88 typedef struct PHashTable_t PHashTable;
89 /** Typedef */
90 typedef struct PHashTableEntry_t PHashTableEntry;
91 
92 /**
93  * Structure specified to specify initialization parameters for the hash
94  * table.
95  */
96 typedef struct PHashTableArgs_t
97 {
98   /**
99    * Total capacity.
100    */
101   size_t capacity;
102 
103   /**
104    * Maximum load-factor before hashtable is rehashed.
105    */
106   float maxLoadFactor;
107 
108   /**
109    * Hashing function used to compute the hashcode of a key.
110    */
111   PHashFunction hashFunction;
112 
113   /**
114    * Function used to compare two keys.
115    */
116   PHashCompFunction compFunction;
117 }
118 PHashTableArgs;
119 
120 /**
121  * Creates an hash table.  The hash table is created with specified capacity
122  * and maximum load factor.
123  *
124  * @param hashArgs Specifies the arguments controlling the hashtable.  If
125  * NULL, all arguments are assumed to be the default value.  This value is
126  * copied. This is the responsibility of the caller to delete the
127  * HashTableArgs if required.
128  *
129  * @param memTag Memory tag to be used for the internal memory allocation
130  * calls.  Since this string is used by the memory allocation tag, it is not
131  * copied internally and it must remain valid for the lifetime of the hash
132  * table including the call to the HashTableDestroy function.  Most likely,
133  * this string is a static string or is allocated from the stack.
134  *
135  * @param hashtable A pointer to the returned hash table. This parameter may
136  * not be NULL.
137  * @return ESR_INVALID_ARGUMENT if hashArgs, or hashTable is null or
138  * hashArgs->maxLoadFactor <= 0; ESR_OUT_OF_MEMORY if system is out of memory
139  */
140 PORTABLE_API ESR_ReturnCode PHashTableCreate(PHashTableArgs *hashArgs,
141     const LCHAR *memTag,
142     PHashTable **hashtable);
143 
144 /**
145  * Destructor.  The keys and values need to be deleted (if necessary) before
146  * deleting the table to avoid memory leak.
147  *
148  * @param ESR_INVALID_ARGUMENT if hashtable is null
149  */
150 PORTABLE_API ESR_ReturnCode PHashTableDestroy(PHashTable *hashtable);
151 
152 /**
153  * Retrieves the size (number of entries) of the hashtable.
154  *
155  * @return ESR_INVALID_ARGUMENT if hashtable or size is null
156  */
157 PORTABLE_API ESR_ReturnCode PHashTableGetSize(PHashTable *hashtable,
158     size_t *size);
159 
160 
161 /**
162  * Retrieves the value associated with a key.
163  *
164  * @param hashtable The hashtable
165  * @param key The key for which to retrieve the value.
166  * @param value The value associated with the key.
167  * @return If no match, ESR_NO_MATCH_ERROR is returned.
168  */
169 PORTABLE_API ESR_ReturnCode PHashTableGetValue(PHashTable *hashtable,
170     const void *key, void **value);
171 
172 /**
173  * Indicates if hashtable contains the specified key.
174  *
175  * @param hashtable The hashtable
176  * @param key The key for which to retrieve the value.
177  * @param exists [out] True if the key was found
178  * @return ESR_INVALID_ARGUMENT if self is null
179  */
180 PORTABLE_API ESR_ReturnCode PHashTableContainsKey(PHashTable *hashtable,
181     const void *key, ESR_BOOL* exists);
182 /**
183  * Associates a value with a key.
184  *
185  * @param hashtable The hashtable
186  *
187  * @param key The key to associate a value with.
188  *
189  * @param value The value to associate with a key.
190  *
191  * @param oldValue If this pointer is non-NULL, it will be set to the
192  * value previously associated with the key.
193  * @return ESR_INVALID_STATE if hashtable is null
194  */
195 PORTABLE_API ESR_ReturnCode PHashTablePutValue(PHashTable *hashtable,
196     const void *key,
197     const void *value,
198     void **oldValue);
199 
200 /**
201  * Removes the value with associated with a key.  Note that calling this
202  * function might cause a leak in the event that the key needs to be deleted.
203  * In those situations, use PHashTableGetEntry, then retrieve the key by
204  * PHashTableEntryGetKeyValue, destroy the key and value and then use
205  * PHashTableEntryRemove.
206  *
207  * @param hashtable The hashtable
208  * @param key The key for which to remove the associated value.
209  * @param oldValue If this pointer is non-NULL, it will be set to the value
210  * previously associated with the key and that was removed.
211  * @return ESR_INVALID_ARGUMENT if hashtable is null
212  */
213 PORTABLE_API ESR_ReturnCode PHashTableRemoveValue(PHashTable *hashtable,
214     const void *key,
215     void **oldValue);
216 
217 /**
218  * Retrieves the hash entry corresponding to the key.
219  *
220  * @param hashtable The hashtable
221  * @param key The key for which to retrieve the hash entry.
222  * @param entry The entry associated with the key. Cannot be NULL.
223  * @return If no match, ESR_NO_MATCH_ERROR is returned.
224  */
225 PORTABLE_API ESR_ReturnCode PHashTableGetEntry(PHashTable *hashtable,
226     const void *key,
227     PHashTableEntry **entry);
228 
229 /**
230  * Returns the key and value associated with this entry.  Both key and values
231  * can be deleted after removing the entry from the table.
232  *
233  * @param entry The hashtable entry
234  * @param key If non-NULL, returns the key associated with the entry.
235  * @param value If non-NULL, returns the value associated with the entry.
236  * @return ESR_INVALID_ARGUMENT if entry is null
237  */
238 PORTABLE_API ESR_ReturnCode PHashTableEntryGetKeyValue(PHashTableEntry *entry,
239     void **key,
240     void **value);
241 
242 /**
243  * Sets the value associated with this entry.
244  *
245  * @param entry The hashtable entry.
246  * @param value The value to associate with the entry.
247  * @param oldValue If this pointer is non-NULL, it will be set to the value
248  * previously associated with this entry.
249  */
250 PORTABLE_API ESR_ReturnCode PHashTableEntrySetValue(PHashTableEntry *entry,
251     const void *value,
252     void **oldValue);
253 
254 /**
255  * Removes the entry from its hash table.
256  *
257  * POST-CONDITION: 'entry' variable is invalid
258  *
259  * @param entry The hashtable entry.
260  * @return ESR_INVALID_ARGUMENT if entry is null
261  */
262 PORTABLE_API ESR_ReturnCode PHashTableEntryRemove(PHashTableEntry *entry);
263 
264 /**
265  * Resets the iterator at the beginning.
266  */
267 PORTABLE_API
268 ESR_ReturnCode PHashTableEntryGetFirst(PHashTable *table,
269                                        PHashTableEntry **entry);
270 
271 /**
272  * Advance to the next entry in the hash table.
273  *
274  * @param entry the current entry.
275  * @return ESR_INVALID_ARGUMENT if entry or the value it points to is null.
276  */
277 PORTABLE_API ESR_ReturnCode PHashTableEntryAdvance(PHashTableEntry** entry);
278 
279 /**
280  * @}
281  */
282 
283 #endif
284