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(&ltid, &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, &ltid, 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: }

Defined functions

cant defined in line 595; used 5 times
cmpa defined in line 623; used 4 times
kget defined in line 790; used 1 times
kget_page defined in line 713; used 1 times
ksort defined in line 72; used 2 times
makfile defined in line 588; used 2 times
merge defined in line 421; used 2 times
mintup defined in line 497; used 1 times
newfile defined in line 553; used 2 times
oldfile defined in line 578; used 2 times
rline defined in line 534; used 2 times
setfil defined in line 565; used 8 times
sort defined in line 288; used 1 times
term defined in line 601; used 1 times

Defined variables

Accuread defined in line 711; used 1 times
Accuwrite defined in line 711; never used
Btree_fd defined in line 69; used 6 times
Bucket defined in line 56; used 4 times
Ccount defined in line 61; used 5 times
Descsort defined in line 53; used 5 times
File defined in line 57; used 3 times
Filep defined in line 59; used 6 times
Fileset defined in line 58; used 2 times
Infile defined in line 50; used 5 times
KsortFn defined in line 36; never used
Lspace defined in line 62; used 10 times
Nfiles defined in line 70; used 12 times
Nlines defined in line 60; used 4 times
Outfile defined in line 51; used 2 times
Tspace defined in line 63; used 3 times
Tupsize defined in line 55; used 10 times
Tupsout defined in line 65; used 6 times
firstime defined in line 66; used 2 times

Defined struct's

merg defined in line 414; used 16 times

Defined macros

BUCKETSIZE defined in line 16; used 4 times
ENDKEY defined in line 17; used 3 times
MEM defined in line 15; used 1 times
N defined in line 14; used 4 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1886
Valid CSS Valid XHTML 1.0 Strict