ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.10
Committed: Thu May 29 16:26:22 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.9: +1 -1 lines
Log Message:
Changed beam offset from long to off_t, so holodecks can grow to max. length

File Contents

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 greg 3.8 static const char RCSid[] = "$Id$";
3 gwlarson 3.1 #endif
4     /*
5     * Optimize holodeck for quick access.
6     *
7     * 11/4/98 Greg Ward Larson
8     */
9    
10     #include "holo.h"
11    
12 gwlarson 3.3 #include <signal.h>
13    
14 gwlarson 3.1 #ifndef BKBSIZE
15 gwlarson 3.2 #define BKBSIZE 256 /* beam clump size (kilobytes) */
16 gwlarson 3.1 #endif
17    
18     char *progname;
19 gwlarson 3.3 char tempfile[128];
20 gwlarson 3.6 int dupchecking = 0;
21 gwlarson 3.1
22 gwlarson 3.3 extern char *rindex();
23 gwlarson 3.1 extern long rhinitcopy();
24    
25    
26     main(argc, argv)
27     int argc;
28     char *argv[];
29     {
30     char *inpname, *outname;
31     int hdfd[2];
32     long nextipos, lastopos, thisopos;
33    
34     progname = argv[0];
35 gwlarson 3.6 argv++; argc--; /* duplicate checking flag? */
36     if (argc > 1 && !strcmp(argv[0], "-u")) {
37     dupchecking++;
38     argv++; argc--;
39     }
40     if (argc < 1 | argc > 2) {
41     fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
42     progname);
43 gwlarson 3.1 exit(1);
44     }
45 gwlarson 3.6 inpname = argv[0]; /* get input file */
46     argv++; argc--;
47     if (argc == 1) /* use given output file */
48     outname = argv[0];
49 gwlarson 3.3 else { /* else use temporary file */
50     if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */
51     sprintf(errmsg, "cannot access \"%s\"", inpname);
52     error(SYSTEM, errmsg);
53     }
54     strcpy(tempfile, inpname);
55     if ((outname = rindex(tempfile, '/')) != NULL)
56 gwlarson 3.1 outname++;
57     else
58 gwlarson 3.3 outname = tempfile;
59 gwlarson 3.1 sprintf(outname, "rho%d.hdk", getpid());
60 gwlarson 3.3 outname = tempfile;
61 gwlarson 3.1 }
62     /* copy holodeck file header */
63     nextipos = rhinitcopy(hdfd, inpname, outname);
64     lastopos = 0L; /* copy sections one by one */
65     while (nextipos != 0L) {
66     /* set input position; get next */
67 greg 3.8 lseek(hdfd[0], (off_t)nextipos, 0);
68 gwlarson 3.1 read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
69     /* get output position; set last */
70 greg 3.8 thisopos = lseek(hdfd[1], (off_t)0L, 2);
71 gwlarson 3.1 if (lastopos > 0L) {
72 greg 3.8 lseek(hdfd[1], (off_t)lastopos, 0);
73 gwlarson 3.1 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
74 greg 3.8 lseek(hdfd[1], (off_t)0L, 2);
75 gwlarson 3.1 }
76     lastopos = thisopos;
77     thisopos = 0L; /* write place holder */
78     write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
79     /* copy holodeck section */
80     copysect(hdfd[0], hdfd[1]);
81     }
82     /* clean up */
83     close(hdfd[0]);
84     close(hdfd[1]);
85 gwlarson 3.3 if (outname == tempfile && rename(outname, inpname) < 0) {
86 gwlarson 3.1 sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
87     outname, inpname);
88     error(SYSTEM, errmsg);
89     }
90     exit(0);
91     }
92    
93    
94     long
95     rhinitcopy(hfd, infn, outfn) /* open files and copy header */
96     int hfd[2]; /* returned file descriptors */
97     char *infn, *outfn;
98     {
99     FILE *infp, *outfp;
100     long ifpos;
101     /* open files for i/o */
102     if ((infp = fopen(infn, "r")) == NULL) {
103     sprintf(errmsg, "cannot open \"%s\" for reading", infn);
104     error(SYSTEM, errmsg);
105     }
106 greg 3.8 if (access(outfn, F_OK) == 0) {
107     sprintf(errmsg, "output file \"%s\" already exists!", outfn);
108     error(USER, errmsg);
109     }
110 gwlarson 3.1 if ((outfp = fopen(outfn, "w+")) == NULL) {
111     sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
112     error(SYSTEM, errmsg);
113     }
114 gwlarson 3.3 /* set up signal handling */
115     if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN);
116     if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN);
117     if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN);
118     #ifdef SIGXCPU
119     if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN);
120     if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN);
121     #endif
122 gwlarson 3.1 /* copy and verify header */
123 gwlarson 3.3 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
124 gwlarson 3.1 error(USER, "input not in holodeck format");
125     fputformat(HOLOFMT, outfp);
126     fputc('\n', outfp);
127     putw(HOLOMAGIC, outfp);
128     /* get descriptors and free stdio */
129     if ((hfd[0] = dup(fileno(infp))) < 0 ||
130     (hfd[1] = dup(fileno(outfp))) < 0)
131     error(SYSTEM, "dup call failed in rhinitcopy");
132     ifpos = ftell(infp);
133     fclose(infp);
134     if (fclose(outfp) == EOF)
135     error(SYSTEM, "file flushing error in rhinitcopy");
136 gwlarson 3.4 /* check cache size */
137     if (BKBSIZE*1024*1.5 > hdcachesize)
138     hdcachesize = BKBSIZE*1024*1.5;
139 gwlarson 3.1 /* return input position */
140     return(ifpos);
141     }
142    
143    
144 gwlarson 3.6 int
145     nuniq(rva, n) /* sort unique rays to front of beam list */
146     register RAYVAL *rva;
147     int n;
148     {
149     register int i, j;
150     RAYVAL rtmp;
151    
152     for (j = 0; j < n; j++)
153     for (i = j+1; i < n; i++)
154     if ( rva[i].d == rva[j].d &&
155     rva[i].r[0][0]==rva[j].r[0][0] &&
156     rva[i].r[0][1]==rva[j].r[0][1] &&
157     rva[i].r[1][0]==rva[j].r[1][0] &&
158     rva[i].r[1][1]==rva[j].r[1][1] ) {
159     n--; /* swap duplicate with end */
160     copystruct(&rtmp, rva+n);
161     copystruct(rva+n, rva+i);
162     copystruct(rva+i, &rtmp);
163     i--; /* recheck one we swapped */
164     }
165     return(n);
166     }
167    
168    
169 gwlarson 3.5 static BEAMI *beamdir;
170 gwlarson 3.1
171 gwlarson 3.4 static int
172 gwlarson 3.5 bpcmp(b1p, b2p) /* compare beam positions on disk */
173     int *b1p, *b2p;
174 gwlarson 3.1 {
175 greg 3.10 register off_t pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
176 gwlarson 3.5
177     if (pdif < 0L) return(-1);
178 gwlarson 3.6 return(pdif > 0L);
179 gwlarson 3.2 }
180    
181 gwlarson 3.5 static HOLO *hout;
182    
183     static int
184     xferclump(hp, bq, nb) /* transfer the given clump to hout and free */
185     HOLO *hp;
186     int *bq, nb;
187     {
188     register int i;
189     register BEAM *bp;
190 gwlarson 3.6 int n;
191 gwlarson 3.5
192     beamdir = hp->bi; /* sort based on file position */
193 greg 3.9 qsort((void *)bq, nb, sizeof(*bq), bpcmp);
194 gwlarson 3.5 /* transfer and free each beam */
195     for (i = 0; i < nb; i++) {
196     bp = hdgetbeam(hp, bq[i]);
197 gwlarson 3.6 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
198     n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
199 greg 3.9 bcopy((void *)hdbray(bp), (void *)hdnewrays(hout,bq[i],n),
200 gwlarson 3.6 n*sizeof(RAYVAL));
201 gwlarson 3.5 hdfreebeam(hp, bq[i]);
202     }
203 gwlarson 3.7 hdfreebeam(hout, 0); /* write & free clump */
204 gwlarson 3.5 return(0);
205     }
206    
207 gwlarson 3.1 copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
208     int ifd, ofd;
209     {
210 gwlarson 3.4 HOLO *hinp;
211 gwlarson 3.1 /* load input section directory */
212     hinp = hdinit(ifd, NULL);
213     /* create output section directory */
214     hout = hdinit(ofd, (HDGRID *)hinp);
215 gwlarson 3.4 /* clump the beams */
216 gwlarson 3.5 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
217 gwlarson 3.4 /* clean up */
218 gwlarson 3.1 hddone(hinp);
219     hddone(hout);
220     }
221    
222    
223 greg 3.8 void
224 gwlarson 3.1 eputs(s) /* put error message to stderr */
225     register char *s;
226     {
227     static int midline = 0;
228    
229     if (!*s)
230     return;
231     if (!midline++) { /* prepend line with program name */
232     fputs(progname, stderr);
233     fputs(": ", stderr);
234     }
235     fputs(s, stderr);
236     if (s[strlen(s)-1] == '\n') {
237     fflush(stderr);
238     midline = 0;
239     }
240     }
241    
242    
243 greg 3.8 void
244 gwlarson 3.1 quit(code) /* exit the program gracefully */
245     int code;
246     {
247 gwlarson 3.3 if (tempfile[0])
248     unlink(tempfile);
249 gwlarson 3.1 exit(code);
250     }