--- ray/src/hd/rhoptimize.c 1998/11/06 16:54:23 3.3 +++ ray/src/hd/rhoptimize.c 2003/07/27 22:12:02 3.15 @@ -1,33 +1,26 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: rhoptimize.c,v 3.15 2003/07/27 22:12:02 schorsch Exp $"; #endif - /* * Optimize holodeck for quick access. * * 11/4/98 Greg Ward Larson */ -#include "holo.h" - #include +#include +#include "rtprocess.h" /* getpid() */ +#include "holo.h" + #ifndef BKBSIZE #define BKBSIZE 256 /* beam clump size (kilobytes) */ #endif -#define flgop(p,i,op) ((p)[(i)>>5] op (1L<<((i)&0x1f))) -#define isset(p,i) flgop(p,i,&) -#define setfl(p,i) flgop(p,i,|=) -#define clrfl(p,i) flgop(p,i,&=~) - char *progname; char tempfile[128]; +int dupchecking = 0; -extern char *rindex(); -extern int quit(); extern long rhinitcopy(); @@ -40,20 +33,27 @@ char *argv[]; long nextipos, lastopos, thisopos; progname = argv[0]; - if (argc < 2 | argc > 3) { - fprintf(stderr, "Usage: %s input.hdk [output.hdk]\n", progname); + argv++; argc--; /* duplicate checking flag? */ + if (argc > 1 && !strcmp(argv[0], "-u")) { + dupchecking++; + argv++; argc--; + } + if ((argc < 1) | (argc > 2)) { + fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n", + progname); exit(1); } - inpname = argv[1]; - if (argc == 3) /* use given output file */ - outname = argv[2]; + inpname = argv[0]; /* get input file */ + argv++; argc--; + if (argc == 1) /* use given output file */ + outname = argv[0]; else { /* else use temporary file */ if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */ sprintf(errmsg, "cannot access \"%s\"", inpname); error(SYSTEM, errmsg); } strcpy(tempfile, inpname); - if ((outname = rindex(tempfile, '/')) != NULL) + if ((outname = strrchr(tempfile, '/')) != NULL) outname++; else outname = tempfile; @@ -65,14 +65,14 @@ char *argv[]; lastopos = 0L; /* copy sections one by one */ while (nextipos != 0L) { /* set input position; get next */ - lseek(hdfd[0], nextipos, 0); + lseek(hdfd[0], (off_t)nextipos, 0); read(hdfd[0], (char *)&nextipos, sizeof(nextipos)); /* get output position; set last */ - thisopos = lseek(hdfd[1], 0L, 2); + thisopos = lseek(hdfd[1], (off_t)0, 2); if (lastopos > 0L) { - lseek(hdfd[1], lastopos, 0); + lseek(hdfd[1], (off_t)lastopos, 0); write(hdfd[1], (char *)&thisopos, sizeof(thisopos)); - lseek(hdfd[1], 0L, 2); + lseek(hdfd[1], (off_t)0, 2); } lastopos = thisopos; thisopos = 0L; /* write place holder */ @@ -104,6 +104,10 @@ char *infn, *outfn; sprintf(errmsg, "cannot open \"%s\" for reading", infn); error(SYSTEM, errmsg); } + if (access(outfn, F_OK) == 0) { + sprintf(errmsg, "output file \"%s\" already exists!", outfn); + error(USER, errmsg); + } if ((outfp = fopen(outfn, "w+")) == NULL) { sprintf(errmsg, "cannot open \"%s\" for writing", outfn); error(SYSTEM, errmsg); @@ -130,187 +134,94 @@ char *infn, *outfn; fclose(infp); if (fclose(outfp) == EOF) error(SYSTEM, "file flushing error in rhinitcopy"); - /* flush everything manually hence */ - hdcachesize = 0; + /* check cache size */ + if (BKBSIZE*1024*1.5 > hdcachesize) + hdcachesize = BKBSIZE*1024*1.5; /* return input position */ return(ifpos); } -gcshifti(gc, ia, di, hp) /* shift cell row or column */ -register GCOORD *gc; -int ia, di; -register HOLO *hp; +int +nuniq(rva, n) /* sort unique rays to front of beam list */ +register RAYVAL *rva; +int n; { - int nw; - - if (di > 0) { - if (++gc->i[ia] >= hp->grid[((gc->w>>1)+1+ia)%3]) { - nw = ((gc->w&~1) + (ia<<1) + 3) % 6; - gc->i[ia] = gc->i[1-ia]; - gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0; - gc->w = nw; - } - } else if (di < 0) { - if (--gc->i[ia] < 0) { - nw = ((gc->w&~1) + (ia<<1) + 2) % 6; - gc->i[ia] = gc->i[1-ia]; - gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0; - gc->w = nw; - } - } -} - - -mkneighgrid(ng, hp, gc) /* compute neighborhood for grid cell */ -GCOORD ng[3*3]; -HOLO *hp; -GCOORD *gc; -{ - GCOORD gci0; register int i, j; + RAYVAL rtmp; - for (i = 3; i--; ) { - copystruct(&gci0, gc); - gcshifti(&gci0, 0, i-1, hp); - for (j = 3; j--; ) { - copystruct(ng+(3*i+j), &gci0); - gcshifti(ng+(3*i+j), gci0.w==gc->w, j-1, hp); - } - } + for (j = 0; j < n; j++) + for (i = j+1; i < n; i++) + if ( rva[i].d == rva[j].d && + rva[i].r[0][0]==rva[j].r[0][0] && + rva[i].r[0][1]==rva[j].r[0][1] && + rva[i].r[1][0]==rva[j].r[1][0] && + rva[i].r[1][1]==rva[j].r[1][1] ) { + n--; /* swap duplicate with end */ + rtmp = *(rva+n); + *(rva+n) = *(rva+i); + *(rva+i) = rtmp; + i--; /* recheck one we swapped */ + } + return(n); } -int bneighlist[9*9-1]; -int bneighrem; +static BEAMI *beamdir; -#define nextneigh() (bneighrem<=0 ? 0 : bneighlist[--bneighrem]) - -int -firstneigh(hp, b) /* initialize neighbor list and return first */ -HOLO *hp; -int b; +static int +bpcmp(b1p, b2p) /* compare beam positions on disk */ +int *b1p, *b2p; { - GCOORD wg0[9], wg1[9], bgc[2]; - int i, j; + register off_t pdif = beamdir[*b1p].fo - beamdir[*b2p].fo; - hdbcoord(bgc, hp, b); - mkneighgrid(wg0, hp, bgc); - mkneighgrid(wg1, hp, bgc+1); - bneighrem = 0; - for (i = 9; i--; ) - for (j = 9; j--; ) { - if (i == 4 & j == 4) /* don't copy starting beam */ - continue; - if (wg0[i].w == wg1[j].w) - continue; - copystruct(bgc, wg0+i); - copystruct(bgc+1, wg1+j); - bneighlist[bneighrem++] = hdbindex(hp, bgc); -#ifdef DEBUG - if (bneighlist[bneighrem-1] <= 0) - error(CONSISTENCY, "bad beam in firstneigh"); -#endif - } - return(nextneigh()); + if (pdif < 0L) return(-1); + return(pdif > 0L); } +static HOLO *hout; -BEAMI *beamdir; - -int -bpcmp(b1p, b2p) /* compare beam positions on disk */ -int *b1p, *b2p; +static int +xferclump(hp, bq, nb) /* transfer the given clump to hout and free */ +HOLO *hp; +int *bq, nb; { - register long pdif = beamdir[*b1p].fo - beamdir[*b2p].fo; + register int i; + register BEAM *bp; + int n; - if (pdif > 0L) return(1); - if (pdif < 0L) return(-1); + beamdir = hp->bi; /* sort based on file position */ + qsort((void *)bq, nb, sizeof(*bq), bpcmp); + /* transfer and free each beam */ + for (i = 0; i < nb; i++) { + bp = hdgetbeam(hp, bq[i]); + DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump"); + n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm; + memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp), + n*sizeof(RAYVAL)); + hdfreebeam(hp, bq[i]); + } + hdfreebeam(hout, 0); /* write & free clump */ return(0); } - copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */ int ifd, ofd; { - static short primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1}; - register HOLO *hinp; - HOLO *hout; - register BEAM *bp; - unsigned int4 *bflags; - int *bqueue; - int bqlen; - int4 bqtotal; - int bc, bci, bqc, myprime; - register int i; + HOLO *hinp; /* load input section directory */ hinp = hdinit(ifd, NULL); /* create output section directory */ hout = hdinit(ofd, (HDGRID *)hinp); - /* allocate beam queue */ - bqueue = (int *)malloc(nbeams(hinp)*sizeof(int)); - bflags = (unsigned int4 *)calloc((nbeams(hinp)>>5)+1, - sizeof(unsigned int4)); - if (bqueue == NULL | bflags == NULL) - error(SYSTEM, "out of memory in copysect"); - /* mark empty beams as done */ - for (i = nbeams(hinp); i > 0; i--) - if (!hinp->bi[i].nrd) - setfl(bflags, i); - /* pick a good prime step size */ - for (i = 0; primes[i]<<5 >= nbeams(hinp); i++) - ; - while ((myprime = primes[i++]) > 1) - if (nbeams(hinp) % myprime) - break; - /* add each input beam and neighbors */ - for (bc = bci = nbeams(hinp); bc > 0; bc--, - bci += bci>myprime ? -myprime : nbeams(hinp)-myprime) { - if (isset(bflags, bci)) - continue; - bqueue[0] = bci; /* initialize queue */ - bqlen = 1; - bqtotal = hinp->bi[bci].nrd; - setfl(bflags, bci); - /* run through growing queue */ - for (bqc = 0; bqc < bqlen; bqc++) { - /* add neighbors until full */ - for (i = firstneigh(hinp,bqueue[bqc]); i > 0; - i = nextneigh()) { - if (isset(bflags, i)) /* done already? */ - continue; - bqueue[bqlen++] = i; /* add it */ - bqtotal += hinp->bi[i].nrd; - setfl(bflags, i); - if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL)) - break; /* queue full */ - } - if (i > 0) - break; - } - beamdir = hinp->bi; /* sort queue */ - qsort((char *)bqueue, bqlen, sizeof(*bqueue), bpcmp); - /* transfer each beam */ - for (i = 0; i < bqlen; i++) { - bp = hdgetbeam(hinp, bqueue[i]); - bcopy((char *)hdbray(bp), - (char *)hdnewrays(hout,bqueue[i],bp->nrm), - bp->nrm*sizeof(RAYVAL)); - hdfreebeam(hinp, bqueue[i]); - } - hdfreebeam(hout, 0); /* flush output block */ -#ifdef DEBUG - hdsync(hout, 0); -#endif - } - /* we're done -- clean up */ - free((char *)bqueue); - free((char *)bflags); + /* clump the beams */ + clumpbeams(hinp, 0, BKBSIZE*1024, xferclump); + /* clean up */ hddone(hinp); hddone(hout); } +void eputs(s) /* put error message to stderr */ register char *s; { @@ -330,6 +241,7 @@ register char *s; } +void quit(code) /* exit the program gracefully */ int code; {