|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <access.h>
4: # include <sccs.h>
5:
6: SCCSID(@(#)findbest.c 7.1 2/5/81)
7:
8:
9: /*
10: ** Findbest - find the "best" place to put a tuple.
11: ** Findbest does not actually put the tuple but rather
12: ** returns and allocates the tid for the tuple.
13: **
14: ** The initial part of the algorithm depends on whether
15: ** the relation is a heap or not.
16: **
17: ** If the relation is a heap, if there is a current page
18: ** with room for the tuple, that page is used. Otherwise
19: ** the last page of the heap is considered.
20: **
21: ** If the relation is hash or isam, then "find" is used
22: ** to determine the primary page for the tuple.
23: **
24: ** If necessary, findbest will allocate an overflow page
25: ** if there is not sufficient room for the tuple otherwise.
26: **
27: ** If checkdups is TRUE and the relation is not a heap,
28: ** findbest will check for duplicates.
29: **
30: ** Returns:
31: **
32: ** 0 tuple not a duplicate, tid allocated
33: ** 1 tuple a duplicate of the tuple at tid
34: */
35:
36: findbest(dx, tidx, tuple, need, checkdups)
37: DESC *dx;
38: TID *tidx;
39: char *tuple;
40: int need;
41: bool checkdups;
42: {
43: register DESC *d;
44: register TID *tid;
45: register int i;
46: TID temptid;
47:
48: d = dx;
49: tid = tidx;
50:
51:
52: if (abs(d->reldum.relspec) == M_HEAP)
53: {
54: checkdups = FALSE;
55: /* determine a page to place tuple in heap relation */
56: find_page(d, tid, need);
57:
58: }
59: else
60: {
61: /* find a suitable page for isam or hash */
62: /* determine primary page */
63: if (i = find(d, FULLKEY, tid, tid, tuple))
64: {
65: return (i); /* fatal error */
66: }
67:
68: /* If we are not checking for duplicates then take any
69: ** convenient page linked to the main page current indicated
70: ** in "tid"
71: */
72: if (!checkdups)
73: find_page(d, tid, need);
74: }
75:
76: /* search the chain of pages looking for a spot */
77: for (;;)
78: {
79: if (i = get_page(d, tid))
80: break; /* fatal error */
81:
82: /* if tuple is duplicate, drop out */
83: if (checkdups && dup_check(d, tid, tuple))
84: {
85: i = 1;
86: break;
87: }
88:
89: /* is there space on this page */
90: if (space_left(Acc_head) >= need)
91: break; /* found a page to use */
92:
93: /* no space yet. look on next overflow page */
94: if (Acc_head->ovflopg)
95: {
96: stuff_page(tid, &Acc_head->ovflopg);
97: continue;
98: }
99:
100: /* no space. allocate new overflow page */
101: if (i = add_ovflo(d, tid))
102: break; /* fatal error */
103: }
104:
105: /* check for dups on remaining overflow pages */
106: /* check only if there hasn't been a dup or a page error */
107: if (i == 0 && checkdups && Acc_head->ovflopg)
108: {
109: stuff_page(&temptid, &Acc_head->ovflopg);
110: if (i = scan_dups(d, &temptid, tuple))
111: bmove((char *) &temptid, (char *) tid, sizeof(temptid)); /* tid of duplicate */
112: }
113:
114: /* if tuple isn't a duplicate, allocate a line number */
115: if (i == 0)
116: tid->line_id = newlino(need);
117:
118: # ifdef xATR1
119: if (tTf(27, 0))
120: {
121: printf("findbest ret %d,", i);
122: dumptid(tid);
123: }
124: # endif
125: return (i);
126: }
127: /*
128: ** FINDBEST -- find best page for tuple
129: **
130: ** Find an appropriate page to put a tuple.
131: ** If HEAP then any page with room will do. If none
132: ** can be found, then use the last page.
133: ** If it is a user relation and a page was found but
134: ** was full, use it anyway. This can happen only on a
135: ** modify (which has checkdups turned off).
136: **
137: ** For ISAM or HASH look for a page on the same mainpage
138: ** chain. Duplicate checking must not be enforced.
139: **
140: ** The first page to use will be returned in tid in either
141: ** case.
142: */
143:
144: find_page(dx, tid, need)
145: DESC *dx;
146: TID *tid;
147: int need;
148: {
149: register DESC *d;
150: register struct accbuf *b, *maxbf;
151: int heap;
152: long mainpg;
153:
154: d = dx;
155: maxbf = NULL;
156: heap = abs(d->reldum.relspec) == M_HEAP;
157: pluck_page(tid, &mainpg);
158: mainpg++; /* mainpage in buffer points to next higher mainpage */
159:
160: /* scan all current buffers looking for one belonging to this relation */
161: for (b = Acc_head; b != NULL; b = b->modf)
162: {
163: if (d->reltid.ltid == b->rel_tupid && !(b->bufstatus & BUF_DIRECT)
164: && (heap || (b->mainpg == mainpg)))
165: {
166: if (space_left(b) >= need)
167: {
168: /* use this page */
169: stuff_page(tid, &b->thispage);
170: return;
171: }
172:
173: /* save buffer of largest page */
174: if (maxbf == NULL || maxbf->thispage < b->thispage)
175: maxbf = b;
176: }
177: }
178:
179: if (heap)
180: last_page(d, tid, maxbf);
181: else
182: {
183: /* if we found a full page of a user's relation,use it */
184: if (maxbf && (d->reldum.relstat & S_CATALOG) == 0)
185: stuff_page(tid, &maxbf->thispage);
186: }
187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.