CARMA C++
hash.h
1 #ifndef hash_h
2 #define hash_h
3 
4 #include "carma/szaarrayutils/freelist.h"
5 #include "carma/szaarrayutils/stringmem.h"
6 
7 /*
8  * The following macro can be used to prototype or define a
9  * function that deletes the data of a symbol-table entry.
10  *
11  * Input:
12  * app_data void * The new_HashTable() app_data argument.
13  * code int The Symbol::code argument.
14  * sym_data void * The Symbol::data argument to be deleted.
15  * Output:
16  * return void * The deleted data (always return NULL).
17  */
18 #define SYM_DEL_FN(fn) void *(fn)(void *app_data, int code, void *sym_data)
19 
20 /*
21  * The following macro can be used to prototype or define a
22  * function that deletes the application-data of a hash-table.
23  *
24  * Input:
25  * data void * The new_HashTable() 'app_data' argument to be
26  * deleted.
27  * Output:
28  * return void * The deleted data (always return NULL).
29  */
30 #define HASH_DEL_FN(fn) void *(fn)(void *app_data)
31 
32 /*
33  * The following is a container for recording the context
34  * of a symbol in a manner that is independant of the particular
35  * symbol-table implementation. Each hash-table entry contains
36  * the following user supplied parameters:
37  *
38  * 1. An optional integral parameter 'code'. This is useful for
39  * enumerating a symbol or for describing what type of data
40  * or function is stored in the symbol.
41  *
42  * 2. An optional generic function pointer. This is useful for
43  * associating functions with names. The user is responsible
44  * for casting between the generic function type and the
45  * actual function type. The code field could be used to
46  * enumerate what type of function to cast to.
47  *
48  * 3. An optional generic pointer to a static or heap-allocated
49  * object. It is up to the user to cast this back to the
50  * appropriate object type. Again, the code field could be used
51  * to describe what type of object is stored there.
52  * If the object is dynamically allocated and should be discarded
53  * when the symbol is deleted from the symbol table, send a
54  * destructor function to have it deleted automatically.
55  */
56 typedef struct {
57  char *name; /* The name of the symbol */
58  int code; /* Application supplied integral code */
59  void (*fn)(void); /* Application supplied generic function */
60  void *data; /* Application supplied context data */
61  SYM_DEL_FN(*del_fn); /* Data destructor function */
62 } Symbol;
63 
64 /*
65  * HashNode's and HashTable's are small objects. Separately allocating
66  * many such objects would normally cause memory fragmentation. To
67  * counter this, HashMemory objects are used. These contain
68  * dedicated free-lists formed from large dynamically allocated arrays
69  * of objects. One HashMemory object can be shared between multiple hash
70  * tables (within a single thread).
71  */
72 /*
73  * The following container object contains free-lists to be used
74  * for allocation of HashTable containers and nodes.
75  */
76 struct HashMemory {
77  FreeList *hash_memory; /* HashTable free-list */
78  FreeList *node_memory; /* HashNode free-list */
79  StringMem *string_memory; /* Memory used to allocate hash strings */
80 };
81 
82  /* Create a free-list for allocation of hash tables and their nodes */
83 
84 HashMemory *new_HashMemory(int hash_count, int node_count);
85 
86  /* Delete a redundant free-list if not being used */
87 
88 HashMemory *del_HashMemory(HashMemory *mem, int force);
89 
90 /*
91  * Display the number of active hash-tables and hash nodes that are
92  * currently allocated from a given freelist
93  */
94 void show_HashMemory(HashMemory *mem);
95 
96 /*
97  * Define a hash symbol-table entry.
98  * See symbol.h for the definition of the Symbol container type.
99  */
100 typedef struct HashNode HashNode;
101 struct HashNode {
102  Symbol symbol; /* The symbol stored in the hash-entry */
103  HashNode *next; /* The next hash-table entry in a bucket list */
104 };
105 
106 /*
107  * Each hash-table bucket contains a linked list of entries that
108  * hash to the same bucket.
109  */
110 typedef struct {
111  HashNode *head; /* The head of the bucket hash-node list */
112  int count; /* The number of entries in the list */
113 } HashBucket;
114 
115 /*
116  * A hash-table consists of 'size' hash buckets.
117  * Note that the HashTable typedef for this struct is contained in hash.h.
118  */
119 struct HashTable {
120  unsigned ref; /* The reference count of the table */
121  HashMemory *mem; /* HashTable free-list */
122  int internal_mem; /* True if 'mem' was allocated by new_HashTable() */
123  int case_sensitive; /* True if case is significant in lookup keys */
124  int size; /* The number of hash buckets */
125  HashBucket *bucket; /* An array of 'size' hash buckets */
126  int (*keycmp)(const char *, const char *); /* Key comparison function */
127  void *app_data; /* Application-provided data */
128  HASH_DEL_FN(*del_fn); /* Application-provided 'app_data' destructor */
129 };
130 
131 /*
132  * Enumerate case-sensitivity options.
133  */
134 typedef enum {
135  IGNORE_CASE, /* Ignore case when looking up symbols */
136  HONOUR_CASE /* Honor case when looking up symbols */
137 } HashCase;
138 
139  /* Create a new hash-table */
140 
141 HashTable *new_HashTable(HashMemory *mem, int size, HashCase hcase,
142  void *app_data, HASH_DEL_FN(*del_fn));
143 
144  /* Increment the reference count of a list to prevent untimely deletion */
145 
146 HashTable *ref_HashTable(HashTable *hash);
147 
148  /* Delete a reference to a hash-table */
149 
150 HashTable *del_HashTable(HashTable *hash);
151 
152  /* Add an entry to a hash table */
153 
154 Symbol *new_HashSymbol(HashTable *hash, char *key, int code, void (*fn)(void),
155  void *data, SYM_DEL_FN(*del_fn));
156 
157  /* Remove and delete all the entries in a given hash table */
158 
159 int clear_HashTable(HashTable *hash);
160 
161  /* Remove and delete a given hash-table entry */
162 
163 Symbol *del_HashSymbol(HashTable *hash, char *key);
164 
165  /* Lookup a given hash-table entry */
166 
167 Symbol *find_HashSymbol(HashTable *hash, char *key);
168 
169  /* Display the contents of a hash table to standard output */
170 
171 void show_HashTable(HashTable *hash, int summarize);
172 
173  /* Execute a given function on each entry of a hash table, returning */
174  /* before completion if the specified function returns non-zero. */
175 
176 #define HASH_SCAN_FN(fn) int (fn)(Symbol *sym, void *context)
177 
178 int scan_HashTable(HashTable *hash, HASH_SCAN_FN(*scan_fn), void *context);
179 
180 #endif