|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <tree.h>
4: # include <symbol.h>
5: # include "globs.h"
6: # include <sccs.h>
7:
8: SCCSID(@(#)openrs.c 7.1 2/5/81)
9:
10:
11:
12:
13: /* Defined constants for dtmode field above */
14: # define DTALLOC 0 /* descriptor allocated */
15: # define DTREL 1 /* has been openr'd -1 */
16: # define DTATTS 2 /* has rel+atts but not opened */
17: # define DTREAD 3 /* currently open for reading */
18: # define DTWRITE 4 /* currently open for writing */
19:
20:
21:
22: /* Allocation of descriptors */
23:
24: /* Globals which count #files open and maximum # of files which can be open */
25:
26:
27: /*
28: ** OPENRS -- routines associated with maintaining the range table for decomp
29: **
30: ** openrs(root) -- fill range table info about each relation.
31: **
32: ** closers() -- close all variables in range table.
33: **
34: ** openr1(varno) -- fill range table for a particular relation.
35: **
36: ** closer1(varno) -- close a particular relation.
37: **
38: ** readopen(varno) -- open a variable for reading. returns descriptor.
39: **
40: ** writeopen(varno) -- open a variable for writing. returns descriptor.
41: **
42: ** initdesc() -- initialize the descriptor cache.
43: **
44: ** reldescrip(varno) -- returns descriptor for var (has rel/atts
45: ** but might not be open).
46: **
47: ** desc_get(relnum, flag) -- finds a desc_tab & alloctes it for relnum.
48: **
49: ** desc_lru() -- returns least recently used desc_tab.
50: **
51: ** desc_top(desc_tab) -- makes desc_tab most recently used.
52: **
53: ** desc_last(desc_tab) -- makes desc_tab the least recently used.
54: **
55: ** Trace Flags:
56: ** 62
57: */
58: /*
59: ** Initdesc -- initialize descriptors for range table
60: */
61:
62: initdesc(mode)
63: int mode;
64: {
65: register struct desc_tab *dt;
66: register int i;
67: extern int Equel;
68:
69:
70: for (dt = De.de_desc, i = 0; dt <= &De.de_desc[MAXRELN - 1]; dt++, i++)
71: {
72: dt->dtmode = DTALLOC;
73: dt->relnum = -2; /* unused relnum value */
74: dt->dtpos = i; /* lru order */
75: }
76:
77: /*
78: ** Determine number of available file descriptors.
79: ** av_files gives number of files that are def. open
80: ** for users. if we will need to open a batch file,
81: ** get rid of that also.
82: */
83:
84: De.de_dfiles = av_files();
85: if (mode != mdRETR)
86: De.de_dfiles--;
87: De.de_dopnfiles = 0;
88: }
89: /*
90: ** Openrs -- open source relations for query. Fill values
91: ** in range table.
92: */
93:
94: openrs(root)
95: QTREE *root;
96: {
97: register QTREE *r;
98: register int map, i;
99: DESC *openr1();
100:
101: r = root;
102: map = r->sym.value.sym_root.lvarm | r->sym.value.sym_root.rvarm;
103:
104: # ifdef xDTR1
105: if (tTf(62, 0))
106: printf("OPENRS-root:%x,map:%o\n", r, map);
107: # endif
108:
109: for (i = 0; i < MAXRANGE; i++)
110: if (map & (01 << i))
111: openr1(i);
112:
113: }
114: /*
115: ** Close all open relations.
116: ** If any relations were created but never
117: ** opened, destroy them. The only
118: ** situation under which that can occur
119: ** is when a rub-out occurs at an
120: ** in opportune moment or when an error
121: ** occurs in ovqp.
122: */
123:
124: closers()
125: {
126: register int i;
127: register struct desc_tab *dt;
128: bool dstr_flag;
129:
130:
131: for (dt = De.de_desc; dt <= &De.de_desc[MAXRELN - 1]; dt++)
132: desc_close(dt);
133:
134: /* destroy any temps */
135: initp(); /* init parameters vector for destroys */
136: dstr_flag = FALSE;
137: while (i = rnum_last())
138: {
139: dstr_flag |= dstr_mark(i); /* indicate that there are relations to be destroyed */
140: }
141:
142: if (dstr_flag)
143: call_dbu(mdDESTROY, TRUE);
144: else
145: resetp();
146: }
147: /*
148: ** Openr1 -- open relation to get relation relation tuple
149: **
150: ** This will not open the relation for reading -- only
151: ** for getting the first part of the descriptor filled
152: */
153:
154: DESC *
155: openr1(var)
156: int var;
157: {
158: register struct desc_tab *dt;
159: register struct rang_tab *rp;
160: register DESC *d;
161: int i;
162: struct desc_tab *desc_get();
163: extern char *rnum_convert();
164:
165: rp = &De.de_rangev[var];
166:
167: # ifdef xDTR1
168: if (tTf(62, 2))
169: printf("openr1: var %d (%s)\t", var, rnum_convert(rp->relnum));
170: # endif
171:
172: dt = desc_get(rp->relnum, TRUE);
173:
174: if (dt->dtmode == DTALLOC)
175: {
176: if (i = openr(&dt->desc, -1, rnum_convert(rp->relnum)))
177: syserr("openr1 open %d %s", i, rnum_convert(rp->relnum));
178: dt->dtmode = DTREL;
179: }
180:
181: # ifdef xDTR1
182: if (tTf(62, 2))
183: printf("tups=%ld\n", dt->desc.reldum.reltups);
184: # endif
185:
186: d = &dt->desc;
187:
188: rp->rtspec = d->reldum.relspec;
189: rp->rtstat = d->reldum.relstat;
190: rp->rtwid = d->reldum.relwid;
191: rp->rtcnt = d->reldum.reltups;
192:
193: return (d);
194: }
195: /*
196: ** CLOSER1
197: */
198:
199: closer1(var)
200: int var;
201: {
202: register struct desc_tab *dt;
203: register struct rang_tab *rp;
204: register int i;
205: struct desc_tab *desc_get();
206: struct desc_tab *desc_last();
207:
208: i = var;
209: rp = &De.de_rangev[i];
210:
211: # ifdef xDTR1
212: if (tTf(62, 4))
213: printf("closer1:var %d (%s)\n", i, rnum_convert(rp->relnum));
214: # endif
215: if (dt = desc_get(rp->relnum, FALSE))
216: {
217:
218: /* currently a descriptor for rel */
219: desc_close(dt);
220:
221: dt->relnum = -2;
222: desc_last(dt);
223:
224: }
225: }
226: /*
227: ** READOPEN
228: */
229:
230: DESC *
231: readopen(var)
232: int var;
233: {
234: register struct desc_tab *dt;
235: struct desc_tab *desc_get();
236:
237: /* get descv for the relation */
238: dt = desc_get(De.de_rangev[var].relnum, TRUE);
239:
240: if (!(dt->dtmode == DTREAD || dt->dtmode == DTWRITE))
241: {
242: /* not open for reading or writing */
243: openup(dt, var, 0); /* open for reading */
244: }
245:
246: return (&dt->desc);
247: }
248: /*
249: ** WRITEOPEN
250: */
251:
252: DESC *
253: writeopen(var)
254: int var;
255: {
256: register struct desc_tab *dt;
257:
258: /* get descv for the relation */
259: dt = desc_get(De.de_rangev[var].relnum, TRUE);
260:
261: if (dt->dtmode != DTWRITE)
262: {
263: /* not open for writing */
264: openup(dt, var, 2); /* open for reading */
265: }
266:
267: return (&dt->desc);
268: }
269: /*
270: ** SPECOPEN -- open for writing not associated with any variable
271: */
272:
273: DESC *
274: specopen(relnum)
275: int relnum;
276: {
277: register struct desc_tab *dt;
278: struct desc_tab *desc_get();
279:
280: dt = desc_get(relnum, TRUE);
281:
282: if (dt->dtmode != DTWRITE)
283: openup(dt, -1, 2);
284:
285: return (&dt->desc);
286: }
287: /*
288: ** SPECCLOSE
289: */
290:
291: specclose(relnum)
292: int relnum;
293: {
294: register struct desc_tab *dt;
295: struct desc_tab *desc_get();
296: struct desc_tab *desc_last();
297:
298: if (dt = desc_get(relnum, FALSE))
299: {
300: desc_close(dt);
301: desc_last(dt);
302: dt->relnum = -2;
303: }
304: }
305: /*
306: ** Openup -- make sure that the given descriptor is open
307: ** suitably for reading or writing.
308: */
309:
310: openup(dt1, varno, mode)
311: struct desc_tab *dt1;
312: int varno;
313: int mode;
314: {
315: register struct desc_tab *dt;
316: register int md, openmd;
317: int i;
318: extern char *rnum_convert();
319: char rnam_tmp[MAXNAME+3];
320:
321: /* quick check to handle typical case of rel being already open */
322: md = mode;
323: dt = dt1;
324: if ((md != 2 && dt->dtmode == DTREAD) || dt->dtmode == DTWRITE)
325: return;
326:
327: /* relation not opened correctly */
328: switch (dt->dtmode)
329: {
330:
331: case DTALLOC:
332: /*
333: ** Descriptor allocated but nothing else. If this
334: ** is for a variable then use openr1 to get range table
335: ** info. Else open directly.
336: */
337: if (varno < 0)
338: {
339: /* open unassociated with a range table variable */
340: openmd = md ? 2 : 0;
341: bmove(rnum_convert(dt->relnum), dt->desc.reldum.relid, MAXNAME);
342: break;
343: }
344:
345: /* open for range table variable */
346: openr1(varno);
347:
348: /* now fall through to DTREL case */
349:
350: case DTREL:
351: /* relation relation tuple present but nothing else */
352: openmd = md ? -3 : -2; /* open -2 for read, -3 for write */
353: break;
354:
355: case DTATTS:
356: /* relation & attributes filled but relation closed */
357: openmd = md ? -5 : -4;
358: break;
359: case DTREAD:
360: /* relation open for reading but we need to write */
361: desc_close(dt);
362:
363: openmd = -5;
364: break;
365:
366: default:
367: syserr("openup:bad md %d", dt->dtmode);
368: }
369:
370: /* close a previous file if necessary */
371: if (De.de_dopnfiles == De.de_dfiles)
372: desc_victum(); /* close oldest file */
373:
374: /* now open relation */
375: bmove(dt->desc.reldum.relid, rnam_tmp, MAXNAME + 3);
376: if (i = openr(&dt->desc, openmd, rnam_tmp))
377: syserr("openup:openr %d,%d,%.12s,%s", i, openmd, rnam_tmp, rnum_convert(dt->relnum));
378: De.de_dopnfiles++;
379:
380: /* update mode of descriptor */
381: dt->dtmode = md ? DTWRITE : DTREAD;
382: }
383: /*
384: ** DESC_GET
385: */
386:
387: struct desc_tab *
388: desc_get(relnum, flag)
389: int relnum;
390: bool flag;
391: {
392: register struct desc_tab *dt, *ret;
393: struct desc_tab *desc_lru();
394:
395: ret = NULL;
396:
397: /* search for one currently allocated */
398: for (dt = &De.de_desc[0]; dt <= &De.de_desc[MAXRELN-1]; dt++)
399: {
400: if (dt->relnum == relnum)
401: {
402: ret = dt;
403: # ifdef xDTR1
404: if (tTf(62, 3))
405: printf("found desc for %d\n", relnum);
406: # endif
407: break;
408: }
409: }
410:
411: if (ret == NULL && flag)
412: {
413: /* get a victim and deallocate desc */
414: ret = desc_lru();
415:
416: /* deallocate */
417: # ifdef xDTR1
418: if (tTf(62, 5))
419: printf("trading %d for %d\n", ret->relnum, relnum);
420: # endif
421: desc_close(ret);
422:
423: /* allocate */
424: ret->relnum = relnum;
425: ret->dtmode = DTALLOC;
426: }
427:
428: if (ret != NULL)
429: desc_top(ret);
430:
431: return (ret);
432: }
433: /*
434: ** For text space reasons only, the close relation routine varies
435: ** between decomp and decomp70. In decomp, the relation is opened
436: ** only for reading and never for writing thus inpcloser() can be
437: ** called. For decomp70 closer() must be called. If there were no
438: ** text space shortage, then closer() could always be called.
439: ** The routine init_decomp() assigned the value to Des_closefunc.
440: */
441:
442: extern int (*Des_closefunc)(); /* either &inpcloser or &closer */
443:
444: desc_close(dt1)
445: struct desc_tab *dt1;
446: {
447: register struct desc_tab *dt;
448: register int i;
449:
450: dt = dt1;
451:
452: if (dt->dtmode == DTREAD || dt->dtmode == DTWRITE)
453: {
454: if (i = (*Des_closefunc)(&dt->desc))
455: syserr("desc_close:closer %d,%.12s", i, dt->desc.reldum.relid);
456: De.de_dopnfiles--;
457: dt->dtmode = DTATTS;
458: }
459: }
460: /*
461: ** Desc_top -- make the desc_tab entry "dtx" the most recently used.
462: */
463:
464: desc_top(dt1)
465: struct desc_tab *dt1;
466: {
467: register struct desc_tab *dt, *dx;
468: register int oldpos;
469:
470: dt = dt1;
471:
472: if ((oldpos = dt->dtpos) != 0)
473: {
474: /* descriptor isn't currently top */
475: for (dx = De.de_desc; dx <= &De.de_desc[MAXRELN-1]; dx++)
476: if (dx->dtpos < oldpos)
477: dx->dtpos++;
478:
479: /* make descriptor first */
480: dt->dtpos = 0;
481: }
482: }
483: /*
484: ** Desc_last -- make the desc_tab entry "dt" the least recently used.
485: */
486:
487: struct desc_tab *
488: desc_last(dt)
489: register struct desc_tab *dt;
490: {
491: register int oldpos;
492: register struct desc_tab *dx;
493:
494: oldpos = dt->dtpos;
495: for (dx = De.de_desc; dx <= &De.de_desc[MAXRELN-1]; dx++)
496: if (dx->dtpos > oldpos)
497: dx->dtpos--;
498:
499: /* make descriptor last */
500: dt->dtpos = MAXRELN - 1;
501: }
502: /*
503: ** Desc_lru -- return least recently used descriptor
504: */
505:
506: struct desc_tab *
507: desc_lru()
508: {
509: register struct desc_tab *dx;
510:
511: for (dx = De.de_desc; dx <= &De.de_desc[MAXRELN-1]; dx++)
512: {
513: if (dx->dtpos == MAXRELN - 1)
514: return (dx);
515: }
516: syserr("desc_lru:no lru");
517: /*NOTREACHED*/
518: }
519:
520:
521: desc_victum()
522: {
523: register struct desc_tab *dt, *old;
524:
525: old = NULL;
526: for (dt = &De.de_desc[0]; dt <= &De.de_desc[MAXRELN-1]; dt++)
527: {
528: if (dt->dtmode == DTWRITE || dt->dtmode == DTREAD)
529: {
530: if (old == NULL || dt->dtpos > old->dtpos)
531: old = dt;
532: }
533: }
534:
535: if (old == NULL)
536: syserr("desc_victum:no victum %d,%d", De.de_dopnfiles, De.de_dfiles);
537: desc_close(old);
538: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.