|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include <ingres.h> ! 3: # include <aux.h> ! 4: # include <symbol.h> ! 5: # include <access.h> ! 6: # include <func.h> ! 7: # include <batch.h> ! 8: # include <catalog.h> ! 9: # include <pv.h> ! 10: # include <sccs.h> ! 11: ! 12: SCCSID(@(#)ksort.c 8.4 12/8/85) ! 13: ! 14: # define N 7 ! 15: # define MEM (32768 - 2) ! 16: # define BUCKETSIZE 4 ! 17: # define ENDKEY MAXDOM + 1 ! 18: ! 19: ! 20: ! 21: /* ! 22: ** Parameters: ! 23: ** ! 24: ** pv[0]: Fileset ! 25: ** pv[1]: Infile from which reln is read ! 26: ** pv[2]: Outfile to which reln is written ! 27: ** pv[3...]: the desc of the new relation ! 28: ** ! 29: ** Trace Flag: Z37 ! 30: */ ! 31: ! 32: extern short tTdbu[100]; ! 33: extern int ksort(); ! 34: extern int null_fn(); ! 35: ! 36: struct fn_def KsortFn = ! 37: { ! 38: "KSORT", ! 39: ksort, ! 40: null_fn, ! 41: null_fn, ! 42: NULL, ! 43: 0, ! 44: tTdbu, ! 45: 100, ! 46: 'Z', ! 47: 0 ! 48: }; ! 49: ! 50: static char *Infile; ! 51: static char *Outfile; ! 52: static DESC Desc; ! 53: static char Descsort[MAXDOM+1]; ! 54: static FILE *Oiop; ! 55: static int Tupsize; ! 56: static int Bucket; ! 57: static char File[15]; ! 58: static char *Fileset; ! 59: static char *Filep; ! 60: static int Nlines; ! 61: static long Ccount; ! 62: static char **Lspace; ! 63: static char *Tspace; ! 64: extern int cmpa(); ! 65: static long Tupsout; ! 66: static int firstime = 1; ! 67: static FILE *Btree_fp; ! 68: DESC Btreesec; ! 69: int Btree_fd; ! 70: int Nfiles; ! 71: ! 72: ksort(pc, pv) ! 73: int pc; ! 74: PARM *pv; ! 75: { ! 76: extern char *Proc_name; ! 77: register int i; ! 78: register int j; ! 79: unsigned int mem; ! 80: char *start; ! 81: int maxkey, rev; ! 82: extern char *malloc(); ! 83: ! 84: # ifdef xZTR1 ! 85: if (tTf(37,0)) ! 86: { ! 87: lprintf("entering ksort\n"); ! 88: prvect(pc,pv); ! 89: } ! 90: # endif ! 91: ! 92: Nfiles = 1; ! 93: Fileset = pv[0].pv_val.pv_str; ! 94: ! 95: /* first, the struct relation reldum */ ! 96: strcpy(Desc.reldum.relid, pv[3].pv_val.pv_str); ! 97: strcpy(Desc.reldum.relowner, pv[4].pv_val.pv_str); ! 98: Desc.reldum.relspec = pv[5].pv_val.pv_int; ! 99: Desc.reldum.relindxd = pv[6].pv_val.pv_int; ! 100: Desc.reldum.relstat2 = pv[7].pv_val.pv_int; ! 101: Desc.reldum.relstat = pv[8].pv_val.pv_int; ! 102: Desc.reldum.relsave = (long) pv[9].pv_val.pv_int; ! 103: Desc.reldum.reltups = (long) pv[10].pv_val.pv_int; ! 104: Desc.reldum.relatts = pv[11].pv_val.pv_int; ! 105: Desc.reldum.relwid = pv[12].pv_val.pv_int; ! 106: Desc.reldum.relprim = (long) pv[13].pv_val.pv_int; ! 107: Desc.reldum.relfree = (long) pv[14].pv_val.pv_int; ! 108: Desc.reldum.relstamp = (long) pv[15].pv_val.pv_int; ! 109: Desc.reldum.reldim = pv[16].pv_val.pv_int; ! 110: ! 111: strcpy(Desc.relvname, pv[17].pv_val.pv_str); ! 112: Desc.relfp = pv[18].pv_val.pv_int; ! 113: Desc.relopn = pv[19].pv_val.pv_int; ! 114: Desc.reladds = (long) pv[20].pv_val.pv_int; ! 115: Desc.reltid.ltid = pv[21].pv_val.pv_int; ! 116: j = 22; ! 117: for (i = 0; i <= Desc.reldum.relatts; ++i) ! 118: { ! 119: Desc.reloff[i] = pv[j++].pv_val.pv_int; ! 120: Desc.relfrmt[i] = pv[j++].pv_val.pv_int; ! 121: Desc.relfrml[i] = pv[j++].pv_val.pv_int; ! 122: Desc.relxtra[i] = pv[j++].pv_val.pv_int; ! 123: Desc.relgiven[i] = pv[j++].pv_val.pv_int; ! 124: } ! 125: ! 126: if (Desc.reldum.reldim > 0) ! 127: { ! 128: if ((Desc.relbtree = (DESC *) calloc(1, sizeof(DESC))) == NULL) ! 129: syserr("bad calloc in ksort"); ! 130: /* first, the struct relation reldum */ ! 131: strcpy(Desc.relbtree->reldum.relid, pv[j++].pv_val.pv_str); ! 132: strcpy(Desc.relbtree->reldum.relowner, pv[j++].pv_val.pv_str); ! 133: Desc.relbtree->reldum.relspec = pv[j++].pv_val.pv_int; ! 134: Desc.relbtree->reldum.relindxd = pv[j++].pv_val.pv_int; ! 135: Desc.relbtree->reldum.relstat2 = pv[j++].pv_val.pv_int; ! 136: Desc.relbtree->reldum.relstat = pv[j++].pv_val.pv_int; ! 137: Desc.relbtree->reldum.relsave = pv[j++].pv_val.pv_int; ! 138: Desc.relbtree->reldum.reltups = pv[j++].pv_val.pv_int; ! 139: Desc.relbtree->reldum.relatts = pv[j++].pv_val.pv_int; ! 140: Desc.relbtree->reldum.relwid = pv[j++].pv_val.pv_int; ! 141: Desc.relbtree->reldum.relprim = pv[j++].pv_val.pv_int; ! 142: Desc.relbtree->reldum.relfree = pv[j++].pv_val.pv_int; ! 143: Desc.relbtree->reldum.relstamp = pv[j++].pv_val.pv_int; ! 144: Desc.relbtree->reldum.reldim = pv[j++].pv_val.pv_int; ! 145: ! 146: strcpy(Desc.relbtree->relvname, pv[j++].pv_val.pv_str); ! 147: Desc.relbtree->relfp = pv[j++].pv_val.pv_int; ! 148: Desc.relbtree->relopn = pv[j++].pv_val.pv_int; ! 149: Desc.relbtree->reladds = pv[j++].pv_val.pv_int; ! 150: Desc.relbtree->reltid.ltid = pv[j++].pv_val.pv_int; ! 151: ! 152: for (i = 0; i <= Desc.relbtree->reldum.relatts; ++i) ! 153: { ! 154: Desc.relbtree->reloff[i] = pv[j++].pv_val.pv_int; ! 155: Desc.relbtree->relfrmt[i] = pv[j++].pv_val.pv_int; ! 156: Desc.relbtree->relfrml[i] = pv[j++].pv_val.pv_int; ! 157: Desc.relbtree->relxtra[i] = pv[j++].pv_val.pv_int; ! 158: Desc.relbtree->relgiven[i] = pv[j++].pv_val.pv_int; ! 159: } ! 160: } ! 161: ! 162: # ifdef xZTR1 ! 163: if (tTf(37,0)) ! 164: { ! 165: lprintf(" Desc read in \n"); ! 166: printdesc(&Desc); ! 167: } ! 168: #endif ! 169: ! 170: /* set up Descsort to indicate the sort order for tuple */ ! 171: /* if domain zero is given prepare to generate "hash bucket" ! 172: ** value for tuple */ ! 173: ! 174: maxkey = 0; ! 175: for (i = 0; i <= Desc.reldum.relatts; i++) ! 176: if (j = Desc.relgiven[i]) ! 177: { ! 178: if ((rev = j) < 0) ! 179: j = -j; ! 180: if (maxkey < j) ! 181: maxkey = j; ! 182: Descsort[--j] = rev < 0 ? -i : i; ! 183: } ! 184: ! 185: Descsort[maxkey] = ENDKEY; /* mark end of list */ ! 186: ! 187: Tupsize = Desc.reldum.relwid; ! 188: ! 189: if (Bucket = (Descsort[0] == 0)) ! 190: { ! 191: /* we will be generating hash bucket */ ! 192: Tupsize += BUCKETSIZE; ! 193: Desc.relfrml[0] = BUCKETSIZE; ! 194: Desc.relfrmt[0] = INT; ! 195: Desc.reloff[0] = Desc.reldum.relwid; ! 196: } ! 197: ! 198: # ifdef xZTR1 ! 199: if (tTf(37,0)) ! 200: { ! 201: lprintf("ksort: reldum.relatts is %d\n", Desc.reldum.relatts); ! 202: lprintf("Bucket is %d,Sort is:\n", Bucket); ! 203: for (i = 0; (j = Descsort[i]) != ENDKEY; i++) ! 204: lprintf("Descsort[%d]=%d\n", i, j); ! 205: } ! 206: # endif ! 207: if (i = (maxkey - Bucket - Desc.reldum.relatts)) ! 208: { ! 209: lprintf("MAXKEY=%d\n", maxkey); ! 210: lprintf("ATTS=%d\n", Desc.reldum.relatts); ! 211: syserr("%d domains missing\n", -i); ! 212: } ! 213: Infile = pv[1].pv_val.pv_str; ! 214: Outfile = pv[2].pv_val.pv_str; ! 215: ! 216: /* get up to 2**15 - 1 bytes of memory for buffers */ ! 217: /* note that mem must end up positive so that Nlines computation is right */ ! 218: mem = MEM; /* take at most 2**15 - 1 bytes */ ! 219: if (firstime) ! 220: { ! 221: while ((Lspace = (char **) malloc(mem)) == NULL) ! 222: mem -= 1024; ! 223: firstime = 0; ! 224: } ! 225: ! 226: /* compute pointers and sizes into buffer memory */ ! 227: Nlines = mem / (Tupsize + sizeof(char *)); ! 228: Tspace = (char *) (Lspace + Nlines); ! 229: # ifdef xZTR1 ! 230: if (tTf(37,0)) ! 231: lprintf("Tspace=%x,Lspace=%x,Nlines=%x,mem=%d\n", ! 232: Tspace, Lspace, Nlines, mem); ! 233: # endif ! 234: ! 235: /* set up temp files */ ! 236: concat(ztack("_SYSS", Fileset), "Xaa", File); ! 237: Filep = File; ! 238: while (*Filep != 'X') ! 239: Filep++; ! 240: Filep++; ! 241: ! 242: if (abs(Desc.reldum.relspec) == M_ORDER) ! 243: if ((Btree_fp = fopen(Infile, "r")) == NULL) ! 244: syserr("can't open %s", Infile); ! 245: ! 246: /* sort stage -- create a bunch of temporaries */ ! 247: Ccount = 0; ! 248: # ifdef xZTR1 ! 249: if (tTf(37,0)) ! 250: lprintf("sorting\n"); ! 251: # endif ! 252: sort(); ! 253: # ifdef xZTR1 ! 254: if (tTf(37,0)) ! 255: { ! 256: lprintf("done sorting\n%ld tuples written to %d files\n", Tupsout, Nfiles - 1); ! 257: lprintf("sort required %ld compares\n", Ccount); ! 258: } ! 259: # endif ! 260: ! 261: /* merge stage -- merge up to N temps into a new temp */ ! 262: Ccount = 0; ! 263: for (i = 1; i + N < Nfiles; i += N) ! 264: { ! 265: newfile(); ! 266: merge(i, i + N); ! 267: } ! 268: ! 269: /* merge last set of temps into target file */ ! 270: if (i != Nfiles) ! 271: { ! 272: oldfile(); ! 273: merge(i, Nfiles); ! 274: } ! 275: # ifdef xZTR1 ! 276: if (tTf(37,0)) ! 277: { ! 278: lprintf("%ld tuples in out file\n", Tupsout); ! 279: lprintf("merge required %ld compares\n", Ccount); ! 280: } ! 281: # endif ! 282: term(0); ! 283: } ! 284: /* ! 285: ** SORT ! 286: */ ! 287: ! 288: sort() ! 289: { ! 290: register char *cp; ! 291: register char **lp; ! 292: register int i; ! 293: int done; ! 294: long ntups; ! 295: struct tup_id tid, ltid; ! 296: char *xp; ! 297: long pageid; ! 298: long rhash(); ! 299: char btree[MAXNAME + 4], btreefile[MAXNAME + 4]; ! 300: char relfile[MAXNAME + 4], btreestruct[MAXNAME + 4]; ! 301: ! 302: done = 0; ! 303: ntups = 0; ! 304: Tupsout = 0; ! 305: if (abs(Desc.reldum.relspec) != M_ORDER) ! 306: { ! 307: if ((Desc.relfp = open(Infile, O_RDONLY)) < 0) ! 308: cant(Infile); ! 309: Desc.relopn = (Desc.relfp + 1) * 5; ! 310: } ! 311: if (Desc.reldum.reldim > 0 && abs(Desc.reldum.relspec != M_ORDER)) ! 312: /* open all needed btree files */ ! 313: { ! 314: capital(Desc.reldum.relid, btree); ! 315: ingresname(btree, Desc.reldum.relowner, btreefile); ! 316: if ((Desc.relbtree->relfp = open(btreefile, O_RDONLY)) < 0) ! 317: cant(btreefile); ! 318: Desc.relbtree->relopn = (Desc.relbtree->relfp + 1) * 5; ! 319: ingresname(Desc.reldum.relid, Desc.reldum.relowner, relfile); ! 320: btreename(relfile, btreestruct); ! 321: if ((Desc.btree_fd = open(btreestruct, O_RDWR)) < 0) ! 322: cant(btreestruct); ! 323: } ! 324: ! 325: /* initialize tids for full scan */ ! 326: pageid = 0; ! 327: tid.line_id = -1; ! 328: stuff_page(&tid, &pageid); ! 329: pageid = -1; ! 330: ltid.line_id = -1; ! 331: stuff_page(<id, &pageid); ! 332: ! 333: do ! 334: { ! 335: cp = Tspace; ! 336: lp = Lspace; ! 337: while (lp < Lspace + Nlines) ! 338: { ! 339: if (abs(Desc.reldum.relspec) == M_ORDER) ! 340: { ! 341: /* not reading from a relation */ ! 342: if ((i = fread(cp, 1, Desc.reldum.relwid, Btree_fp)) != Desc.reldum.relwid) ! 343: { ! 344: if (i != 0) ! 345: syserr("read error %d", i); ! 346: fclose(Btree_fp); ! 347: done++; ! 348: break; ! 349: } ! 350: } ! 351: else if ((i = kget(&Desc, &tid, <id, cp, TRUE)) != 0) ! 352: { ! 353: if (i < 0) ! 354: syserr("get %d", i); ! 355: close(Desc.relfp); ! 356: Desc.relopn = 0; ! 357: done++; ! 358: break; ! 359: } ! 360: # ifdef xZTR1 ! 361: if (tTf(37,0)) ! 362: printup(&Desc, cp); ! 363: # endif ! 364: if (Bucket) ! 365: { ! 366: /* compute hash bucket and insert at end */ ! 367: pageid = rhash(&Desc, cp); ! 368: bmove(&pageid, cp + Desc.reldum.relwid, BUCKETSIZE); ! 369: } ! 370: *lp++ = cp; ! 371: cp += Tupsize; ! 372: ntups++; ! 373: } ! 374: qsort(Lspace, lp - Lspace, sizeof(char *), cmpa); ! 375: if (done == 0 || Nfiles != 1) ! 376: newfile(); ! 377: else ! 378: oldfile(); ! 379: while (lp > Lspace) ! 380: { ! 381: cp = *--lp; ! 382: xp = cp; ! 383: if ((lp == Lspace) || (i = abs(cmpa(&xp, &lp[-1]))) != 0 || (i == 0 && abs(Desc.reldum.relspec) == M_ORDER)) ! 384: { ! 385: # ifdef xZTR1 ! 386: if (tTf(37,0)) ! 387: { ! 388: lprintf("writing "); ! 389: printup(&Desc, cp); ! 390: } ! 391: # endif ! 392: if ((i = fwrite(cp, 1, Tupsize, Oiop)) != Tupsize) ! 393: syserr("cant write outfile %d (%d)", i, Nfiles); ! 394: Tupsout++; ! 395: } ! 396: } ! 397: fclose(Oiop); ! 398: } while (done == 0); ! 399: if (Desc.reldum.reldim > 0 && Desc.reldum.relspec != M_ORDER) ! 400: { ! 401: close(Desc.relbtree->relfp); ! 402: Desc.relbtree->relopn = 0; ! 403: close(Desc.btree_fd); ! 404: } ! 405: # ifdef xZTR1 ! 406: if (tTf(37,0)) ! 407: lprintf("%ld tuples in\n", ntups); ! 408: # endif ! 409: } ! 410: /* ! 411: ** MERGE ! 412: */ ! 413: ! 414: struct merg ! 415: { ! 416: char tup[MAXTUP+BUCKETSIZE]; ! 417: int filedes; ! 418: FILE *fiop; ! 419: }; ! 420: ! 421: merge(a, b) ! 422: int a; ! 423: int b; ! 424: { ! 425: register struct merg *merg; ! 426: register int i, j; ! 427: char *f, *yesno; ! 428: struct merg *mbuf[N + 1]; ! 429: char *setfil(); ! 430: ! 431: # ifdef xZTR1 ! 432: if (tTf(37,0)) ! 433: lprintf("merge %d to %d\n", a, b); ! 434: # endif ! 435: merg = (struct merg *) Lspace; ! 436: j = 0; ! 437: for (i = a; i < b; i++) ! 438: { ! 439: f = setfil(i); ! 440: mbuf[j] = merg; ! 441: merg->filedes = i; ! 442: if ((merg->fiop = fopen(f, "r")) == NULL) ! 443: cant(f); ! 444: if (!rline(merg)) ! 445: j++; ! 446: merg++; ! 447: } ! 448: ! 449: i = j - 1; ! 450: # ifdef xZTR1 ! 451: if (tTf(37,0)) ! 452: lprintf("start merg with %d\n", i); ! 453: # endif ! 454: while (i >= 0) ! 455: { ! 456: # ifdef xZTR1 ! 457: if (tTf(37,0)) ! 458: lprintf("mintup %d\n", i); ! 459: # endif ! 460: if (mintup(mbuf, i, cmpa)) ! 461: { ! 462: if (fwrite(mbuf[i]->tup, 1, Tupsize, Oiop) != Tupsize) ! 463: syserr("cant write merge output"); ! 464: Tupsout++; ! 465: } ! 466: merg = mbuf[i]; ! 467: if (rline(merg)) ! 468: { ! 469: yesno = "not "; ! 470: # ifdef xZTR1 ! 471: if (!tTf(37,0)) ! 472: { ! 473: /* truncate temporary files to zero length */ ! 474: yesno = ""; ! 475: close(creat(setfil(merg->filedes), 0600)); ! 476: } ! 477: # endif ! 478: # ifdef xZTR1 ! 479: if (tTf(37,0)) ! 480: lprintf("dropping and %struncating %s\n", yesno, setfil(merg->filedes)); ! 481: # endif ! 482: i--; ! 483: } ! 484: } ! 485: ! 486: fclose(Oiop); ! 487: } ! 488: /* ! 489: ** Mintup puts the smallest tuple in mbuf[cnt-1]. ! 490: ** If the tuple is a duplicate of another then ! 491: ** mintup returns 0, else 1. ! 492: ** ! 493: ** Cnt is the number of compares to make; i.e. ! 494: ** mbuf[cnt] is the last element. ! 495: */ ! 496: ! 497: mintup(mbuf, cnt, cmpfunc) ! 498: struct merg *mbuf[]; ! 499: int cnt; ! 500: int (*cmpfunc)(); ! 501: { ! 502: register struct merg **next, **last; ! 503: struct merg *temp; ! 504: register int nodup; ! 505: int j; ! 506: ! 507: nodup = TRUE; ! 508: next = mbuf; ! 509: last = &next[cnt]; ! 510: ! 511: while (cnt--) ! 512: { ! 513: if (j = (*cmpfunc)(last, next)) ! 514: { ! 515: /* tuples not equal. keep smallest */ ! 516: if (j < 0) ! 517: { ! 518: /* exchange */ ! 519: temp = *last; ! 520: *last = *next; ! 521: *next = temp; ! 522: nodup = TRUE; ! 523: } ! 524: } ! 525: else ! 526: nodup = FALSE; ! 527: ! 528: next++; ! 529: } ! 530: return (nodup); ! 531: } ! 532: ! 533: ! 534: rline(mp) ! 535: struct merg *mp; ! 536: { ! 537: register struct merg *merg; ! 538: register int i; ! 539: ! 540: merg = mp; ! 541: if ((i = fread(merg->tup, 1, Tupsize, merg->fiop)) != Tupsize) ! 542: { ! 543: if (i == 0) ! 544: { ! 545: fclose(merg->fiop); ! 546: return (1); ! 547: } ! 548: syserr("rd err %d on %s", i, setfil(merg->filedes)); ! 549: } ! 550: return (0); ! 551: } ! 552: ! 553: newfile() ! 554: { ! 555: char *setfil(); ! 556: ! 557: makfile(setfil(Nfiles)); ! 558: Nfiles++; ! 559: } ! 560: /* ! 561: ** Convert the number i to a char ! 562: ** sequence aa, ab, ..., az, ba, etc. ! 563: */ ! 564: ! 565: char * ! 566: setfil(i) ! 567: int i; ! 568: { ! 569: register int j; ! 570: ! 571: j = i; ! 572: j--; ! 573: Filep[0] = j/26 + 'a'; ! 574: Filep[1] = j%26 + 'a'; ! 575: return (File); ! 576: } ! 577: ! 578: oldfile() ! 579: { ! 580: makfile(Outfile); ! 581: Tupsout = 0; ! 582: } ! 583: /* ! 584: ** Create a file by the name "name" ! 585: ** and place its fio pointer in Oiop ! 586: */ ! 587: ! 588: makfile(name) ! 589: char *name; ! 590: { ! 591: if ((Oiop = fopen(name, "w")) == NULL) ! 592: cant(name); ! 593: } ! 594: ! 595: cant(f) ! 596: char *f; ! 597: { ! 598: syserr("open %s", f); ! 599: } ! 600: ! 601: term(error) ! 602: int error; ! 603: { ! 604: register int i; ! 605: ! 606: if (Nfiles == 1) ! 607: Nfiles++; ! 608: # ifdef xZTR1 ! 609: if (tTf(37,0)) ! 610: lprintf("temp files not removed\n"); ! 611: else ! 612: # endif ! 613: for (i = 1; i < Nfiles; i++) ! 614: { ! 615: unlink(setfil(i)); ! 616: } ! 617: return(error); ! 618: } ! 619: /* ! 620: ** CMPA -- compare tuples ! 621: */ ! 622: ! 623: cmpa(a, b) ! 624: char **a; ! 625: char **b; ! 626: { ! 627: int af[4]; ! 628: int bf[4]; ! 629: char *pa, *pb; ! 630: register union anytype *tupa, *tupb; ! 631: int dom; ! 632: register int frml; ! 633: int frmt; ! 634: int off; ! 635: int temp; ! 636: int rt; ! 637: char *dp; ! 638: ! 639: pa = *a; ! 640: pb = *b; ! 641: Ccount++; ! 642: dp = Descsort; ! 643: while ((temp = *dp++) != ENDKEY) ! 644: { ! 645: if ((dom = temp) < 0) ! 646: dom = -temp; ! 647: frml = Desc.relfrml[dom]; ! 648: frmt = Desc.relfrmt[dom]; ! 649: off = Desc.reloff[dom]; ! 650: tupa = (union anytype *) &pa[off]; ! 651: tupb = (union anytype *) &pb[off]; ! 652: if (temp < 0) ! 653: { ! 654: tupb = tupa; ! 655: tupa = (union anytype *) &pb[off]; ! 656: } ! 657: if (frmt == CHAR) ! 658: { ! 659: frml &= I1MASK; ! 660: if (rt = scompare(tupb, frml, tupa, frml)) ! 661: return (rt); ! 662: continue; ! 663: } ! 664: ! 665: /* domain is a numeric type */ ! 666: if (bequal(tupa, tupb, frml)) ! 667: continue; ! 668: /* copy to even word boundary */ ! 669: bmove(tupa, af, frml); ! 670: bmove(tupb, bf, frml); ! 671: tupa = (union anytype *) af; ! 672: tupb = (union anytype *) bf; ! 673: ! 674: switch (frmt) ! 675: { ! 676: ! 677: case INT: ! 678: switch (frml) ! 679: { ! 680: ! 681: case 1: ! 682: return (tupa->i1type > tupb->i1type ? -1 : 1); ! 683: ! 684: case 2: ! 685: return (tupa->i2type > tupb->i2type ? -1 : 1); ! 686: ! 687: case 4: ! 688: return (tupa->i4type > tupb->i4type ? -1 : 1); ! 689: } ! 690: ! 691: case FLOAT: ! 692: switch (frml) ! 693: { ! 694: ! 695: case 4: ! 696: return (tupa->f4type > tupb->f4type ? -1 : 1); ! 697: ! 698: case 8: ! 699: return (tupa->f8type > tupb->f8type ? -1 : 1); ! 700: } ! 701: } ! 702: } ! 703: return (0); ! 704: } ! 705: /* ! 706: ** KGET_PAGE ! 707: ** Replacement for access method routine get_page(); ! 708: ** and associated globals and routines. ! 709: */ ! 710: ! 711: long Accuread, Accuwrite; ! 712: ! 713: kget_page(d, tid) ! 714: register DESC *d; ! 715: struct tup_id *tid; ! 716: { ! 717: register int i; ! 718: long pageid; ! 719: register struct accbuf *b; ! 720: extern struct accbuf *choose_buf(); ! 721: ! 722: # ifdef xZTR1 ! 723: if (tTf(37,0)) ! 724: { ! 725: lprintf("kget_page: %.14s,", d->reldum.relid); ! 726: dumptid(tid); ! 727: } ! 728: # endif ! 729: pluck_page(tid, &pageid); ! 730: if ((b = choose_buf(d, pageid)) == NULL) ! 731: { ! 732: # ifdef xZTR1 ! 733: if (tTf(37,0)) ! 734: lprintf(" choose_buf: buffer not avail \n"); ! 735: # endif ! 736: return(-1); ! 737: } ! 738: top_acc(b); ! 739: ! 740: i = 0; ! 741: if (b->thispage != pageid) ! 742: { ! 743: # ifdef xZTR1 ! 744: if (tTf(37,0)) ! 745: lprintf("kget_page: rdg pg %ld\n", pageid); ! 746: # endif ! 747: b->thispage = pageid; ! 748: if ((lseek(d->relfp, pageid * PGSIZE, 0) < 0) || ! 749: ((read(d->relfp, b, PGSIZE)) != PGSIZE)) ! 750: { ! 751: i = AMREAD_ERR; ! 752: } ! 753: Accuread++; ! 754: } ! 755: return (i); ! 756: } ! 757: ! 758: /* ! 759: ** KGET - get a single tuple ! 760: ** ! 761: ** Get either gets the next sequencial tuple after ! 762: ** "tid" or else gets the tuple specified by tid. ! 763: ** ! 764: ** If getnxt == TRUE, then tid is incremented to the next ! 765: ** tuple after tid. If there are no more, then get returns ! 766: ** 1. Otherwise get returns 0 and "tid" is set to the tid of ! 767: ** the returned tuple. ! 768: ** ! 769: ** Under getnxt mode, the previous page is reset before ! 770: ** the next page is read. This is done to prevent the previous ! 771: ** page from hanging around in the am's buffers when we "know" ! 772: ** that it will not be referenced again. ! 773: ** ! 774: ** If getnxt == FALSE then the tuple specified by tid is ! 775: ** returned. If the tuple was deleted previously, ! 776: ** get retuns 2 else get returns 0. ! 777: ** ! 778: ** If getnxt is true, limtid holds the the page number ! 779: ** of the first page past the end point. Limtid and the ! 780: ** initial value of tid are set by calls to FIND. ! 781: ** ! 782: ** returns: ! 783: ** <0 fatal error ! 784: ** 0 success ! 785: ** 1 end of scan (getnxt=TRUE only) ! 786: ** 2 tuple deleted (getnxt=FALSE only) ! 787: */ ! 788: ! 789: ! 790: kget(d, tid, limtid, tuple, getnxt) ! 791: register DESC *d; ! 792: register TID *tid; ! 793: TID *limtid; ! 794: int getnxt; ! 795: char *tuple; ! 796: { ! 797: register int i; ! 798: long pageid, lpageid; ! 799: ! 800: # ifdef xATR1 ! 801: if (tTf(23, 0) || tTf(37,0)) ! 802: { ! 803: lprintf("kget: %.14s,", d->reldum.relid); ! 804: dumptid(tid); ! 805: lprintf("kget: lim"); ! 806: dumptid(limtid); ! 807: } ! 808: # endif ! 809: if (kget_page(d, tid)) ! 810: { ! 811: return (-1); ! 812: } ! 813: if (getnxt) ! 814: { ! 815: pluck_page(limtid, &lpageid); ! 816: do ! 817: { ! 818: while (((++(tid->line_id)) & I1MASK) >= Acc_head->nxtlino) ! 819: { ! 820: tid->line_id = -1; ! 821: pageid = Acc_head->ovflopg; ! 822: stuff_page(tid, &pageid); ! 823: if (pageid == 0) ! 824: { ! 825: pageid = Acc_head->mainpg; ! 826: stuff_page(tid, &pageid); ! 827: if (pageid == 0 || pageid == lpageid + 1) ! 828: return (1); ! 829: } ! 830: if (i = resetacc(Acc_head)) ! 831: return (i); ! 832: if (i = get_page(d, tid)) ! 833: return (i); ! 834: } ! 835: } while (!Acc_head->linetab[-(tid->line_id & I1MASK)]); ! 836: } ! 837: else ! 838: { ! 839: if (i = invalid(tid)) ! 840: return (i); ! 841: } ! 842: get_tuple(d, tid, tuple); ! 843: # ifdef xATR2 ! 844: if (tTf(23, 1) || tTf(37,0)) ! 845: { ! 846: printf("kget: "); ! 847: printup(d, tuple); ! 848: } ! 849: # endif ! 850: return (0); ! 851: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.