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