ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/lookup.c
Revision: 1.1
Committed: Tue Jun 21 14:45:45 1994 UTC (29 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1994 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * Table lookup routines
9     */
10    
11     #include <stdio.h>
12     #include "lookup.h"
13    
14     #ifndef MEM_PTR
15     #define MEM_PTR void *
16     #endif
17    
18     extern MEM_PTR calloc();
19    
20    
21     int
22     lu_init(tbl, nel) /* initialize tbl for at least nel elements */
23     register LUTAB *tbl;
24     int nel;
25     {
26     static int hsiztab[] = {
27     31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 0
28     };
29     register int *hsp;
30    
31     nel += nel>>2; /* 75% occupancy */
32     for (hsp = hsiztab; *hsp; hsp++)
33     if (*hsp > nel)
34     break;
35     if (!(tbl->tsiz = *hsp))
36     tbl->tsiz = nel*2 + 1; /* not always prime */
37     tbl->tabl = (LUENT *)calloc(tbl->tsiz, sizeof(LUENT));
38     if (tbl->tabl == NULL)
39     tbl->tsiz = 0;
40     return(tbl->tsiz);
41     }
42    
43    
44     int
45     lu_hash(s) /* hash a nul-terminated string */
46     register char *s;
47     {
48     register int h = 0;
49    
50     while (*s)
51     h = (h<<1 & 0x7fff) ^ (*s++ & 0xff);
52     return(h);
53     }
54    
55    
56     LUENT *
57     lu_find(tbl, key) /* find a table entry */
58     register LUTAB *tbl;
59     char *key;
60     {
61     int hval, i;
62     register int ndx;
63     register LUENT *le;
64     LUENT *oldtabl;
65     /* look up object */
66     hval = lu_hash(key);
67     tryagain:
68     for (i = 0; i < tbl->tsiz; i++) {
69     ndx = (hval + i*i) % tbl->tsiz;
70     if (tbl->tabl[ndx].key == NULL ||
71     !strcmp(tbl->tabl[ndx].key, key))
72     return(&tbl->tabl[ndx]);
73     }
74     /* table is full, reallocate */
75     oldtabl = tbl->tabl;
76     ndx = tbl->tsiz;
77     if (!lu_init(tbl, ndx)) { /* no more memory! */
78     tbl->tabl = oldtabl;
79     tbl->tsiz = ndx;
80     return(NULL);
81     }
82     if (!ndx)
83     goto tryagain;
84     while (ndx--)
85     if (oldtabl[ndx].key != NULL) {
86     le = lu_find(tbl, oldtabl[ndx].key);
87     le->key = oldtabl[ndx].key;
88     le->data = oldtabl[ndx].data;
89     }
90     free((MEM_PTR)oldtabl);
91     goto tryagain; /* should happen only once! */
92     }
93    
94    
95     void
96     lu_done(tbl, f) /* free table and contents */
97     LUTAB *tbl;
98     int (*f)();
99     {
100     register LUENT *tp;
101    
102     if (!tbl->tsiz)
103     return;
104     if (f != NULL)
105     for (tp = tbl->tabl + tbl->tsiz; tp-- > tbl->tabl; )
106     if (tp->key != NULL)
107     (*f)(tp);
108     free((MEM_PTR)tbl->tabl);
109     tbl->tabl = NULL;
110     tbl->tsiz = 0;
111     }