ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/modobject.c
Revision: 2.13
Committed: Sat Mar 9 18:53:05 2013 UTC (11 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +35 -27 lines
Log Message:
Slight efficiency improvement and ansification

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: modobject.c,v 2.12 2004/07/14 02:37:23 greg Exp $";
3 #endif
4 /*
5 * Routines for tracking object modifiers
6 *
7 * External symbols declared in object.h
8 */
9
10 #include "copyright.h"
11
12 #include "standard.h"
13
14 #include "object.h"
15
16 #include "otypes.h"
17
18
19 static struct ohtab {
20 int hsiz; /* current table size */
21 OBJECT *htab; /* table, if allocated */
22 } modtab = {100, NULL}, objtab = {1000, NULL}; /* modifiers and objects */
23
24 static int otndx(char *, struct ohtab *);
25
26
27 OBJECT
28 objndx( /* get object number from pointer */
29 OBJREC *op
30 )
31 {
32 int i, j;
33
34 for (i = nobjects>>OBJBLKSHFT; i >= 0; i--) {
35 j = op - objblock[i];
36 if ((j >= 0) & (j < OBJBLKSIZ))
37 return((i<<OBJBLKSHFT) + j);
38 }
39 return(OVOID);
40 }
41
42
43 OBJECT
44 lastmod( /* find modifier definition before obj */
45 OBJECT obj,
46 char *mname
47 )
48 {
49 OBJREC *op;
50 int i;
51
52 i = modifier(mname); /* try hash table first */
53 if ((obj == OVOID) | (i < obj))
54 return(i);
55 for (i = obj; i-- > 0; ) { /* need to search */
56 op = objptr(i);
57 if (ismodifier(op->otype) && op->oname[0] == mname[0] &&
58 !strcmp(op->oname, mname))
59 return(i);
60 }
61 return(OVOID);
62 }
63
64
65 OBJECT
66 modifier( /* get a modifier number from its name */
67 char *mname
68 )
69 {
70 int ndx;
71
72 ndx = otndx(mname, &modtab);
73 return(modtab.htab[ndx]);
74 }
75
76
77 #ifdef GETOBJ
78 OBJECT
79 object( /* get an object number from its name */
80 char *oname
81 )
82 {
83 int ndx;
84
85 ndx = otndx(oname, &objtab);
86 return(objtab.htab[ndx]);
87 }
88 #endif
89
90
91 void
92 insertobject( /* insert new object into our list */
93 OBJECT obj
94 )
95 {
96 int i;
97
98 if (ismodifier(objptr(obj)->otype)) {
99 i = otndx(objptr(obj)->oname, &modtab);
100 modtab.htab[i] = obj;
101 }
102 #ifdef GETOBJ
103 else {
104 i = otndx(objptr(obj)->oname, &objtab);
105 objtab.htab[i] = obj;
106 }
107 #endif
108 for (i = 0; addobjnotify[i] != NULL; i++)
109 (*addobjnotify[i])(obj);
110 }
111
112
113 void
114 clearobjndx(void) /* clear object hash tables */
115 {
116 if (modtab.htab != NULL) {
117 free((void *)modtab.htab);
118 modtab.htab = NULL;
119 modtab.hsiz = 100;
120 }
121 if (objtab.htab != NULL) {
122 free((void *)objtab.htab);
123 objtab.htab = NULL;
124 objtab.hsiz = 100;
125 }
126 }
127
128
129 static int
130 nexthsiz( /* return next hash table size */
131 int oldsiz
132 )
133 {
134 static int hsiztab[] = {
135 251, 509, 1021, 2039, 4093, 8191, 16381, 0
136 };
137 int *hsp;
138
139 for (hsp = hsiztab; *hsp; hsp++)
140 if (*hsp > oldsiz)
141 return(*hsp);
142 return(oldsiz*2 + 1); /* not always prime */
143 }
144
145
146 static int
147 otndx( /* get object table index for name */
148 char *name,
149 struct ohtab *tab
150 )
151 {
152 OBJECT *oldhtab;
153 int hval, i;
154 int ndx;
155
156 if (tab->htab == NULL) { /* new table */
157 tab->hsiz = nexthsiz(tab->hsiz);
158 tab->htab = (OBJECT *)malloc(tab->hsiz*sizeof(OBJECT));
159 if (tab->htab == NULL)
160 error(SYSTEM, "out of memory in otndx");
161 ndx = tab->hsiz;
162 while (ndx--) /* empty it */
163 tab->htab[ndx] = OVOID;
164 }
165 /* look up object */
166 hval = shash(name);
167 tryagain:
168 for (i = 0; i < tab->hsiz; i++) {
169 ndx = (hval + (unsigned long)i*i) % tab->hsiz;
170 if (tab->htab[ndx] == OVOID ||
171 !strcmp(objptr(tab->htab[ndx])->oname, name))
172 return(ndx);
173 }
174 /* table is full, reallocate */
175 oldhtab = tab->htab;
176 ndx = tab->hsiz;
177 tab->htab = NULL;
178 while (ndx--)
179 if (oldhtab[ndx] != OVOID) {
180 i = otndx(objptr(oldhtab[ndx])->oname, tab);
181 tab->htab[i] = oldhtab[ndx];
182 }
183 free((void *)oldhtab);
184 goto tryagain; /* should happen only once! */
185 }