|
|
1.1 ! root 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 7.2 5/19/83) ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.