Annotation of 42BSD/ingres/source/dbu/ksort.c, revision 1.1

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      <sccs.h>
        !             8: 
        !             9: SCCSID(@(#)ksort.c     7.3     8/24/83)
        !            10: 
        !            11: # define       N       7
        !            12: # define       MEM     (32768 - 2)
        !            13: # define       BUCKETSIZE      4
        !            14: # define       ENDKEY  MAXDOM + 1
        !            15: 
        !            16: 
        !            17: 
        !            18: /*
        !            19: **     Parameters:
        !            20: **
        !            21: **             argv[1]:        Fileset
        !            22: **             argv[2]:        trace info (see below)
        !            23: **             argv[3]:        file from which Desc is read
        !            24: **             argv[4]:        Infile
        !            25: **             argv[5]:        Outfile
        !            26: **
        !            27: **
        !            28: **     Trace info comes from trace flag Z37 passed as the
        !            29: **     second parameter. The bits used are:
        !            30: **
        !            31: **             0001    main trace info
        !            32: **             0002    secondary trace info
        !            33: **             0004    terciary trace info
        !            34: **             0010    don't truncate temps
        !            35: **             0020    don't unlink temps
        !            36: **             0040    print am page refs
        !            37: **             0100    print am tuple gets
        !            38: **             0200    print tuples as output
        !            39: */
        !            40: 
        !            41: char           *Infile;
        !            42: char           *Outfile;
        !            43: DESC           Desc;
        !            44: char           Descsort[MAXDOM+1];
        !            45: FILE           *Oiop;
        !            46: int            Trace;
        !            47: int            Tupsize;
        !            48: int            Bucket;
        !            49: char           File[15];
        !            50: char           *Fileset;
        !            51: char           *Filep;
        !            52: int            Nfiles          = 1;
        !            53: int            Nlines;
        !            54: long           Ccount;
        !            55: char           **Lspace;
        !            56: char           *Tspace;
        !            57: extern int     cmpa();
        !            58: long           Tupsout;
        !            59: short          Tr[100];
        !            60: 
        !            61: main(argc, argv)
        !            62: int    argc;
        !            63: char   **argv;
        !            64: {
        !            65:        extern char     *Proc_name;
        !            66:        register int    i;
        !            67:        register int    j;
        !            68:        unsigned int    mem;
        !            69:        char            *start;
        !            70:        int             maxkey, rev;
        !            71:        extern char     *malloc();
        !            72: 
        !            73: 
        !            74:        Proc_name = "KSORT";
        !            75:        tT = Tr;
        !            76:        if (argc != 6)
        !            77:                syserr("argc");
        !            78:        Fileset = argv[1];
        !            79:        Trace = atoi(argv[2]);
        !            80:        if ((i = open(argv[3], 0)) < 0)
        !            81:                cant(argv[3]);
        !            82:        if (read(i, &Desc, sizeof Desc) < sizeof Desc)
        !            83:                syserr("read(Desc)");
        !            84:        close(i);
        !            85: 
        !            86:        /* set up Descsort to indicate the sort order for tuple */
        !            87:        /* if domain zero is given prepare to generate "hash bucket"
        !            88:        ** value for tuple */
        !            89: 
        !            90:        maxkey = 0;
        !            91:        for (i = 0; i <= Desc.reldum.relatts; i++)
        !            92:                if (j = Desc.relgiven[i])
        !            93:                {
        !            94:                        if ((rev = j) < 0)
        !            95:                                j = -j;
        !            96:                        if (maxkey < j)
        !            97:                                maxkey = j;
        !            98:                        Descsort[--j] = rev < 0 ? -i : i;
        !            99:                }
        !           100: 
        !           101:        Descsort[maxkey] = ENDKEY;      /* mark end of list */
        !           102: 
        !           103:        Tupsize = Desc.reldum.relwid;
        !           104: 
        !           105:        if (Bucket = (Descsort[0] == 0))
        !           106:        {
        !           107:                /* we will be generating hash bucket */
        !           108:                Tupsize += BUCKETSIZE;
        !           109:                Desc.relfrml[0] = BUCKETSIZE;
        !           110:                Desc.relfrmt[0] = INT;
        !           111:                Desc.reloff[0] = Desc.reldum.relwid;
        !           112:        }
        !           113: 
        !           114:        if (Trace & 01)
        !           115:        {
        !           116:                printf("ksort: reldum.relatts is %d\n", Desc.reldum.relatts);
        !           117:                printf("Bucket is %d,Sort is:\n", Bucket);
        !           118:                for (i = 0; (j = Descsort[i]) != ENDKEY; i++)
        !           119:                        printf("Descsort[%d]=%d\n", i, j);
        !           120:        }
        !           121:        if (i = (maxkey - Bucket - Desc.reldum.relatts))
        !           122:                syserr("%d domains missing\n", -i);
        !           123:        Infile = argv[4];
        !           124:        Outfile = argv[5];
        !           125: 
        !           126:        /* get up to 2**15 - 1 bytes of memory for buffers */
        !           127:        /* note that mem must end up positive so that Nlines computation is right */
        !           128:        mem = MEM;      /* take at most 2**15 - 1 bytes */
        !           129:        while ((Lspace = (char **) malloc(mem)) == NULL)
        !           130:                mem -= 1024;
        !           131: 
        !           132:        /* compute pointers and sizes into buffer memory */
        !           133:        Nlines = mem / (Tupsize + sizeof(char *));
        !           134:        Tspace = (char *) (Lspace + Nlines);
        !           135:        if (Trace & 01)
        !           136:                printf("Tspace=%x,Lspace=%x,Nlines=%x,mem=%d\n",
        !           137:                        Tspace, Lspace, Nlines, mem);
        !           138: 
        !           139:        /* set up temp files */
        !           140:        concat(ztack("_SYSS", Fileset), "Xaa", File);
        !           141:        Filep = File;
        !           142:        while (*Filep != 'X')
        !           143:                Filep++;
        !           144:        Filep++;
        !           145: 
        !           146:        /* sort stage -- create a bunch of temporaries */
        !           147:        Ccount = 0;
        !           148:        if (Trace & 01)
        !           149:                printf("sorting\n");
        !           150:        sort();
        !           151:        close(0);
        !           152:        if (Trace & 01)
        !           153:        {
        !           154:                printf("done sorting\n%ld tuples written to %d files\n", Tupsout, Nfiles - 1);
        !           155:                printf("sort required %ld compares\n", Ccount);
        !           156:        }
        !           157: 
        !           158:        /* merge stage -- merge up to N temps into a new temp */
        !           159:        Ccount = 0;
        !           160:        for (i = 1; i + N < Nfiles; i += N) 
        !           161:        {
        !           162:                newfile();
        !           163:                merge(i, i + N);
        !           164:        }
        !           165: 
        !           166:        /* merge last set of temps into target file */
        !           167:        if (i != Nfiles) 
        !           168:        {
        !           169:                oldfile();
        !           170:                merge(i, Nfiles);
        !           171:        }
        !           172:        if (Trace & 01)
        !           173:        {
        !           174:                printf("%ld tuples in out file\n", Tupsout);
        !           175:                printf("merge required %ld compares\n", Ccount);
        !           176:        }
        !           177:        term(0);
        !           178: }
        !           179: /*
        !           180: **  SORT
        !           181: */
        !           182: 
        !           183: sort()
        !           184: {
        !           185:        register char   *cp;
        !           186:        register char   **lp;
        !           187:        register int    i;
        !           188:        int             done;
        !           189:        long            ntups;
        !           190:        struct tup_id   tid, ltid;
        !           191:        char            *xp;
        !           192:        long            pageid;
        !           193:        long            rhash();
        !           194: 
        !           195:        done = 0;
        !           196:        ntups = 0;
        !           197:        Tupsout = 0;
        !           198:        if ((Desc.relfp = open(Infile, 0)) < 0)
        !           199:                cant(Infile);
        !           200:        Desc.relopn = (Desc.relfp + 1) * 5;
        !           201: 
        !           202:        /* initialize tids for full scan */
        !           203:        pageid = 0;
        !           204:        tid.line_id = -1;
        !           205:        stuff_page(&tid, &pageid);
        !           206:        pageid = -1;
        !           207:        ltid.line_id = -1;
        !           208:        stuff_page(&ltid, &pageid);
        !           209: 
        !           210:        do 
        !           211:        {
        !           212:                cp = Tspace;
        !           213:                lp = Lspace;
        !           214:                while (lp < Lspace + Nlines)
        !           215:                {
        !           216:                        if ((i = get(&Desc, &tid, &ltid, cp, TRUE)) != 0)
        !           217:                        {
        !           218:                                if (i < 0)
        !           219:                                        syserr("get %d", i);
        !           220:                                close(Desc.relfp);
        !           221:                                Desc.relopn = 0;
        !           222:                                done++;
        !           223:                                break;
        !           224:                        }
        !           225:                        if (Trace & 0100)
        !           226:                                printup(&Desc, cp);
        !           227:                        if (Bucket)
        !           228:                        {
        !           229:                                /* compute hash bucket and insert at end */
        !           230:                                pageid = rhash(&Desc, cp);
        !           231:                                bmove(&pageid, cp + Desc.reldum.relwid, BUCKETSIZE);
        !           232:                        }
        !           233:                        *lp++ = cp;
        !           234:                        cp += Tupsize;
        !           235:                        ntups++;
        !           236:                }
        !           237:                qsort(Lspace, lp - Lspace, sizeof(char *), cmpa);
        !           238:                if (done == 0 || Nfiles != 1)
        !           239:                        newfile();
        !           240:                else
        !           241:                        oldfile();
        !           242:                while (lp > Lspace) 
        !           243:                {
        !           244:                        cp = *--lp;
        !           245:                        xp = cp;
        !           246:                        if ((lp == Lspace) || (cmpa(&xp, &lp[-1]) != 0))
        !           247:                        {
        !           248:                                if (Trace & 0200)
        !           249:                                {
        !           250:                                        printf("writing ");
        !           251:                                        printup(&Desc, cp);
        !           252:                                }
        !           253:                                if ((i = fwrite(cp, 1, Tupsize, Oiop)) != Tupsize)
        !           254:                                        syserr("cant write outfile %d (%d)", i, Nfiles);
        !           255:                                Tupsout++;
        !           256:                        }
        !           257:                }
        !           258:                fclose(Oiop);
        !           259:        } while (done == 0);
        !           260:        if (Trace & 01)
        !           261:                printf("%ld tuples in\n", ntups);
        !           262: }
        !           263: /*
        !           264: **  MERGE
        !           265: */
        !           266: 
        !           267: struct merg
        !           268: {
        !           269:        char            tup[MAXTUP+BUCKETSIZE];
        !           270:        int             filedes;
        !           271:        FILE            *fiop;
        !           272: };
        !           273: 
        !           274: merge(a, b)
        !           275: int    a;
        !           276: int    b;
        !           277: {
        !           278:        register struct merg    *merg;
        !           279:        register int            i, j;
        !           280:        char                    *f, *yesno;
        !           281:        struct merg             *mbuf[N + 1];
        !           282:        char                    *setfil();
        !           283: 
        !           284:        if (Trace & 02)
        !           285:                printf("merge %d to %d\n", a, b);
        !           286:        merg = (struct merg *) Lspace;
        !           287:        j = 0;
        !           288:        for (i = a; i < b; i++) 
        !           289:        {
        !           290:                f = setfil(i);
        !           291:                mbuf[j] = merg;
        !           292:                merg->filedes = i;
        !           293:                if ((merg->fiop = fopen(f, "r")) == NULL)
        !           294:                        cant(f);
        !           295:                if (!rline(merg))
        !           296:                        j++;
        !           297:                merg++;
        !           298:        }
        !           299: 
        !           300:        i = j - 1;
        !           301:        if (Trace & 04)
        !           302:                printf("start merg with %d\n", i);
        !           303:        while (i >= 0) 
        !           304:        {
        !           305:                if (Trace & 04)
        !           306:                        printf("mintup %d\n", i);
        !           307:                if (mintup(mbuf, i, cmpa))
        !           308:                {
        !           309:                        if (fwrite(mbuf[i]->tup, 1, Tupsize, Oiop) != Tupsize)
        !           310:                                syserr("cant write merge output");
        !           311:                        Tupsout++;
        !           312:                }
        !           313:                merg = mbuf[i];
        !           314:                if (rline(merg))
        !           315:                {
        !           316:                        yesno = "not ";
        !           317:                        if (!(Trace & 010))
        !           318:                        {
        !           319:                                /* truncate temporary files to zero length */
        !           320:                                yesno = "";
        !           321:                                close(creat(setfil(merg->filedes), 0600));
        !           322:                        }
        !           323:                        if (Trace & 02 || Trace & 010)
        !           324:                                printf("dropping and %struncating %s\n", yesno, setfil(merg->filedes));
        !           325:                        i--;
        !           326:                }
        !           327:        }
        !           328: 
        !           329:        fclose(Oiop);
        !           330: }
        !           331: /*
        !           332: **     Mintup puts the smallest tuple in mbuf[cnt-1].
        !           333: **     If the tuple is a duplicate of another then
        !           334: **     mintup returns 0, else 1.
        !           335: **
        !           336: **     Cnt is the number of compares to make; i.e.
        !           337: **     mbuf[cnt] is the last element.
        !           338: */
        !           339: 
        !           340: mintup(mbuf, cnt, cmpfunc)
        !           341: struct merg    *mbuf[];
        !           342: int            cnt;
        !           343: int            (*cmpfunc)();
        !           344: {
        !           345:        register struct merg    **next, **last;
        !           346:        struct merg             *temp;
        !           347:        register int            nodup;
        !           348:        int                     j;
        !           349: 
        !           350:        nodup = TRUE;
        !           351:        next = mbuf;
        !           352:        last = &next[cnt];
        !           353: 
        !           354:        while (cnt--)
        !           355:        {
        !           356:                if (j = (*cmpfunc)(last, next))
        !           357:                {
        !           358:                        /* tuples not equal. keep smallest */
        !           359:                        if (j < 0)
        !           360:                        {
        !           361:                                /* exchange */
        !           362:                                temp = *last;
        !           363:                                *last = *next;
        !           364:                                *next = temp;
        !           365:                                nodup = TRUE;
        !           366:                        }
        !           367:                }
        !           368:                else
        !           369:                        nodup = FALSE;
        !           370: 
        !           371:                next++;
        !           372:        }
        !           373:        return (nodup);
        !           374: }
        !           375: 
        !           376: 
        !           377: rline(mp)
        !           378: struct merg    *mp;
        !           379: {
        !           380:        register struct merg    *merg;
        !           381:        register int            i;
        !           382: 
        !           383:        merg = mp;
        !           384:        if ((i = fread(merg->tup, 1, Tupsize, merg->fiop)) != Tupsize)
        !           385:        {
        !           386:                if (i == 0)
        !           387:                {
        !           388:                        fclose(merg->fiop);
        !           389:                        return (1);
        !           390:                }
        !           391:                syserr("rd err %d on %s", i, setfil(merg->filedes));
        !           392:        }
        !           393:        return (0);
        !           394: }
        !           395: 
        !           396: newfile()
        !           397: {
        !           398:        char    *setfil();
        !           399: 
        !           400:        makfile(setfil(Nfiles));
        !           401:        Nfiles++;
        !           402: }
        !           403: /*
        !           404: **     Convert the number i to a char
        !           405: **     sequence aa, ab, ..., az, ba, etc.
        !           406: */
        !           407: 
        !           408: char *
        !           409: setfil(i)
        !           410: int    i;
        !           411: {
        !           412:        register int    j;
        !           413: 
        !           414:        j = i;
        !           415:        j--;
        !           416:        Filep[0] = j/26 + 'a';
        !           417:        Filep[1] = j%26 + 'a';
        !           418:        return (File);
        !           419: }
        !           420: 
        !           421: oldfile()
        !           422: {
        !           423:        makfile(Outfile);
        !           424:        Tupsout = 0;
        !           425: }
        !           426: /*
        !           427: **     Create a file by the name "name"
        !           428: **     and place its fio pointer in Oiop
        !           429: */
        !           430: 
        !           431: makfile(name)
        !           432: char   *name;
        !           433: {
        !           434:        if ((Oiop = fopen(name, "w")) == NULL)
        !           435:                cant(name);
        !           436: }
        !           437: 
        !           438: cant(f)
        !           439: char   *f;
        !           440: {
        !           441:        syserr("open %s", f);
        !           442: }
        !           443: 
        !           444: term(error)
        !           445: int    error;
        !           446: {
        !           447:        register int    i;
        !           448: 
        !           449:        if (Nfiles == 1)
        !           450:                Nfiles++;
        !           451:        if (Trace & 020)
        !           452:                printf("temp files not removed\n");
        !           453:        else
        !           454:                for (i = 1; i < Nfiles; i++) 
        !           455:                {
        !           456:                        unlink(setfil(i));
        !           457:                }
        !           458:        exit(error);
        !           459: }
        !           460: /*
        !           461: **  CMPA -- compare tuples
        !           462: */
        !           463: 
        !           464: cmpa(a, b)
        !           465: char   **a;
        !           466: char   **b;
        !           467: {
        !           468:        int                     af[4];
        !           469:        int                     bf[4];
        !           470:        char                    *pa, *pb;
        !           471:        register union anytype  *tupa, *tupb;
        !           472:        int                     dom;
        !           473:        register int            frml;
        !           474:        int                     frmt;
        !           475:        int                     off;
        !           476:        int                     temp;
        !           477:        int                     rt;
        !           478:        char                    *dp;
        !           479: 
        !           480:        pa = *a;
        !           481:        pb = *b;
        !           482:        Ccount++;
        !           483:        dp = Descsort;
        !           484:        while ((temp = *dp++) != ENDKEY)
        !           485:        {
        !           486:                if ((dom = temp) < 0)
        !           487:                        dom = -temp;
        !           488:                frml = Desc.relfrml[dom];
        !           489:                frmt = Desc.relfrmt[dom];
        !           490:                off = Desc.reloff[dom];
        !           491:                tupa = (union anytype *) &pa[off];
        !           492:                tupb = (union anytype *) &pb[off];
        !           493:                if (temp < 0)
        !           494:                {
        !           495:                        tupb = tupa;
        !           496:                        tupa = (union anytype *) &pb[off];
        !           497:                }
        !           498:                if (frmt == CHAR)
        !           499:                {
        !           500:                        frml &= 0377;
        !           501:                        if (rt = scompare(tupb, frml, tupa, frml))
        !           502:                                return (rt);
        !           503:                        continue;
        !           504:                }
        !           505: 
        !           506:                /* domain is a numeric type */
        !           507:                if (bequal(tupa, tupb, frml))
        !           508:                        continue;
        !           509:                /* copy to even word boundary */
        !           510:                bmove(tupa, af, frml);
        !           511:                bmove(tupb, bf, frml);
        !           512:                tupa = (union anytype *) af;
        !           513:                tupb = (union anytype *) bf;
        !           514: 
        !           515:                switch (frmt)
        !           516:                {
        !           517: 
        !           518:                  case INT:
        !           519:                        switch (frml)
        !           520:                        {
        !           521: 
        !           522:                          case 1:
        !           523:                                return (tupa->i1type > tupb->i1type ? -1 : 1);
        !           524: 
        !           525:                          case 2:
        !           526:                                return (tupa->i2type > tupb->i2type ? -1 : 1);
        !           527: 
        !           528:                          case 4:
        !           529:                                return (tupa->i4type > tupb->i4type ? -1 : 1);
        !           530:                        }
        !           531: 
        !           532:                  case FLOAT:
        !           533:                        switch (frml)
        !           534:                        {
        !           535: 
        !           536:                          case 4:
        !           537:                                return (tupa->f4type > tupb->f4type ? -1 : 1);
        !           538: 
        !           539:                          case 8:
        !           540:                                return (tupa->f8type > tupb->f8type ? -1 : 1);
        !           541:                        }
        !           542:                }
        !           543:        }
        !           544:        return (0);
        !           545: }
        !           546: /*
        !           547: **     Replacement for access method routine get_page();
        !           548: **     and associated globals and routines.
        !           549: */
        !           550: 
        !           551: struct accbuf  *Acc_head, Accbuf;
        !           552: long           Accuread, Accuwrite;
        !           553: 
        !           554: get_page(d, tid)
        !           555: register DESC  *d;
        !           556: struct tup_id  *tid;
        !           557: {
        !           558:        register int            i;
        !           559:        long                    pageid;
        !           560:        register struct accbuf  *b;
        !           561: 
        !           562:        if (Trace & 0100)
        !           563:        {
        !           564:                printf("get_page: %.14s,", d->reldum.relid);
        !           565:                dumptid(tid);
        !           566:        }
        !           567:        b = Acc_head;
        !           568:        if (b == 0)
        !           569:        {
        !           570:                /* initialize buffer */
        !           571:                Acc_head = &Accbuf;
        !           572:                b = &Accbuf;
        !           573:                b->thispage = -1;
        !           574:        }
        !           575:        pluck_page(tid, &pageid);
        !           576:        i = 0;
        !           577:        if (b->thispage != pageid)
        !           578:        {
        !           579:                if (Trace & 040)
        !           580:                        printf("get_page: rdg pg %ld\n", pageid);
        !           581:                b->thispage = pageid;
        !           582:                if ((lseek(d->relfp, pageid * PGSIZE, 0) < 0) ||
        !           583:                    ((read(d->relfp, b, PGSIZE)) != PGSIZE))
        !           584:                {
        !           585:                        i = AMREAD_ERR;
        !           586:                }
        !           587:                Accuread++;
        !           588:        }
        !           589:        return (i);
        !           590: }
        !           591: 
        !           592: resetacc(buf)
        !           593: struct accbuf  *buf;
        !           594: {
        !           595:        return (0);
        !           596: }
        !           597: 
        !           598: acc_err(err)
        !           599: int    err;
        !           600: {
        !           601:        return (err);
        !           602: 
        !           603: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.