Annotation of 43BSD/ingres/source/iutil/btree_util.c, revision 1.1.1.1

1.1       root        1: #include       <btree.h>
                      2: #include       <ingres.h>
                      3: #include       <opsys.h>
                      4: #include       <sccs.h>
                      5: 
                      6: SCCSID(@(#)btree_util.c        8.2     1/31/86)
                      7: 
                      8: /*     Trace up to the root of the BTree, incrementing (or decrementing) all
                      9: **     key values.
                     10: **
                     11: **     Parameters :
                     12: **             tree - BTree filename (I)
                     13: **             block - starting node from which path is traced (I)
                     14: **             inc - either +1 or -1 (I)
                     15: */
                     16: 
                     17: tracepath(rootpage, block, inc)
                     18: 
                     19: long rootpage;
                     20: register struct locator *block;
                     21: register int inc;
                     22: {
                     23:        struct locator  p, child;
                     24: 
                     25:        if (block->pageno != rootpage)  /* if at root, no need for adjustment */
                     26:        {
                     27:                bmove(block, &child, sizeof(struct locator));
                     28: 
                     29:                /* trace up to root node */
                     30:                do
                     31:                {
                     32:                        p.pageno = child.page.parent;
                     33:                        parentkey(child.pageno, &p);
                     34:                        p.page.node.intnode.key[p.offset] += inc;
                     35:                        write_node(p.pageno, &p.page);
                     36:                        bmove(&p, &child, sizeof(struct locator));
                     37:                } while (p.pageno != rootpage);
                     38:        }
                     39: }
                     40: 
                     41: /*     Determines which key/ptr pair is the parent of the given page
                     42: **
                     43: **     Parameters :
                     44: **             tree - BTree filename (I)
                     45: **             block - page number of child (I)
                     46: **             prt - information about the parent of the child (I, O)
                     47: **
                     48: */
                     49: 
                     50: parentkey(block, prt)
                     51: 
                     52: long block;
                     53: register struct locator *prt;
                     54: {
                     55:        register int    i;
                     56: 
                     57:        get_node(prt->pageno, &prt->page);
                     58:        /* find pointer in parent which references desired block */
                     59:        for (i = 0; prt->page.node.intnode.ptr[i] != block && i < prt->page.nelmts; ++i)
                     60:                continue;
                     61: 
                     62:        if (i == prt->page.nelmts)
                     63:                syserr("parentkey: child = %ld", block);
                     64:        prt->offset = i;
                     65:        return(0);
                     66: }
                     67: 
                     68: /*     Retrieve a node from the BTree
                     69: **
                     70: **     Parameters :
                     71: **             tree - BTree filename (I)
                     72: **             pagenum - page number of page to be retrieved (I)
                     73: **             buffer - buffer into which page is retrieved (O)
                     74: */
                     75: 
                     76: get_node(pagenum, buffer)
                     77: 
                     78: long pagenum;
                     79: register struct BTreeNode *buffer;
                     80: {
                     81:        extern int      Btree_fd;
                     82: 
                     83:        if ( lseek(Btree_fd, pagenum * PGSIZE, 0) == -1 )
                     84:                syserr("GET_NODE: seek to %ld failed",pagenum);
                     85:        if (read(Btree_fd, buffer, sizeof *buffer) != sizeof *buffer)
                     86:                syserr("GET_NODE: read btree, page %ld", pagenum);
                     87: }
                     88: 
                     89: /*     Write a node into the BTree file name 
                     90: **
                     91: **     Parameters :
                     92: **             tree - BTree filename (I)
                     93: **             pagenum - page number of page to be written (I)
                     94: **             buffer - buffer containing page to be written (I)
                     95: */
                     96: 
                     97: write_node(pagenum, buffer)
                     98: 
                     99: long pagenum;
                    100: register struct BTreeNode *buffer;
                    101: {
                    102:        extern int      Btree_fd;
                    103: 
                    104:        lseek(Btree_fd, pagenum * PGSIZE, 0);
                    105:        if (write(Btree_fd, buffer, sizeof *buffer) != sizeof *buffer)
                    106:                syserr("WRITE_NODE: write btree, page %ld", pagenum);
                    107: }
                    108: 
                    109: /*     Retrieves a new page from the BTree file.  If there is an empty page
                    110: **     in the file, that page is used.  Otherwise, a new page is added to
                    111: **     the end of the file.
                    112: **
                    113: **     Parameters :
                    114: **             tree - BTree filename (I)
                    115: **
                    116: **     Returns :
                    117: **             page number of new page
                    118: */
                    119: 
                    120: long
                    121: new_page(tree)
                    122: 
                    123: char *tree;
                    124: {
                    125:        int                     i;
                    126:        long                    freepage, newpage;
                    127:        struct BTreeNode        page, root, garbage;
                    128:        struct stat             fileinfo;
                    129:        extern DESC             Btreesec;
                    130: 
                    131:        get_node(RT, &root);
                    132:        freepage = root.parent;
                    133:        if (freepage == 0)
                    134:        /* no free pages in file, add a new page to the end */
                    135:        {
                    136:                /* determine page number of page at very end of file */
                    137:                stat(tree, &fileinfo);
                    138:                newpage = fileinfo.st_size / PGSIZE;
                    139:                write_node(newpage, &page);
                    140:        }
                    141:        else
                    142:        /* use first free page, adjusting free page chain */
                    143:        {
                    144:                newpage = freepage;
                    145:                get_node(newpage, &garbage);
                    146:                root.parent = garbage.parent;
                    147:                write_node(RT, &root);
                    148:        }
                    149:        return(newpage);
                    150: }
                    151: 
                    152: /*     Returns an empty file to the empty file list.  The head of the list
                    153: **     is indicated through the parent of the root and linked together
                    154: **     through the parents of the empty pages.
                    155: **
                    156: **     Parameters :
                    157: **             tree - BTree filename (I)
                    158: **             pagenum - page number of empty page (I)
                    159: */
                    160: 
                    161: return_page(pagenum)
                    162: 
                    163: long pagenum;
                    164: {
                    165:        struct BTreeNode        root, freepage; 
                    166: 
                    167:        /* indicate that page is free by inserting its page number at the
                    168:        ** head of the free page list */
                    169:        get_node(RT, &root);
                    170:        get_node(pagenum, &freepage);
                    171:        freepage.parent = root.parent;
                    172:        freepage.depth = 0;
                    173:        write_node(pagenum, &freepage);
                    174:        root.parent = pagenum;
                    175:        write_node(RT, &root);
                    176: }
                    177: 
                    178: /*
                    179: **     Determine the lid that corresponds to a given position in the B-Tree.
                    180: **
                    181: **     Parameters :
                    182: **             tree - BTree name (I)
                    183: **             tidloc - location in BTree (I)
                    184: **
                    185: **     Returns :
                    186: **             lid value
                    187: */
                    188: get_lid(tidloc, lid)
                    189: 
                    190: TID *tidloc;
                    191: long lid[];
                    192: {
                    193:        static struct locator   tid;
                    194:        register int            i, j;
                    195:        long                    l, child;
                    196: 
                    197:        do
                    198:        {
                    199:                /* determine where in BTree to search */
                    200:                pluck_page(tidloc, &tid.pageno);
                    201:        
                    202:                get_node(tid.pageno, (char *) &tid.page);
                    203:                tid.offset = tid.page.node.leafnode.back_ptr[tidloc->line_id & I1MASK];
                    204: 
                    205:                if (tid.offset > tid.page.nelmts - 1)
                    206:                        syserr("get_lid: bad tid location %ld, tid.offset=%d, tid.page.nelmts=%d", *tidloc, tid.offset,tid.page.nelmts);
                    207:        
                    208:                /* scan through leaf */
                    209:                for (l = 1, i = tid.offset; i > 0; ++l, --i)
                    210:                        continue;
                    211:                /* trace up to root, adding keys */
                    212:                while (!tid.page.depth)
                    213:                {
                    214:                        child = tid.pageno;
                    215:                        tid.pageno = tid.page.parent;
                    216:                        parentkey(child, &tid);
                    217:                        for (i = tid.offset - 1; i >= 0; l += tid.page.node.intnode.key[i--])
                    218:                                continue;
                    219:                }
                    220:                lid[tid.page.depth - 1] = l;
                    221: #              ifdef xATR1
                    222:                        if (tTf(24,0))
                    223:                                printf("lid=%ld\n", lid[tid.page.depth - 1]);
                    224: #              endif
                    225:                bmove(&tid.page.prttree, tidloc, LIDSIZE);
                    226:        } while (tid.page.depth > 1);
                    227: }
                    228: 
                    229: /*
                    230: **     Uses the secondary btree relation to find the btree tid corresponding 
                    231: **     to a given main relation tid
                    232: */
                    233: 
                    234: search_btree(mtid, tidloc)
                    235: 
                    236: TID mtid; 
                    237: register TID *tidloc;
                    238: {
                    239:        char            key[2 * LIDSIZE], tup[2 * LIDSIZE];
                    240:        TID             tid;
                    241:        extern DESC     Btreesec;
                    242: 
                    243: #      ifdef xATR1
                    244:                if (tTf(24,0))
                    245:                {
                    246:                        printf("In Search_btree: searching for tid %ld\n", mtid);
                    247:                        printdesc(&Btreesec);
                    248:                }
                    249: #      endif
                    250:        clearkeys(&Btreesec);
                    251:        setkey(&Btreesec, key, &mtid, 1);
                    252:        if (!getequal(&Btreesec, key, tup, &tid))
                    253:                bmove(tup + LIDSIZE, tidloc, LIDSIZE);
                    254:        else
                    255:                syserr("search_btree:can't find mtid %ld in btree", mtid);
                    256: #      ifdef xATR1
                    257:                if (tTf(24,0))
                    258:                        printup(&Btreesec, tup);
                    259: #      endif
                    260: }
                    261: 
                    262: /*
                    263: **     Linearly searches the leaves of the BTree for a desired tid
                    264: **
                    265: **     Parameters :
                    266: **             tree - BTree file name (I)
                    267: **             tid - desired tid value (I)
                    268: **             tidloc - location of the desired tid (O)
                    269: */
                    270: 
                    271: lin_search(level, tid, tidloc, lid, tupcnt)
                    272: 
                    273: int level;
                    274: long tid;
                    275: TID *tidloc;
                    276: long lid[];
                    277: long tupcnt;
                    278: {
                    279:        struct locator  block;
                    280:        register int    i;
                    281:        long            page, t, next;
                    282:        int             found;
                    283:        long            nextpage, count;
                    284:        int             forward, first;
                    285: 
                    286:        page = RT;
                    287:        for (i = 0; i < level - 1; ++i)
                    288:        {
                    289:                t = get_tid(page, lid[i], &block);
                    290:                page = t;
                    291:        }
                    292: 
                    293:        found = 0;
                    294:        forward  = 0;
                    295:        first = 1;
                    296:        do
                    297:        {
                    298:                if (!forward)
                    299:                {
                    300:                        get_node(page, &block.page);
                    301:                        next = block.page.nexttree;
                    302:                }
                    303:                count = 0;
                    304: 
                    305:                /* start at leftmost leaf */
                    306:                do
                    307:                {
                    308:                        get_node(page, &block.page);
                    309:                        if (forward)
                    310:                                nextpage = block.page.nexttree;
                    311:                        else
                    312:                                nextpage = block.page.prevtree;
                    313:                        get_tid(page, 1, &block);
                    314:                        for ( ; ; )
                    315:                        {
                    316:                                /* search through leaf */
                    317:                                for (i = 0; i < block.page.nelmts && block.page.node.leafnode.tid_pos[block.page.node.leafnode.tid_loc[i]] != tid; ++i)
                    318:                                {
                    319:                                        if (!first)
                    320:                                                ++count;
                    321:                                }
                    322:                                if (i < block.page.nelmts && block.page.node.leafnode.tid_pos[block.page.node.leafnode.tid_loc[i]] == tid)
                    323:                                {
                    324:                                        found = 1;
                    325:                                        break;  /* tid found */
                    326:                                }
                    327:                                first = 0;
                    328:                                if (!(block.pageno = block.page.node.leafnode.nextleaf) || count >= tupcnt)
                    329:                                        break;  /* all leaves exhausted */
                    330:                                else
                    331:                                        /* try leaf to the right */
                    332:                                        get_node(block.pageno, &block.page);
                    333:                        }
                    334:                        if (found || count >= tupcnt)
                    335:                                break;
                    336:                } while (page = nextpage);
                    337:                nextpage = next;
                    338:                forward = !forward;
                    339:        } while (forward != 0 && !found);
                    340:        if (!found)
                    341:                syserr("search_btree: tid not found %ld", tid);
                    342:        else
                    343:        {
                    344:                stuff_page(tidloc, &block.pageno);
                    345:                tidloc->line_id = block.page.node.leafnode.tid_loc[i];
                    346:        }
                    347: }
                    348: 
                    349: /*
                    350: **     Determines the value corresponding to the very last lid in the
                    351: **     BTree.
                    352: **
                    353: **     Parameters :
                    354: **             tree - BTree file name (I)
                    355: **
                    356: **     Returns :
                    357: **             value of last lid
                    358: */
                    359: long
                    360: last_lid(rootpage)
                    361: 
                    362: long rootpage;
                    363: 
                    364: {
                    365:        register int            i;
                    366:        long                    lid;
                    367:        struct BTreeNode        root;
                    368: 
                    369:        lid = 0;
                    370:        get_node(rootpage, &root);
                    371:        if (root.nodetype == 'L')
                    372:                lid = root.nelmts;
                    373:        else
                    374:                for (i = 0; i < root.nelmts; ++i)
                    375:                        lid += root.node.intnode.key[i];
                    376:        ++lid;
                    377:        return(lid);
                    378: }
                    379: 
                    380: /*
                    381: **     Changes the tid value stored in the leaf of a BTree node
                    382: **
                    383: **     Parameters :
                    384: **             tree - BTree file name (I)
                    385: **             tid - new tid value (I)
                    386: **             tidloc - location of tid to be replaced (I)
                    387: */
                    388: 
                    389: replace_btree(tid, tidloc)
                    390: 
                    391: long tid;
                    392: register TID *tidloc;
                    393: 
                    394: {
                    395:        long                    pageno;
                    396:        struct BTreeNode        p;
                    397: 
                    398:        pluck_page(tidloc, &pageno);
                    399:        get_node(pageno, &p);
                    400:        p.node.leafnode.tid_pos[tidloc->line_id] = tid;
                    401:        write_node(pageno, &p);
                    402: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.