|
|
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.