ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/src/common/modobject.c
(Generate patch)

Comparing src/common/modobject.c (file contents):
Revision 2.14 by greg, Sun Dec 8 18:59:53 2013 UTC vs.
Revision 2.26 by greg, Sun Jun 22 17:21:37 2025 UTC

# Line 10 | Line 10 | static const char RCSid[] = "$Id$";
10   #include "copyright.h"
11  
12   #include  "standard.h"
13
13   #include  "object.h"
15
14   #include  "otypes.h"
15  
16  
17   static struct ohtab {
18 <        int  hsiz;                      /* current table size */
19 <        OBJECT  *htab;                  /* table, if allocated */
18 >        int     hsiz;                   /* current table size */
19 >        OBJECT  *htab;                  /* table, if allocated */
20   }  modtab = {100, NULL}, objtab = {1000, NULL}; /* modifiers and objects */
21  
22   static int  otndx(char *, struct ohtab *);
# Line 29 | Line 27 | objndx(                                /* get object number from pointer */
27          OBJREC  *op
28   )
29   {
30 <        int  i, j;
30 > #ifndef ONCACHESIZ
31 > #define ONCACHESIZ      907     /* keep a cache of previous searches */
32 > #endif
33 >        static OBJECT   oncache[ONCACHESIZ];
34 >        const int       ent = (size_t)op % ONCACHESIZ;  /* hash on pointer */
35 >        int             i, lastblock;
36  
37 <        for (i = nobjects>>OBJBLKSHFT; i >= 0; i--) {
38 <                j = op - objblock[i];
39 <                if ((j >= 0) & (j < OBJBLKSIZ))
40 <                        return((i<<OBJBLKSHFT) + j);
41 <        }
42 <        return(OVOID);
37 > #if OVOID != 0                  /* clear cache on first call */
38 >        for (i = ONCACHESIZ*(!oncache[0] & !oncache[1]); i--; )
39 >                oncache[i] = OVOID;
40 > #endif
41 >                                /* is this pointer in cache? */
42 >        if ((oncache[ent] != OVOID) & (oncache[ent] < nobjects) &&
43 >                                objptr(oncache[ent]) == op)
44 >                return(oncache[ent]);           /* matches previous search */
45 >                                /* else search for our block from first */
46 >        lastblock = (nobjects-1)>>OBJBLKSHFT;
47 >        for (i = 0; i <= lastblock; i++)
48 >                if ((objblock[i] <= op) & (op < objblock[i]+OBJBLKSIZ)) {
49 >                                /* found it -- cache corresponding index */
50 >                        oncache[ent] = ((OBJECT)i << OBJBLKSHFT) +
51 >                                                (op - objblock[i]);
52 >                        return(oncache[ent]);
53 >                }
54 >        return(OVOID);          /* not allocated -- may still be valid */
55   }
56  
57  
# Line 47 | Line 62 | lastmod(                       /* find modifier definition before obj */
62   )
63   {
64          OBJREC  *op;
65 <        int  i;
65 >        OBJECT  i;
66  
67          i = modifier(mname);            /* try hash table first */
68          if ((obj == OVOID) | (i < obj))
69                  return(i);
70          for (i = obj; i-- > 0; ) {      /* need to search */
71                  op = objptr(i);
72 <                if (ismodifier(op->otype) && op->oname[0] == mname[0] &&
73 <                                        !strcmp(op->oname, mname))
72 >                if ((ismodifier(op->otype) != 0) & (op->oname[0] == mname[0])
73 >                                && !strcmp(op->oname, mname))
74                          return(i);
75          }
76          return(OVOID);
# Line 88 | Line 103 | object(                                /* get an object number from its name */
103   #endif
104  
105  
106 < static int
106 > int
107   eqreal(                         /* are two real values close enough to equal? */
108          double  d1,
109          double  d2
# Line 107 | Line 122 | eqobjects(                     /* check if two objects are equal */
122   )
123   {
124          OBJREC  *op1, *op2;
125 <        int     i;
125 >        int     i, n;
126  
127 <        if (obj1 == OVOID)
128 <                return(obj2 == OVOID);
114 <        if (obj2 == OVOID)
115 <                return(0);
116 <        op1 = objptr(obj1);
117 <        op2 = objptr(obj2);
118 <        if (op1->omod != op2->omod)
119 <                return(0);
120 <        if (op1->otype != op2->otype)
121 <                return(0);
122 <        if (strcmp(op1->oname, op2->oname))
123 <                return(0);
124 <        if (op1->oargs.nsargs != op2->oargs.nsargs)
125 <                return(0);
126 <        if (op1->oargs.nfargs != op2->oargs.nfargs)
127 <                return(0);
128 < #ifdef IARGS
129 <        if (op1->oargs.niargs != op2->oargs.niargs)
130 <                return(0);
131 <        for (i = op1->oargs.niargs; i-- > 0; )
132 <                if (op1->oargs.iarg[i] != op2->oargs.iarg[i])
127 >        while (obj1 != obj2) {
128 >                if (obj1 == OVOID)
129                          return(0);
130 < #endif
135 <        for (i = op1->oargs.nfargs; i-- > 0; )
136 <                if (!eqreal(op1->oargs.farg[i], op2->oargs.farg[i]))
130 >                if (obj2 == OVOID)
131                          return(0);
132 <        for (i = op1->oargs.nsargs; i-- > 0; )
133 <                if (strcmp(op1->oargs.sarg[i], op2->oargs.sarg[i]))
132 >                op1 = objptr(obj1);
133 >                op2 = objptr(obj2);
134 >                if (op1->otype != op2->otype)
135                          return(0);
136 +                if (op1->oargs.nsargs != op2->oargs.nsargs)
137 +                        return(0);
138 +                if (op1->oargs.nfargs != op2->oargs.nfargs)
139 +                        return(0);
140 + #ifdef IARGS
141 +                if (op1->oargs.niargs != op2->oargs.niargs)
142 +                        return(0);
143 +                for (i = op1->oargs.niargs; i-- > 0; )
144 +                        if (op1->oargs.iarg[i] != op2->oargs.iarg[i])
145 +                                return(0);
146 + #endif
147 +                for (i = op1->oargs.nfargs; i-- > 0; )
148 +                        if (!eqreal(op1->oargs.farg[i], op2->oargs.farg[i]))
149 +                                return(0);
150 +                n = 0;
151 +                switch (op1->otype) {   /* special cases (KEEP CONSISTENT!) */
152 +                case MOD_ALIAS:
153 +                case MAT_ILLUM:
154 +                case MAT_MIRROR:
155 +                        n = (op1->oargs.nsargs > 0);
156 +                        break;
157 +                case MIX_FUNC:
158 +                case MIX_DATA:
159 +                case MIX_TEXT:
160 +                case MIX_PICT:
161 +                        n = 2*(op1->oargs.nsargs >= 2);
162 +                        break;
163 +                case MAT_CLIP:
164 +                        n = op1->oargs.nsargs;
165 +                        break;
166 +                }
167 +                                        /* check other string arguments */
168 +                for (i = op1->oargs.nsargs; i-- > n; )
169 +                        if (strcmp(op1->oargs.sarg[i], op2->oargs.sarg[i]))
170 +                                return(0);
171 +                while (n-- > 0)         /* check modifier references */
172 +                        if (!eqobjects( lastmod(obj1, op1->oargs.sarg[n]),
173 +                                        lastmod(obj2, op2->oargs.sarg[n]) ))
174 +                                return(0);
175 +                obj1 = op1->omod;
176 +                obj2 = op2->omod;
177 +        }
178          return(1);
179   }
180  
# Line 152 | Line 189 | insertobject(                  /* insert new object into our list */
189          if (ismodifier(objptr(obj)->otype)) {
190                  i = otndx(objptr(obj)->oname, &modtab);
191                  if (eqobjects(obj, modtab.htab[i]))
192 <                        return;
192 >                        return; /* don't index if same as earlier def. */
193                  modtab.htab[i] = obj;
194          }
195   #ifdef  GETOBJ
# Line 167 | Line 204 | insertobject(                  /* insert new object into our list */
204  
205  
206   void
207 < clearobjndx(void)               /* clear object hash tables */
207 > truncobjndx(void)               /* remove bogus table entries past end */
208   {
209 <        if (modtab.htab != NULL) {
210 <                free((void *)modtab.htab);
211 <                modtab.htab = NULL;
212 <                modtab.hsiz = 100;
209 >        int     ndx;
210 >
211 >        if (nobjects <= 0) {
212 >                if (modtab.htab != NULL) {
213 >                        free(modtab.htab);
214 >                        modtab.htab = NULL;
215 >                        modtab.hsiz = 100;
216 >                }
217 >                if (objtab.htab != NULL) {
218 >                        free(objtab.htab);
219 >                        objtab.htab = NULL;
220 >                        objtab.hsiz = 100;
221 >                }
222 >                return;
223          }
224 <        if (objtab.htab != NULL) {
225 <                free((void *)objtab.htab);
226 <                objtab.htab = NULL;
227 <                objtab.hsiz = 100;
228 <        }
224 >        for (ndx = modtab.hsiz*(modtab.htab != NULL); ndx--; )
225 >                if (modtab.htab[ndx] >= nobjects)
226 >                        modtab.htab[ndx] = OVOID;
227 >
228 >        for (ndx = objtab.hsiz*(objtab.htab != NULL); ndx--; )
229 >                if (objtab.htab[ndx] >= nobjects)
230 >                        objtab.htab[ndx] = OVOID;
231   }
232  
233  
# Line 188 | Line 237 | nexthsiz(                      /* return next hash table size */
237   )
238   {
239          static int  hsiztab[] = {
240 <                251, 509, 1021, 2039, 4093, 8191, 16381, 0
240 >                251, 509, 1021, 2039, 4093, 8191, 16381,
241 >                32749, 65521, 131071, 262139, 0
242          };
243          int  *hsp;
244  
# Line 205 | Line 255 | otndx(                         /* get object table index for name */
255          struct ohtab  *tab
256   )
257   {
258 +        char    *onm;
259          OBJECT  *oldhtab;
260          int  hval, i;
261          int  ndx;
# Line 223 | Line 274 | otndx(                         /* get object table index for name */
274   tryagain:
275          for (i = 0; i < tab->hsiz; i++) {
276                  ndx = (hval + (unsigned long)i*i) % tab->hsiz;
277 <                if (tab->htab[ndx] == OVOID ||
227 <                                !strcmp(objptr(tab->htab[ndx])->oname, name))
277 >                if (tab->htab[ndx] == OVOID)
278                          return(ndx);
279 +                onm = objptr(tab->htab[ndx])->oname;
280 +                if (onm != NULL && !strcmp(onm, name))
281 +                        return(ndx);
282          }
283                                          /* table is full, reallocate */
284          oldhtab = tab->htab;
# Line 233 | Line 286 | tryagain:
286          tab->htab = NULL;
287          while (ndx--)
288                  if (oldhtab[ndx] != OVOID) {
289 <                        i = otndx(objptr(oldhtab[ndx])->oname, tab);
289 >                        onm = objptr(oldhtab[ndx])->oname;
290 >                        if (onm == NULL)
291 >                                continue;
292 >                        i = otndx(onm, tab);
293                          tab->htab[i] = oldhtab[ndx];
294                  }
295 <        free((void *)oldhtab);
295 >        free(oldhtab);
296          goto tryagain;                  /* should happen only once! */
297   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines