diff --git a/WEGA/contrib/ingres/dbs/src/dbu/dbu___s.c b/WEGA/contrib/ingres/dbs/src/dbu/dbu___s.c new file mode 100644 index 0000000..5698726 --- /dev/null +++ b/WEGA/contrib/ingres/dbs/src/dbu/dbu___s.c @@ -0,0 +1,733 @@ +# include +# include "gen.h" +# include "../h/dbs.h" +# include "../h/aux.h" +# include "../h/symbol.h" +# include "../h/access.h" + +# define N MERGESIZE +# ifdef MEM_E +# define MEM COREBUFSIZE +char start[MEM] = {0}; +# else +# define MEM ((char *) COREBUFSIZE) +# endif +# define BUCKETSIZE sizeof (long) +# define ENDKEY (MAXDOM + 1) + +char SYSSORT[] = "_SYS"; + +static char File[15]; +static char DBU_buf[TUP_BUF_SIZ]; +static char *DBU_ptr; +static char Descsort[MAXDOM + 1]; +static DESC Desc; +static char **Lspace; +static char *Tspace; +static char *Infile; +static char *Outfile; +char *Fileset; +static char *Filep; +char *AApath; +static long Ccount; +static long Page; +static long Tupsout; +static int Outpipe = -2; /* fd to write to modify */ +static unsigned int Memory; /* available memory buffer size */ +# ifdef VPGSIZE +int AApgsize = PGSIZE; +int AAmaxtup = MAXTUP; +int AAltsize = 0; +# endif +static short Trace; +static short Bucket; +static short Nfiles; +static short Nlines; +static short Reorg; +static short AppendOutput; +static struct tup_id Lowtid; +static struct tup_id Hightid; + +extern int term(); +extern int cmpa(); + +/* +** argv[0] -- sx_dbu for sorting or +** rx_dbu for reorganization +** and x is the fd for outfile or '_' +** +** argv[1] -- Fileset (process id) +** +** argv[2] -- trace information +** comes from trace flag Z23 +** +** The bits used are: +** 0001 main trace info +** 0002 secondary trace info +** 0004 terciary trace info +** 0010 don't truncate temps +** 0020 don't unlink temps +** 0040 print am page refs +** 0100 print am tuple gets +** +** argv[3] -- pathname of DBS subtree +** +** argv[4] -- page size of data base +** +** argv[5] -- name of descritor file +** +** argv[6] -- name of infile +** +** argv[7] -- name of outfile +*/ +main(argc, argv) +int argc; +char **argv; +{ + register int i; + register int j; + register int maxkey; + short rev; +# ifndef MEM_E + register char *start; + register char *stopp; + extern char *sbrk(); + extern char *brk(); +# endif + extern char *setfil(); + extern char *AAproc_name; + extern int (*AAexitfn)(); + + AAproc_name = "DB_SORT"; + AAexitfn = term; + + Reorg = **argv == 'r'; + if ((i = (*argv)[1]) != '_') + { + Outpipe = i - '0'; + Outpipe = 10 * Outpipe + (*argv)[2] - '0'; + } + + Fileset = *++argv; + + AA_atoi(*++argv, &Trace); + + AApath = *++argv; + +# ifdef VPGSIZE + AA_atoi(*++argv, &rev); + AApgsize = rev; + /* get the linetab size, the difference */ + AAltsize = (PGSIZE - AApgsize) / sizeof (short); +# else + argv++; +# endif + + if (Trace & 01) + printf("DB_SORT: %s path %s set %s pipe %d\n", + Reorg? "Reorg": "Sort", AApath, Fileset, Outpipe); + + if ((i = open(*++argv, 0)) < 0) + AAsyserr(11055, *argv); + if (read(i, &Desc, sizeof Desc) < sizeof Desc) + AAsyserr(11049); + close(i); + + /* set up Descsort to indicate the sort order for tuple */ + /* if domain zero is given prepare to generate "hash bucket" + ** value for tuple */ + maxkey = 0; + for (i = 0; i <= Desc.reldum.relatts; i++) + if (j = Desc.relgiven[i]) + { + if ((rev = j) < 0) + j = -j; + if (maxkey < j) + maxkey = j; + Descsort[--j] = rev < 0? -i: i; + } + + Descsort[maxkey] = ENDKEY; /* mark end of list */ + + Tup_size = Desc.reldum.relwid; + + if (Bucket = !Descsort[0]) + { + /* we will be generating hash bucket */ + Tup_size += BUCKETSIZE; + Desc.relfrml[0] = BUCKETSIZE; + Desc.relfrmt[0] = INT; + Desc.reloff[0] = Desc.reldum.relwid; + } + + if (Trace & 01) + { + printf("Bucket is %d,Sort is:\n", Bucket); + for (i = 0; ctou(j = Descsort[i]) != ENDKEY; i++) + printf("Descsort[%d]=%d\n", i, j); + } + if (i = (maxkey - Bucket - Desc.reldum.relatts)) + AAsyserr(11050, -i); + + Infile = *++argv; + + Outfile = (Outpipe > 0)? "PIPE": *++argv; + +# ifdef MEM_E + Memory = MEM; +# else + /* get up to MEM-K bytes of memory for buffers. Note that mem */ + /* must end up positive so that Nlines computation is right */ + start = sbrk((char *) 0); + stopp = MEM; + while (brk(stopp) == (char *) -1) + stopp -= 512; + Memory = stopp - start; +# endif + Lspace = (char **) start; + + /* compute pointers and sizes into buffer memory */ + Nlines = Memory / (Tup_size + sizeof (char *)); + Tspace = (char *) (Lspace + Nlines); + if (Trace & 01) + printf("Tspace=0%o,Lspace=0%o,Nlines=%u,mem=0%o,start=0%o\n", + Tspace, Lspace, Nlines, Memory, start); + + /* set up temp files */ + AAconcat(AAztack(SYSSORT, Fileset), "Sxxxx", File); + for (Filep = File; *Filep != 'x'; Filep++) + continue; + + /* initialize tids for full scan */ + Page = 0L; + Lowtid.line_id = SCANTID; + AAstuff_page(&Lowtid, &Page); + Page = -1L; + Hightid.line_id = SCANTID; + AAstuff_page(&Hightid, &Page); + Page = 1L; + + /* open relation */ + close(0); + if ((Desc.relfp = open(Infile, 0)) < 0) + AAsyserr(11055, Infile); + Desc.relopn = RELROPEN(Desc.relfp); + + signal(2, term); + signal(3, term); + + while (Desc.relopn) + { + /* sort stage -- create a bunch of temporaries */ + Ccount = 0; + Tupsout = 0; + Nfiles = 1; + if (Trace & 01) + printf("sorting\n"); + sort(); + if (Trace & 01) + { + printf("done sorting\n%ld tuples written to %d files\n", Tupsout, Nfiles - 1); + printf("sort required %ld compares\n", Ccount); + } + + /* merge stage -- merge up to N temps into a new temp */ + Ccount = 0; + for (i = 1; i + N < Nfiles; i += N) + { + makfile(setfil(Nfiles++)); + merge(i, i + N); + } + + /* merge last set of temps into target file */ + if (i != Nfiles) + { + oldfile(); + merge(i, Nfiles); + } + if (Trace & 01) + { + printf("%ld tuples in out file\n", Tupsout); + printf("merge required %ld compares\n", Ccount); + } + } + term(0); +} + + +sort() +{ + register char *cp; + register char **lp; + register int i; + register int done; + char *xp; + long ntups; + long pageid; + extern char *setfil(); + extern long AArhash(); + extern char *AAbmove(); + + done = 0; + ntups = 0; + + do + { + cp = Tspace; + lp = Lspace; + while (lp < Lspace + Nlines) + { + if (i = AAam_get(&Desc, &Lowtid, &Hightid, cp, TRUE)) + { + if (i < 0) + AAsyserr(11051, i); + + close(Desc.relfp); + Desc.relopn = 0; + goto step_ok; + } + if (Reorg && Page != AAcc_head->mainpg) + { + Page = AAcc_head->mainpg; + Lowtid.line_id = SCANTID; +step_ok: + done++; + break; + } + if (Bucket) + { + /* compute hash bucket and insert at end */ + pageid = AArhash(&Desc, cp); + AAbmove(&pageid, cp + Desc.reldum.relwid, BUCKETSIZE); + } + *lp++ = cp; + cp += Tup_size; + ntups++; + } + + qsort(Lspace, lp - Lspace, sizeof (char *), cmpa); + + if (!done || Nfiles != 1) + makfile(setfil(Nfiles++)); + else + oldfile(); + + while (lp > Lspace) + { + cp = *--lp; + xp = cp; + if ((lp == Lspace) || cmpa(&xp, &lp[-1])) + { + tup_write(cp); + Tupsout++; + } + } + + if (Tup_fd != Outpipe) + tup_close(); + } while (!done); + if (Trace & 01) + printf("%ld tuples in\n", ntups); +} + + +merge(low, high) +int low; +int high; +{ + register struct tup_hdr *merg; + register int i; + register int j; + register char *f; + register unsigned int blen; + register unsigned int mlen; + register char *mem; + char *yesno; + struct tup_hdr *merg_buf[N + 1]; + extern char *setfil(); + + if (Trace & 02) + printf("merge %d to %d\n", low, high); + + /* compute length of merge buffers */ + j = sizeof (struct tup_hdr); + i = ((Memory / (high - low)) - j) / PGSIZE; + if ((blen = i * PGSIZE) > 32768L - PGSIZE) + blen = 32768L - PGSIZE; + mlen = ALIGNMENT(j + blen); + blen += PGSIZE; + + if (Trace & 02) + printf("merge mem 0%o buflen 0%o\n", Memory, blen); + + mem = (char *) Lspace; + for (j = 0, i = low; i < high; i++) + { + merg_buf[j] = merg = (struct tup_hdr *) mem; + + if ((merg->tup_fd = open(f = setfil(i), 0)) < 0) + AAsyserr(11055, f); + + merg->tup_ptr = merg->tup_buf; + merg->tup_end = merg->tup_buf; + merg->tup_len = blen; + merg->tup_no = i; + if (!next_tuple(merg)) + j++; + mem += mlen; + } + + i = j - 1; + if (Trace & 04) + printf("start merg with %d\n", i); + while (i >= 0) + { + if (Trace & 04) + printf("mintup %d\n", i); + if (mintup(merg_buf, i, cmpa)) + { + tup_write(merg_buf[i]->tup_ptr); + Tupsout++; + } + if (next_tuple(merg = merg_buf[i])) + { + yesno = "not "; + if (!(Trace & 010)) + { + /* truncate temporary files to zero length */ + yesno = ""; + close(creat(setfil(merg->tup_no), FILEMODE)); + } + if (Trace & 02 || Trace & 010) + printf("dropping and %struncating %s\n", yesno, setfil(merg->tup_no)); + i--; + } + } + + if (Tup_fd != Outpipe) + tup_close(); +} + + +/* +** Mintup puts the smallest tuple in merg_buf[cnt-1]. +** If the tuple is a duplicate of another then +** mintup returns 0, else 1. +** +** Cnt is the number of compares to make; i.e. +** merg_buf[cnt] is the last element. +*/ +mintup(merg_buf, cnt, cmpfunc) +struct tup_hdr *merg_buf[]; +int cnt; +int (*cmpfunc)(); +{ + register struct tup_hdr **next; + register struct tup_hdr **last; + register int nodup; + register struct tup_hdr *temp; + register int j; + + nodup = TRUE; + next = merg_buf; + last = &next[cnt]; + + while (cnt--) + { + if (j = (*cmpfunc)(*last, *next)) + { + /* tuples not equal. keep smallest */ + if (j < 0) + { + /* exchange */ + temp = *last; + *last = *next; + *next = temp; + nodup = TRUE; + } + } + else + nodup = FALSE; + + next++; + } + return (nodup); +} + + +next_tuple(merg) +register struct tup_hdr *merg; +{ + register int eof; + extern char *tup_read(); + + if (eof = !tup_read(merg)) + close(merg->tup_fd); + + return (eof); +} + + +/* +** Convert the number i to a char +** sequence 1, 2, ..., 10, 11, etc. +*/ +char *setfil(i) +register int i; +{ + AA_itoa(--i, Filep); + return (File); +} + + +oldfile() +{ + register int i; + register char *name; + register int fd; + long off; + extern long lseek(); + extern char *AAbmove(); + + name = Outfile; + + if (Trace & 02) + printf("OLDFILE: %s\n", name); + + if (Outpipe > 0) + { + if (AppendOutput) + { + if (Tup_fd == Outpipe) + return; + if (i = DBU_ptr - DBU_buf) + Tup_ptr = AAbmove(DBU_buf, Tup_buf, i); + else + Tup_ptr = Tup_buf; + } + else + Tup_ptr = Tup_buf; + Tup_fd = Outpipe; + } + else if (AppendOutput) + { + if ((fd = open(name, 2)) < 0) + AAsyserr(11055, name); + if ((off = lseek(fd, 0L, 2)) < 0) + AAsyserr(11055, name); + if (i = off % PGSIZE) + { + if (lseek(fd, off - i, 0) < 0 || read(fd, Tup_buf, i) != i) + AAsyserr(11055, name); + lseek(fd, off - i, 0); + } + Tup_ptr = &Tup_buf[i]; + Tup_fd = fd; + } + else + makfile(name); + + AppendOutput++; +} + + +makfile(name) +register char *name; +{ + register int i; + extern char *AAbmove(); + + if (Trace & 02) + printf("MAKFILE: %s\n", name); + + if (Outpipe > 0 && AppendOutput) + { + if (i = Tup_ptr - Tup_buf) + DBU_ptr = AAbmove(Tup_buf, DBU_buf, i); + else + DBU_ptr = DBU_buf; + } + + if ((Tup_fd = creat(name, FILEMODE)) < 0) + AAsyserr(11055, name); + + Tup_ptr = Tup_buf; +} + + +term(error) +register int error; +{ + register int i; + extern char *setfil(); + + if (Nfiles == 1) + Nfiles++; + + if (Trace & 020) + printf("temp files not removed\n"); + else + for (i = 1; i < Nfiles; i++) + unlink(setfil(i)); + + if (Tup_fd >= 0) + tup_close(); + + if (Outpipe > 0) + close(Outpipe); + + fflush(stdout); + sync(); + exit(error); +} + + +AAunlall() +{ +} + + +cmpa(a, b) +char **a; +char **b; +{ + register char *tupa; + register char *tupb; + register int frml; + register int i; + register int dom; + register int off; + char *dp; + int frmt; + char *pa; + char *pb; + char af[sizeof (double)]; + char bf[sizeof (double)]; + + pa = *a; + pb = *b; + Ccount++; + dp = Descsort; + while (ctou(i = *dp++) != ENDKEY) + { + if ((dom = i) < 0) + dom = -i; + frml = ctou(Desc.relfrml[dom]); + frmt = Desc.relfrmt[dom]; + off = Desc.reloff[dom]; + tupa = &pa[off]; + tupb = &pb[off]; + if (i < 0) + { + tupb = tupa; + tupa = &pb[off]; + } + if (frmt == CHAR) + { + if (i = AAscompare(tupb, frml, tupa, frml)) + return (i); + continue; + } + + /* domain is a numeric type */ + if (AAbequal(tupa, tupb, frml)) + continue; + + /* copy to even word boundary */ + AAbmove(tupa, af, frml); + AAbmove(tupb, bf, frml); + tupa = af; + tupb = bf; + + switch (frmt) + { + case INT: + switch (frml) + { + case sizeof (char): + return (ctoi(((I1TYPE *) tupa)->i1type) > ctoi(((I1TYPE *) tupb)->i1type)? -1: 1); + + case sizeof (short): + return (((I2TYPE *) tupa)->i2type > ((I2TYPE *) tupb)->i2type? -1: 1); + + case sizeof (long): + return (((I4TYPE *) tupa)->i4type > ((I4TYPE *) tupb)->i4type? -1: 1); + } + + case FLOAT: +# ifndef NO_F4 + switch (frml) + { + case sizeof (float): + return (((F4TYPE *) tupa)->f4type > ((F4TYPE *) tupb)->f4type? -1: 1); + + case sizeof (double): +# endif + return (((F8TYPE *) tupa)->f8type > ((F8TYPE *) tupb)->f8type? -1: 1); +# ifndef NO_F4 + } +# endif + } + } + return (0); +} + + +/* +** Replacement for access method routine AAgetpage(); +** and associated globals and routines. +*/ +ACCBUF *AAcc_head; +static ACCBUF AAcc_buf; +static long AAccuread; +static long AAccuwrite; + +AAgetpage(d, tid) +register DESC *d; +struct tup_id *tid; +{ + register int i; + register ACCBUF *b; + long pageid; + extern long lseek(); + + if (Trace & 0100) + { + printf("GET_PAGE: %.14s,", d->reldum.relid); + AAdumptid(tid); + } + if (!(b = AAcc_head)) + { + /* initialize buffer */ + AAcc_head = &AAcc_buf; + b = &AAcc_buf; + b->thispage = -1L; + } + AApluck_page(tid, &pageid); + i = 0; + if (b->thispage != pageid) + { + if (Trace & 040) + printf("GET_PAGE: rdg pg %ld\n", pageid); + b->thispage = pageid; + if (lseek(d->relfp, pageid * AApgsize, 0) < 0L) + i = AMSEEK_ERR; + else if (read(d->relfp, b, AApgsize) != AApgsize) + i = AMREAD_ERR; + AAccuread++; + } + return (i); +} + + +AAresetacc() +{ + return (0); +} + + +AAam_error(err) +register int err; +{ + return (err); +}