abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
stmm.c
Go to the documentation of this file.
1 /*
2  * Revision Control Information
3  *
4  * /projects/hsis/CVS/utilities/st/st.c,v
5  * serdar
6  * 1.1
7  * 1993/07/29 01:00:13
8  *
9  */
10 #include <stdio.h>
11 #include "misc/extra/extra.h"
12 #include "stmm.h"
13 
15 
16 
17 #define STMM_NUMCMP(x,y) ((x) != (y))
18 #define STMM_NUMHASH(x,size) (Abc_AbsInt((long)x)%(size))
19 //#define STMM_PTRHASH(x,size) ((int)((ABC_PTRUINT_T)(x)>>2)%size) // 64-bit bug fix 9/17/2007
20 #define STMM_PTRHASH(x,size) ((int)(((ABC_PTRUINT_T)(x)>>2)%size))
21 #define EQUAL(func, x, y) \
22  ((((func) == stmm_numcmp) || ((func) == stmm_ptrcmp)) ?\
23  (STMM_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))
24 
25 
26 #define do_hash(key, table)\
27  ((table->hash == stmm_ptrhash) ? STMM_PTRHASH((key),(table)->num_bins) :\
28  (table->hash == stmm_numhash) ? STMM_NUMHASH((key), (table)->num_bins) :\
29  (*table->hash)((key), (table)->num_bins))
30 
31 static int rehash (stmm_table *table);
32 //int stmm_numhash (), stmm_ptrhash (), stmm_numcmp (), stmm_ptrcmp ();
33 
34 stmm_table *
35 stmm_init_table_with_params (stmm_compare_func_type compare, stmm_hash_func_type hash, int size, int density, double grow_factor, int reorder_flag)
36 {
37  int i;
38  stmm_table *newTable;
39 
40  newTable = ABC_ALLOC(stmm_table, 1);
41  if (newTable == NULL) {
42  return NULL;
43  }
44  newTable->compare = compare;
45  newTable->hash = hash;
46  newTable->num_entries = 0;
47  newTable->max_density = density;
48  newTable->grow_factor = grow_factor;
49  newTable->reorder_flag = reorder_flag;
50  if (size <= 0) {
51  size = 1;
52  }
53  newTable->num_bins = size;
54  newTable->bins = ABC_ALLOC(stmm_table_entry *, size);
55  if (newTable->bins == NULL) {
56  ABC_FREE(newTable);
57  return NULL;
58  }
59  for (i = 0; i < size; i++) {
60  newTable->bins[i] = 0;
61  }
62 
63  // added by alanmi
64  newTable->pMemMan = Extra_MmFixedStart(sizeof (stmm_table_entry));
65  return newTable;
66 }
67 
68 stmm_table *
70 {
71  return stmm_init_table_with_params (compare, hash,
76 }
77 
78 void
80 {
81 /*
82  stmm_table_entry *ptr, *next;
83  int i;
84  for ( i = 0; i < table->num_bins; i++ )
85  {
86  ptr = table->bins[i];
87  while ( ptr != NULL )
88  {
89  next = ptr->next;
90  ABC_FREE( ptr );
91  ptr = next;
92  }
93  }
94 */
95  // no need to deallocate entries because they are in the memory manager now
96  // added by alanmi
97  if ( table->pMemMan )
99  ABC_FREE(table->bins);
100  ABC_FREE(table);
101 }
102 
103 // this function recycles all the bins
104 void
106 {
107  int i;
108  // clean the bins
109  for (i = 0; i < table->num_bins; i++)
110  table->bins[i] = NULL;
111  // reset the parameters
112  table->num_entries = 0;
113  // restart the memory manager
115 }
116 
117 
118 #define PTR_NOT_EQUAL(table, ptr, user_key)\
119 (ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key))
120 
121 #define FIND_ENTRY(table, hash_val, key, ptr, last) \
122  (last) = &(table)->bins[hash_val];\
123  (ptr) = *(last);\
124  while (PTR_NOT_EQUAL((table), (ptr), (key))) {\
125  (last) = &(ptr)->next; (ptr) = *(last);\
126  }\
127  if ((ptr) != NULL && (table)->reorder_flag) {\
128  *(last) = (ptr)->next;\
129  (ptr)->next = (table)->bins[hash_val];\
130  (table)->bins[hash_val] = (ptr);\
131  }
132 
133 int
134 stmm_lookup (stmm_table *table, char *key, char **value)
135 {
136  int hash_val;
137  stmm_table_entry *ptr, **last;
138 
139  hash_val = do_hash (key, table);
140 
141  FIND_ENTRY (table, hash_val, key, ptr, last);
142 
143  if (ptr == NULL) {
144  return 0;
145  }
146  else {
147  if (value != NULL)
148  {
149  *value = ptr->record;
150  }
151  return 1;
152  }
153 }
154 
155 int
156 stmm_lookup_int (stmm_table *table, char *key, int *value)
157 {
158  int hash_val;
159  stmm_table_entry *ptr, **last;
160 
161  hash_val = do_hash (key, table);
162 
163  FIND_ENTRY (table, hash_val, key, ptr, last);
164 
165  if (ptr == NULL) {
166  return 0;
167  }
168  else {
169  if (value != 0)
170  {
171  *value = (long) ptr->record;
172  }
173  return 1;
174  }
175 }
176 
177 // This macro contained a line
178 // new = ABC_ALLOC(stmm_table_entry, 1);
179 // which was modified by alanmi
180 
181 
182 /* This macro does not check if memory allocation fails. Use at you own risk */
183 #define ADD_DIRECT(table, key, value, hash_val, new)\
184 {\
185  if (table->num_entries/table->num_bins >= table->max_density) {\
186  rehash(table);\
187  hash_val = do_hash(key,table);\
188  }\
189  \
190  new = (stmm_table_entry *)Extra_MmFixedEntryFetch( (Extra_MmFixed_t *)table->pMemMan );\
191  \
192  new->key = key;\
193  new->record = value;\
194  new->next = table->bins[hash_val];\
195  table->bins[hash_val] = new;\
196  table->num_entries++;\
197 }
198 
199 int
200 stmm_insert (stmm_table *table, char *key, char *value)
201 {
202  int hash_val;
203  stmm_table_entry *newEntry;
204  stmm_table_entry *ptr, **last;
205 
206  hash_val = do_hash (key, table);
207 
208  FIND_ENTRY (table, hash_val, key, ptr, last);
209 
210  if (ptr == NULL) {
211  if (table->num_entries / table->num_bins >= table->max_density) {
212  if (rehash (table) == STMM_OUT_OF_MEM) {
213  return STMM_OUT_OF_MEM;
214  }
215  hash_val = do_hash (key, table);
216  }
217 
218 // newEntry = ABC_ALLOC( stmm_table_entry, 1 );
220  if (newEntry == NULL) {
221  return STMM_OUT_OF_MEM;
222  }
223 
224  newEntry->key = key;
225  newEntry->record = value;
226  newEntry->next = table->bins[hash_val];
227  table->bins[hash_val] = newEntry;
228  table->num_entries++;
229  return 0;
230  }
231  else {
232  ptr->record = value;
233  return 1;
234  }
235 }
236 
237 int
238 stmm_add_direct (stmm_table *table, char *key, char *value)
239 {
240  int hash_val;
241  stmm_table_entry *newEntry;
242 
243  hash_val = do_hash (key, table);
244  if (table->num_entries / table->num_bins >= table->max_density) {
245  if (rehash (table) == STMM_OUT_OF_MEM) {
246  return STMM_OUT_OF_MEM;
247  }
248  }
249  hash_val = do_hash (key, table);
250 
251 // newEntry = ABC_ALLOC( stmm_table_entry, 1 );
253  if (newEntry == NULL) {
254  return STMM_OUT_OF_MEM;
255  }
256 
257  newEntry->key = key;
258  newEntry->record = value;
259  newEntry->next = table->bins[hash_val];
260  table->bins[hash_val] = newEntry;
261  table->num_entries++;
262  return 1;
263 }
264 
265 int
266 stmm_find_or_add (stmm_table *table, char *key, char ***slot)
267 {
268  int hash_val;
269  stmm_table_entry *newEntry, *ptr, **last;
270 
271  hash_val = do_hash (key, table);
272 
273  FIND_ENTRY (table, hash_val, key, ptr, last);
274 
275  if (ptr == NULL) {
276  if (table->num_entries / table->num_bins >= table->max_density) {
277  if (rehash (table) == STMM_OUT_OF_MEM) {
278  return STMM_OUT_OF_MEM;
279  }
280  hash_val = do_hash (key, table);
281  }
282 
283  // newEntry = ABC_ALLOC( stmm_table_entry, 1 );
285  if (newEntry == NULL) {
286  return STMM_OUT_OF_MEM;
287  }
288 
289  newEntry->key = key;
290  newEntry->record = (char *) 0;
291  newEntry->next = table->bins[hash_val];
292  table->bins[hash_val] = newEntry;
293  table->num_entries++;
294  if (slot != NULL)
295  *slot = &newEntry->record;
296  return 0;
297  }
298  else {
299  if (slot != NULL)
300  *slot = &ptr->record;
301  return 1;
302  }
303 }
304 
305 int
306 stmm_find (stmm_table *table, char *key, char ***slot)
307 {
308  int hash_val;
309  stmm_table_entry *ptr, **last;
310 
311  hash_val = do_hash (key, table);
312 
313  FIND_ENTRY (table, hash_val, key, ptr, last);
314 
315  if (ptr == NULL) {
316  return 0;
317  }
318  else {
319  if (slot != NULL)
320  {
321  *slot = &ptr->record;
322  }
323  return 1;
324  }
325 }
326 
327 static int
329 {
330  stmm_table_entry *ptr, *next, **old_bins;
331  int i, old_num_bins, hash_val, old_num_entries;
332 
333  /* save old values */
334  old_bins = table->bins;
335  old_num_bins = table->num_bins;
336  old_num_entries = table->num_entries;
337 
338  /* rehash */
339  table->num_bins = (int) (table->grow_factor * old_num_bins);
340  if (table->num_bins % 2 == 0) {
341  table->num_bins += 1;
342  }
343  table->num_entries = 0;
344  table->bins = ABC_ALLOC(stmm_table_entry *, table->num_bins);
345  if (table->bins == NULL) {
346  table->bins = old_bins;
347  table->num_bins = old_num_bins;
348  table->num_entries = old_num_entries;
349  return STMM_OUT_OF_MEM;
350  }
351  /* initialize */
352  for (i = 0; i < table->num_bins; i++) {
353  table->bins[i] = 0;
354  }
355 
356  /* copy data over */
357  for (i = 0; i < old_num_bins; i++) {
358  ptr = old_bins[i];
359  while (ptr != NULL) {
360  next = ptr->next;
361  hash_val = do_hash (ptr->key, table);
362  ptr->next = table->bins[hash_val];
363  table->bins[hash_val] = ptr;
364  table->num_entries++;
365  ptr = next;
366  }
367  }
368  ABC_FREE(old_bins);
369 
370  return 1;
371 }
372 
373 stmm_table *
374 stmm_copy (stmm_table *old_table)
375 {
376  stmm_table *newEntry_table;
377  stmm_table_entry *ptr, /* *newEntryptr, *next, */ *newEntry;
378  int i, /*j, */ num_bins = old_table->num_bins;
379 
380  newEntry_table = ABC_ALLOC(stmm_table, 1);
381  if (newEntry_table == NULL) {
382  return NULL;
383  }
384 
385  *newEntry_table = *old_table;
386  newEntry_table->bins = ABC_ALLOC(stmm_table_entry *, num_bins);
387  if (newEntry_table->bins == NULL) {
388  ABC_FREE(newEntry_table);
389  return NULL;
390  }
391 
392  // allocate the memory manager for the newEntry table
393  newEntry_table->pMemMan = Extra_MmFixedStart (sizeof (stmm_table_entry));
394 
395  for (i = 0; i < num_bins; i++) {
396  newEntry_table->bins[i] = NULL;
397  ptr = old_table->bins[i];
398  while (ptr != NULL) {
399 // newEntry = ABC_ALLOC( stmm_table_entry, 1 );
400  newEntry = (stmm_table_entry *)Extra_MmFixedEntryFetch ((Extra_MmFixed_t *)newEntry_table->pMemMan);
401  if (newEntry == NULL) {
402 /*
403  for ( j = 0; j <= i; j++ )
404  {
405  newEntryptr = newEntry_table->bins[j];
406  while ( newEntryptr != NULL )
407  {
408  next = newEntryptr->next;
409  ABC_FREE( newEntryptr );
410  newEntryptr = next;
411  }
412  }
413 */
414  Extra_MmFixedStop ((Extra_MmFixed_t *)newEntry_table->pMemMan);
415 
416  ABC_FREE(newEntry_table->bins);
417  ABC_FREE(newEntry_table);
418  return NULL;
419  }
420  *newEntry = *ptr;
421  newEntry->next = newEntry_table->bins[i];
422  newEntry_table->bins[i] = newEntry;
423  ptr = ptr->next;
424  }
425  }
426  return newEntry_table;
427 }
428 
429 int
430 stmm_delete (stmm_table *table, char **keyp, char **value)
431 {
432  int hash_val;
433  char *key = *keyp;
434  stmm_table_entry *ptr, **last;
435 
436  hash_val = do_hash (key, table);
437 
438  FIND_ENTRY (table, hash_val, key, ptr, last);
439 
440  if (ptr == NULL) {
441  return 0;
442  }
443 
444  *last = ptr->next;
445  if (value != NULL)
446  *value = ptr->record;
447  *keyp = ptr->key;
448 // ABC_FREE( ptr );
449  Extra_MmFixedEntryRecycle ((Extra_MmFixed_t *)table->pMemMan, (char *) ptr);
450 
451  table->num_entries--;
452  return 1;
453 }
454 
455 int
456 stmm_delete_int (stmm_table *table, long *keyp, char **value)
457 {
458  int hash_val;
459  char *key = (char *) *keyp;
460  stmm_table_entry *ptr, **last;
461 
462  hash_val = do_hash (key, table);
463 
464  FIND_ENTRY (table, hash_val, key, ptr, last);
465 
466  if (ptr == NULL) {
467  return 0;
468  }
469 
470  *last = ptr->next;
471  if (value != NULL)
472  *value = ptr->record;
473  *keyp = (long) ptr->key;
474 // ABC_FREE( ptr );
475  Extra_MmFixedEntryRecycle ((Extra_MmFixed_t *)table->pMemMan, (char *) ptr);
476 
477  table->num_entries--;
478  return 1;
479 }
480 
481 int
482 stmm_foreach (stmm_table *table, enum stmm_retval (*func) (char *, char *, char *), char *arg)
483 {
484  stmm_table_entry *ptr, **last;
485  enum stmm_retval retval;
486  int i;
487 
488  for (i = 0; i < table->num_bins; i++) {
489  last = &table->bins[i];
490  ptr = *last;
491  while (ptr != NULL) {
492  retval = (*func) (ptr->key, ptr->record, arg);
493  switch (retval) {
494  case STMM_CONTINUE:
495  last = &ptr->next;
496  ptr = *last;
497  break;
498  case STMM_STOP:
499  return 0;
500  case STMM_DELETE:
501  *last = ptr->next;
502  table->num_entries--; /* cstevens@ic */
503 // ABC_FREE( ptr );
504  Extra_MmFixedEntryRecycle ((Extra_MmFixed_t *)table->pMemMan, (char *) ptr);
505 
506  ptr = *last;
507  }
508  }
509  }
510  return 1;
511 }
512 
513 int
514 stmm_strhash (const char *string, int modulus)
515 {
516  int val = 0;
517  int c;
518 
519  while ((c = *string++) != '\0') {
520  val = val * 997 + c;
521  }
522 
523  return ((val < 0) ? -val : val) % modulus;
524 }
525 
526 int
527 stmm_numhash (const char *x, int size)
528 {
529  return STMM_NUMHASH (x, size);
530 }
531 
532 int
533 stmm_ptrhash (const char *x, int size)
534 {
535  return STMM_PTRHASH (x, size);
536 }
537 
538 int
539 stmm_numcmp (const char *x, const char *y)
540 {
541  return STMM_NUMCMP (x, y);
542 }
543 
544 int
545 stmm_ptrcmp (const char *x, const char *y)
546 {
547  return STMM_NUMCMP (x, y);
548 }
549 
552 {
553  stmm_generator *gen;
554 
555  gen = ABC_ALLOC(stmm_generator, 1);
556  if (gen == NULL) {
557  return NULL;
558  }
559  gen->table = table;
560  gen->entry = NULL;
561  gen->index = 0;
562  return gen;
563 }
564 
565 
566 int
567 stmm_gen (stmm_generator *gen, char **key_p, char **value_p)
568 {
569  int i;
570 
571  if (gen->entry == NULL) {
572  /* try to find next entry */
573  for (i = gen->index; i < gen->table->num_bins; i++) {
574  if (gen->table->bins[i] != NULL) {
575  gen->index = i + 1;
576  gen->entry = gen->table->bins[i];
577  break;
578  }
579  }
580  if (gen->entry == NULL) {
581  return 0; /* that's all folks ! */
582  }
583  }
584  *key_p = gen->entry->key;
585  if (value_p != 0) {
586  *value_p = gen->entry->record;
587  }
588  gen->entry = gen->entry->next;
589  return 1;
590 }
591 
592 
593 int
594 stmm_gen_int (stmm_generator *gen, char **key_p, long *value_p)
595 {
596  int i;
597 
598  if (gen->entry == NULL) {
599  /* try to find next entry */
600  for (i = gen->index; i < gen->table->num_bins; i++) {
601  if (gen->table->bins[i] != NULL) {
602  gen->index = i + 1;
603  gen->entry = gen->table->bins[i];
604  break;
605  }
606  }
607  if (gen->entry == NULL) {
608  return 0; /* that's all folks ! */
609  }
610  }
611  *key_p = gen->entry->key;
612  if (value_p != 0)
613  {
614  *value_p = (long) gen->entry->record;
615  }
616  gen->entry = gen->entry->next;
617  return 1;
618 }
619 
620 
621 void
623 {
624  ABC_FREE(gen);
625 }
627 
#define STMM_DEFAULT_REORDER_FLAG
Definition: stmm.h:114
static int rehash(stmm_table *table)
Definition: stmm.c:328
char * key
Definition: stmm.h:48
int stmm_foreach(stmm_table *table, enum stmm_retval(*func)(char *, char *, char *), char *arg)
Definition: stmm.c:482
stmm_table * stmm_init_table(stmm_compare_func_type compare, stmm_hash_func_type hash)
Definition: stmm.c:69
#define STMM_NUMHASH(x, size)
Definition: stmm.c:18
Definition: stmm.h:79
stmm_compare_func_type compare
Definition: stmm.h:55
stmm_retval
Definition: stmm.h:78
int num_bins
Definition: stmm.h:57
int(* stmm_hash_func_type)(const char *, int)
Definition: stmm.h:40
int stmm_insert(stmm_table *table, char *key, char *value)
Definition: stmm.c:200
void Extra_MmFixedStop(Extra_MmFixed_t *p)
int stmm_lookup_int(stmm_table *table, char *key, int *value)
Definition: stmm.c:156
#define STMM_OUT_OF_MEM
Definition: stmm.h:127
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
stmm_table_entry ** bins
Definition: stmm.h:62
char * Extra_MmFixedEntryFetch(Extra_MmFixed_t *p)
int reorder_flag
Definition: stmm.h:60
stmm_table * stmm_init_table_with_params(stmm_compare_func_type compare, stmm_hash_func_type hash, int size, int density, double grow_factor, int reorder_flag)
Definition: stmm.c:35
int stmm_gen_int(stmm_generator *gen, char **key_p, long *value_p)
Definition: stmm.c:594
int stmm_numcmp(const char *x, const char *y)
Definition: stmm.c:539
int index
Definition: stmm.h:72
void stmm_clean(stmm_table *table)
Definition: stmm.c:105
int stmm_lookup(stmm_table *table, char *key, char **value)
Definition: stmm.c:134
int stmm_ptrhash(const char *x, int size)
Definition: stmm.c:533
#define FIND_ENTRY(table, hash_val, key, ptr, last)
Definition: stmm.c:121
void stmm_free_gen(stmm_generator *gen)
Definition: stmm.c:622
Extra_MmFixed_t * Extra_MmFixedStart(int nEntrySize)
char * record
Definition: stmm.h:49
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define STMM_DEFAULT_GROW_FACTOR
Definition: stmm.h:113
static uint32_t hash(uint32_t x)
Definition: Map.h:38
#define STMM_PTRHASH(x, size)
Definition: stmm.c:20
static int size
Definition: cuddSign.c:86
Definition: stmm.h:46
#define STMM_DEFAULT_INIT_TABLE_SIZE
Definition: stmm.h:112
#define do_hash(key, table)
Definition: stmm.c:26
void Extra_MmFixedRestart(Extra_MmFixed_t *p)
int stmm_find_or_add(stmm_table *table, char *key, char ***slot)
Definition: stmm.c:266
stmm_hash_func_type hash
Definition: stmm.h:56
int num_entries
Definition: stmm.h:58
int stmm_strhash(const char *string, int modulus)
Definition: stmm.c:514
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int stmm_ptrcmp(const char *x, const char *y)
Definition: stmm.c:545
void stmm_free_table(stmm_table *table)
Definition: stmm.c:79
int(* stmm_compare_func_type)(const char *, const char *)
Definition: stmm.h:39
stmm_table_entry * next
Definition: stmm.h:50
stmm_table_entry * entry
Definition: stmm.h:71
int stmm_numhash(const char *x, int size)
Definition: stmm.c:527
int stmm_gen(stmm_generator *gen, char **key_p, char **value_p)
Definition: stmm.c:567
#define ABC_FREE(obj)
Definition: abc_global.h:232
enum keys key
int stmm_delete_int(stmm_table *table, long *keyp, char **value)
Definition: stmm.c:456
stmm_table * table
Definition: stmm.h:70
int stmm_add_direct(stmm_table *table, char *key, char *value)
Definition: stmm.c:238
int max_density
Definition: stmm.h:59
int stmm_delete(stmm_table *table, char **keyp, char **value)
Definition: stmm.c:430
double grow_factor
Definition: stmm.h:61
int value
#define STMM_DEFAULT_MAX_DENSITY
Definition: stmm.h:111
stmm_table * stmm_copy(stmm_table *old_table)
Definition: stmm.c:374
void Extra_MmFixedEntryRecycle(Extra_MmFixed_t *p, char *pEntry)
#define STMM_NUMCMP(x, y)
Definition: stmm.c:17
int stmm_find(stmm_table *table, char *key, char ***slot)
Definition: stmm.c:306
void * pMemMan
Definition: stmm.h:65
stmm_generator * stmm_init_gen(stmm_table *table)
Definition: stmm.c:551