Annotation of 43BSD/ingres/source/iutil/btree_util.c, revision 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.