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

Comparing ray/src/common/modobject.c (file contents):
Revision 2.16 by greg, Mon Dec 9 17:57:44 2013 UTC vs.
Revision 2.25 by greg, Sat Jun 21 17:42:17 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;
31 <
32 <        for (i = nobjects>>OBJBLKSHFT; i >= 0; i--) {
33 <                j = op - objblock[i];
34 <                if ((j >= 0) & (j < OBJBLKSIZ))
35 <                        return((i<<OBJBLKSHFT) + j);
36 <        }
37 <        return(OVOID);
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;
35 >        int             i;
36 >                                /* clear cache on first call */
37 >        for (i = ONCACHESIZ*(!oncache[0] & !oncache[1]); i--; )
38 >                oncache[i] = OVOID;
39 >                                /* is this pointer in cache? */
40 >        if ((oncache[ent] != OVOID) & (oncache[ent] < nobjects) &&
41 >                                objptr(oncache[ent]) == op)
42 >                return(oncache[ent]);           /* matches previous search */
43 >                                /* else look for allocated block */
44 >        for (i = (nobjects-1)>>OBJBLKSHFT; i >= 0; i--)
45 >                if ((objblock[i] <= op) & (op < objblock[i]+OBJBLKSIZ)) {
46 >                                /* found it -- save index to cache */
47 >                        oncache[ent] = ((OBJECT)i << OBJBLKSHFT) +
48 >                                                (op - objblock[i]);
49 >                        return(oncache[ent]);
50 >                }
51 >        return(OVOID);          /* not in our array -- may still be valid */
52   }
53  
54  
# Line 47 | Line 59 | lastmod(                       /* find modifier definition before obj */
59   )
60   {
61          OBJREC  *op;
62 <        int  i;
62 >        OBJECT  i;
63  
64          i = modifier(mname);            /* try hash table first */
65          if ((obj == OVOID) | (i < obj))
66                  return(i);
67          for (i = obj; i-- > 0; ) {      /* need to search */
68                  op = objptr(i);
69 <                if (ismodifier(op->otype) && op->oname[0] == mname[0] &&
70 <                                        !strcmp(op->oname, mname))
69 >                if ((ismodifier(op->otype) != 0) & (op->oname[0] == mname[0])
70 >                                && !strcmp(op->oname, mname))
71                          return(i);
72          }
73          return(OVOID);
# Line 107 | Line 119 | eqobjects(                     /* check if two objects are equal */
119   )
120   {
121          OBJREC  *op1, *op2;
122 <        int     i;
122 >        int     i, n;
123  
124          while (obj1 != obj2) {
125                  if (obj1 == OVOID)
# Line 132 | Line 144 | eqobjects(                     /* check if two objects are equal */
144                  for (i = op1->oargs.nfargs; i-- > 0; )
145                          if (!eqreal(op1->oargs.farg[i], op2->oargs.farg[i]))
146                                  return(0);
147 <                for (i = op1->oargs.nsargs; i-- > 0; )
136 <                        if (strcmp(op1->oargs.sarg[i], op2->oargs.sarg[i]))
137 <                                return(0);
138 <                i = 0;
147 >                n = 0;
148                  switch (op1->otype) {   /* special cases (KEEP CONSISTENT!) */
149                  case MOD_ALIAS:
150                  case MAT_ILLUM:
151                  case MAT_MIRROR:
152 <                        i = (op1->oargs.nsargs > 0);
152 >                        n = (op1->oargs.nsargs > 0);
153                          break;
154                  case MIX_FUNC:
155                  case MIX_DATA:
156                  case MIX_TEXT:
157                  case MIX_PICT:
158 <                        i = 2*(op1->oargs.nsargs >= 2);
158 >                        n = 2*(op1->oargs.nsargs >= 2);
159                          break;
160                  case MAT_CLIP:
161 <                        i = op1->oargs.nsargs;
161 >                        n = op1->oargs.nsargs;
162                          break;
163                  }
164 <                while (i-- > 0)         /* check modifier references */
165 <                        if (!eqobjects( lastmod(obj1, op1->oargs.sarg[i]),
166 <                                        lastmod(obj2, op2->oargs.sarg[i]) ))
164 >                                        /* check other string arguments */
165 >                for (i = op1->oargs.nsargs; i-- > n; )
166 >                        if (strcmp(op1->oargs.sarg[i], op2->oargs.sarg[i]))
167                                  return(0);
168 +                while (n-- > 0)         /* check modifier references */
169 +                        if (!eqobjects( lastmod(obj1, op1->oargs.sarg[n]),
170 +                                        lastmod(obj2, op2->oargs.sarg[n]) ))
171 +                                return(0);
172                  obj1 = op1->omod;
173                  obj2 = op2->omod;
174          }
# Line 188 | Line 201 | insertobject(                  /* insert new object into our list */
201  
202  
203   void
204 < clearobjndx(void)               /* clear object hash tables */
204 > truncobjndx(void)               /* remove bogus table entries past end */
205   {
206 <        if (modtab.htab != NULL) {
207 <                free((void *)modtab.htab);
208 <                modtab.htab = NULL;
209 <                modtab.hsiz = 100;
206 >        int     ndx;
207 >
208 >        if (nobjects <= 0) {
209 >                if (modtab.htab != NULL) {
210 >                        free(modtab.htab);
211 >                        modtab.htab = NULL;
212 >                        modtab.hsiz = 100;
213 >                }
214 >                if (objtab.htab != NULL) {
215 >                        free(objtab.htab);
216 >                        objtab.htab = NULL;
217 >                        objtab.hsiz = 100;
218 >                }
219 >                return;
220          }
221 <        if (objtab.htab != NULL) {
222 <                free((void *)objtab.htab);
223 <                objtab.htab = NULL;
224 <                objtab.hsiz = 100;
225 <        }
221 >        for (ndx = modtab.hsiz*(modtab.htab != NULL); ndx--; )
222 >                if (modtab.htab[ndx] >= nobjects)
223 >                        modtab.htab[ndx] = OVOID;
224 >
225 >        for (ndx = objtab.hsiz*(objtab.htab != NULL); ndx--; )
226 >                if (objtab.htab[ndx] >= nobjects)
227 >                        objtab.htab[ndx] = OVOID;
228   }
229  
230  
# Line 209 | Line 234 | nexthsiz(                      /* return next hash table size */
234   )
235   {
236          static int  hsiztab[] = {
237 <                251, 509, 1021, 2039, 4093, 8191, 16381, 0
237 >                251, 509, 1021, 2039, 4093, 8191, 16381,
238 >                32749, 65521, 131071, 262139, 0
239          };
240          int  *hsp;
241  
# Line 226 | Line 252 | otndx(                         /* get object table index for name */
252          struct ohtab  *tab
253   )
254   {
255 +        char    *onm;
256          OBJECT  *oldhtab;
257          int  hval, i;
258          int  ndx;
# Line 244 | Line 271 | otndx(                         /* get object table index for name */
271   tryagain:
272          for (i = 0; i < tab->hsiz; i++) {
273                  ndx = (hval + (unsigned long)i*i) % tab->hsiz;
274 <                if (tab->htab[ndx] == OVOID ||
248 <                                !strcmp(objptr(tab->htab[ndx])->oname, name))
274 >                if (tab->htab[ndx] == OVOID)
275                          return(ndx);
276 +                onm = objptr(tab->htab[ndx])->oname;
277 +                if (onm != NULL && !strcmp(onm, name))
278 +                        return(ndx);
279          }
280                                          /* table is full, reallocate */
281          oldhtab = tab->htab;
# Line 254 | Line 283 | tryagain:
283          tab->htab = NULL;
284          while (ndx--)
285                  if (oldhtab[ndx] != OVOID) {
286 <                        i = otndx(objptr(oldhtab[ndx])->oname, tab);
286 >                        onm = objptr(oldhtab[ndx])->oname;
287 >                        if (onm == NULL)
288 >                                continue;
289 >                        i = otndx(onm, tab);
290                          tab->htab[i] = oldhtab[ndx];
291                  }
292 <        free((void *)oldhtab);
292 >        free(oldhtab);
293          goto tryagain;                  /* should happen only once! */
294   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)