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: }