ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/lookup.c
Revision: 1.3
Committed: Thu Jun 23 08:48:28 1994 UTC (29 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +6 -1 lines
Log Message:
change in comment

File Contents

# Content
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>>1; /* 66% 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 tbl->ndel = 0;
41 return(tbl->tsiz);
42 }
43
44
45 int
46 lu_hash(s) /* hash a nul-terminated string */
47 register char *s;
48 {
49 register int h = 0;
50
51 while (*s)
52 h = (h<<1 & 0x7fff) ^ (*s++ & 0xff);
53 return(h);
54 }
55
56
57 LUENT *
58 lu_find(tbl, key) /* find a table entry */
59 register LUTAB *tbl;
60 char *key;
61 {
62 int hval, i;
63 register int ndx;
64 register 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 i = tbl->ndel;
78 if (!lu_init(tbl, ndx-i)) { /* no more memory! */
79 tbl->tabl = oldtabl;
80 tbl->tsiz = ndx;
81 tbl->ndel = i;
82 return(NULL);
83 }
84 if (!ndx)
85 goto tryagain;
86 /*
87 * The following code may fail if the user has reclaimed many
88 * deleted entries and the system runs out of memory in a
89 * recursive call to lu_find().
90 */
91 while (ndx--)
92 if (oldtabl[ndx].key != NULL)
93 if (oldtabl[ndx].data != NULL)
94 *lu_find(tbl, oldtabl[ndx].key) = oldtabl[ndx];
95 else if (tbl->freek != NULL)
96 (*tbl->freek)(oldtabl[ndx].key);
97 free((MEM_PTR)oldtabl);
98 goto tryagain; /* should happen only once! */
99 }
100
101
102 void
103 lu_delete(tbl, key) /* delete a table entry */
104 register LUTAB *tbl;
105 char *key;
106 {
107 register LUENT *le;
108
109 if ((le = lu_find(tbl, key)) == NULL)
110 return;
111 if (le->key == NULL || le->data == NULL)
112 return;
113 if (tbl->freed != NULL)
114 (*tbl->freed)(le->data);
115 le->data = NULL;
116 tbl->ndel++;
117 }
118
119
120 void
121 lu_done(tbl) /* free table and contents */
122 register LUTAB *tbl;
123 {
124 register LUENT *tp;
125
126 if (!tbl->tsiz)
127 return;
128 for (tp = tbl->tabl + tbl->tsiz; tp-- > tbl->tabl; )
129 if (tp->key != NULL) {
130 if (tbl->freek != NULL)
131 (*tbl->freek)(tp->key);
132 if (tp->data != NULL && tbl->freed != NULL)
133 (*tbl->freed)(tp->data);
134 }
135 free((MEM_PTR)tbl->tabl);
136 tbl->tabl = NULL;
137 tbl->tsiz = 0;
138 tbl->ndel = 0;
139 }