1: # include <ingres.h>
2: # include <access.h>
3: # include <aux.h>
4: # include <lock.h>
5: # include <opsys.h>
6: # include <sccs.h>
7:
8: SCCSID(@(#)accbuf.c 8.1 12/31/84)
9:
10:
11: /*
12: ** access method buffers and other data areas for buffer maintenance
13: */
14:
15: struct accbuf Acc_buf[NACCBUFS]; /* the buffers */
16: struct accbuf *Acc_head; /* head of usage list */
17: struct accbuf *Acc_tail; /* tail of usage list */
18: struct lockreq Lock;
19:
20: /*
21: ** structs for admin file data
22: */
23:
24: struct admin Admin;
25:
26: /*
27: ** global flag indicating if access methods
28: ** have been initialized.
29: */
30:
31: int Acc_init = FALSE;
32:
33: char Acclock; /* locks enabled flag */
34: int Alockdes; /* file descriptor for lock device*/
35: int Lockrel; /* lock relations flag*/
36: /*
37: ** Flush the indicated page and reset all
38: ** important information including the name
39: **
40: ** Trace Flags:
41: ** 20.0,1
42: */
43:
44: resetacc(buf)
45: struct accbuf *buf;
46: {
47: register struct accbuf *b;
48: register int i;
49:
50: b = buf;
51: if (b == 0)
52: b = Acc_head;
53: # ifdef xATR3
54: if (tTf(20, 0))
55: {
56: printf("RESETACC: %x=", b);
57: dumptid((TID *) &b->rel_tupid);
58: }
59: # endif
60:
61: i = pageflush(b); /* write the page if necessary */
62: b->rel_tupid = -1;
63: b->filedesc = -1;
64: b->thispage = -1;
65: b->bufstatus = 0;
66: return (i);
67: }
68: /*
69: ** initialize access method data areas
70: **
71: ** Trace Flags:
72: ** 20.2,3
73: */
74:
75: acc_init()
76: {
77: register struct accbuf *last;
78: register struct accbuf *b;
79: struct stat stbuf;
80: extern int errno;
81:
82: # ifdef xATR3
83: if (tTf(20, 2))
84: printf("ACC_INIT=%d\n", Acc_init);
85: # endif
86:
87: if (Acc_init)
88: return; /* already initialized */
89: last = 0;
90: for (b = Acc_buf; b < &Acc_buf[NACCBUFS]; )
91: {
92: resetacc(b);
93: b->modb = last;
94: last = b;
95: b++;
96: last->modf = b;
97: }
98: last->modf = 0;
99: Acc_head = Acc_buf;
100: Acc_tail = last;
101:
102: /* get the admin file */
103: readadmin();
104:
105: /*
106: ** Set up locking information. If the database has concurrency
107: ** control then Lockrel = TRUE and the concurrency device will
108: ** be opened for writing. If there is no concurrency for the
109: ** data base or if the lock device isn't installed, then Alockdes
110: ** = -1 and no locking will (or can) occure.
111: */
112: Lockrel = (Admin.adhdr.adflags & A_DBCONCUR) != 0;
113: if (Lockrel && Alockdes < 0)
114: Alockdes = start_up_lock_driver();
115: errno = 0; /* clear in case /dev/lock isn't available */
116: Acclock = TRUE;
117: stat(".", &stbuf);
118: bmove((char *) &stbuf, (char *) Lock.dbnode, 4);
119:
120: Acc_init = TRUE;
121: }
122: /*
123: ** place buffer at top of LRU list
124: */
125:
126: top_acc(buf)
127: struct accbuf *buf;
128: {
129: register struct accbuf *b;
130:
131: b = buf;
132:
133: if (b == Acc_head)
134: return (0);
135: if (b == Acc_tail)
136: Acc_tail = b->modb;
137: else
138: b->modf->modb = b->modb;
139: b->modb->modf = b->modf;
140: Acc_head->modb = b;
141: b->modf = Acc_head;
142: Acc_head = b;
143: b->modb = 0;
144: return (0);
145: }
146: /*
147: ** Flush_rel -- flush all pages associated with the relation
148: ** described by the descriptor. If resetflag is TRUE,
149: ** then the buffers are reset so the pages will not be
150: ** found on subsequent calls to find_page().
151: **
152: ** Returns "or'ed" result from calls to pageflush.
153: **
154: ** Trace Flags:
155: ** 20.4-5
156: */
157:
158: flush_rel(d, resetflag)
159: register DESC *d;
160: int resetflag;
161: {
162: register struct accbuf *b;
163: register int i;
164:
165: # ifdef xATR3
166: if (tTf(20, 4))
167: printf("flush_rel: rel=%.14s, reset=%d\n", d->reldum.relid, resetflag);
168: # endif
169:
170: i = 0;
171: for (b = Acc_head; b != NULL; b = b->modf)
172: {
173: if (d->reltid.ltid == b->rel_tupid)
174: {
175: if (resetflag)
176: i |= resetacc(b);
177: else
178: i |= pageflush(b);
179: }
180: }
181:
182: return (i);
183: }
184: /*
185: ** CHOOSE_BUF -- Try to find an empty buffer for assignment.
186: ** If there is no empty buffer, pick the last buffer
187: ** in the LRU queue and make sure it is flushed.
188: **
189: ** Choose_buf guarantees that the buffer will be reset
190: ** if it was used previously for a different relation.
191: **
192: ** Choose_buf -- choose a buffer for use with the given relation on
193: ** the given page. The current algorithm is to allow only one buffer
194: ** per relation. If a relation does not have a buffer, it is given a
195: ** free one (if any) or else the Least Recently Used.
196: **
197: ** Trace Flags:
198: ** 29.0,1
199: */
200:
201: struct accbuf *
202: choose_buf(dx, pageid)
203: DESC *dx;
204: long pageid;
205: {
206: register struct accbuf *b, *free;
207: register DESC *d;
208: struct accbuf *mine;
209:
210: d = dx;
211: free = mine = NULL;
212:
213: for (b = Acc_head; b != 0; b = b->modf)
214: {
215: if (b->rel_tupid == -1)
216: free = b;
217: else
218: if (d->reltid.ltid == b->rel_tupid)
219: {
220: if (pageid == b->thispage)
221: {
222: if (d->relopn < 0)
223: b->filedesc = d->relfp;
224: return (b);
225: }
226: mine = b;
227: }
228: }
229:
230: /*
231: ** "Free" and "Mine" now reflect the current state of the buffers.
232: ** There is no buffer with the currently requested page
233: */
234:
235: # ifdef xATR3
236: if (tTf(29, 1))
237: printf("choosebuf free %x,mine %x\n", free, mine);
238: # endif
239:
240: /* no current buffer. Choose a free one or LRU */
241: if (free == NULL)
242: free = resetacc(Acc_tail) ? NULL : Acc_tail; /* error if can't reset the LRU */
243: if (free)
244: {
245: /* copy relevant material (in this order in case of rubout) */
246: free->filedesc = d->relfp;
247: free->rel_tupid = d->reltid.ltid;
248: }
249:
250: # ifdef xATR1
251: if (tTf(29, 0))
252: printf("choosebuf:rets %x\n", free);
253: # endif
254: return (free);
255: }
256: /*
257: ** ACC_CLOSE -- flush any buffers left around
258: ** and then close the files for relation & attribute.
259: ** The relation and attribute relation are normally left open
260: ** until the end of an INGRES session but must be closed
261: ** and re-opened in the dbu's whenever a new overlay is loaded.
262: */
263:
264: acc_close()
265: {
266: register int i;
267:
268: if (i = pageflush((struct accbuf *) NULL))
269: syserr("acc_close: pageflush %d", i);
270: close(Admin.adreld.relfp);
271: close(Admin.adattd.relfp);
272: Admin.adreld.relopn = Admin.adattd.relopn = 0;
273: if (Alockdes >= 0)
274: close(Alockdes);
275: Alockdes = -1;
276: Acc_init = FALSE;
277: return (0);
278: }
Defined functions
Defined variables
Admin
defined in line
24; used 5 times
Lock
defined in line
18; used 1 times