Annotation of 43BSD/ingres/source/iutil/delete_btree.c, revision 1.1

1.1     ! root        1: # include      <stdio.h>
        !             2: # include      <btree.h>
        !             3: # include      <ingres.h>
        !             4: # include      <batch.h>
        !             5: # include      <sccs.h>
        !             6: 
        !             7: SCCSID(@(#)delete_btree.c      8.1     12/31/84)
        !             8: 
        !             9: /*     DELETE_BTREE -- BTree deletion routine
        !            10: **
        !            11: **     Deletes a tid from a leaf node and adjusts all values up the tree
        !            12: **
        !            13: **     Parameters :
        !            14: **             tree - BTree filename (I)
        !            15: **             lid - lid to be deleted (I)
        !            16: **
        !            17: **     Returns :
        !            18: **             > 0     success
        !            19: **             < 0     bad lid
        !            20: */
        !            21: 
        !            22: delete_btree(lid, level)
        !            23: long lid[];
        !            24: register int level;
        !            25: 
        !            26: {
        !            27:        register int            i, j;
        !            28:        struct locator          tid[MAXLID];
        !            29:        register int            save;
        !            30:        int                     num[MAXLID];
        !            31:        int                     del[MAXLID];
        !            32:        long                    page[MAXLID + 1], t;
        !            33:        struct BTreeNode        temp;
        !            34: 
        !            35: #      ifdef xATR1
        !            36:        if(tTf(24,0))
        !            37:                printf("deleting lid %ld from tree ", lid);
        !            38: #      endif
        !            39: 
        !            40:        page[0] = RT;
        !            41:        for (i = 0; i < level; ++i)
        !            42:        {
        !            43:                if ((t = get_tid(page[i], lid[i], &tid[i])) < 0)
        !            44:                        return(-1);
        !            45:                del[i] = 0;
        !            46:                num[i] = tid[i].page.nelmts; 
        !            47:                page[i+1] = t;
        !            48:        }
        !            49: 
        !            50:        del[level-1] = 1;
        !            51:        for (i = level - 2; i >= 0; --i)
        !            52:        {
        !            53:                if (num[i + 1] == 1 && del[i + 1] == 1)
        !            54:                        del[i] = 1;
        !            55:        }
        !            56: 
        !            57:        for (i = 0; i < level; ++i)
        !            58:        {
        !            59:                if (del[i])
        !            60:                {
        !            61:                        ++Repl_cnt[i];
        !            62:                        for (j = i - 1; j >= 0; --j)
        !            63:                                Prev_lid[j] = lid[j];
        !            64:                        /* remove tid from leaf */
        !            65:                        if (tid[i].offset != tid[i].page.nelmts - 1)
        !            66:                        {
        !            67:                                save = tid[i].page.node.leafnode.tid_loc[tid[i].offset];
        !            68:                                for (j = tid[i].offset; j < tid[i].page.nelmts; ++j)
        !            69:                                {
        !            70:                                        tid[i].page.node.leafnode.tid_loc[j] =
        !            71:                                                tid[i].page.node.leafnode.tid_loc[j + 1];
        !            72:                                        tid[i].page.node.leafnode.back_ptr[tid[i].page.node.leafnode.tid_loc[j]] = j;
        !            73:                                }
        !            74:                                tid[i].page.node.leafnode.tid_loc[tid[i].page.nelmts - 1] = save;
        !            75:                                tid[i].page.node.leafnode.back_ptr[save] = tid[i].page.nelmts - 1;
        !            76:                        }
        !            77:                        --tid[i].page.nelmts;
        !            78: 
        !            79:                        if (tid[i].page.nelmts != 0)
        !            80:                        {
        !            81:                                write_node(tid[i].pageno, &tid[i].page);
        !            82:                                /* leaf is now empty as a result of deletion, decrement keys
        !            83:                                ** up tree */
        !            84:                                tracepath(page[i], &tid[i], -1);
        !            85:                        }
        !            86: 
        !            87:                        else if (tid[i].pageno != page[i])
        !            88:                        {
        !            89:                                /* key/ptr pair corresponding to empty leaf must be removed */
        !            90:                                delete_key(page[i], &tid[i]);
        !            91:                        }
        !            92:                        else if (lid[i] == 1 && page[i] != RT)
        !            93:                        {
        !            94:                                if (tid[i].page.prevtree)
        !            95:                                {
        !            96:                                        get_node(tid[i].page.prevtree, &temp);
        !            97:                                        temp.nexttree = tid[i].page.nexttree;
        !            98:                                        write_node(tid[i].page.prevtree, &temp);
        !            99:                                }
        !           100:                                if (tid[i].page.nexttree)
        !           101:                                {
        !           102:                                        get_node(tid[i].page.nexttree, &temp);
        !           103:                                        temp.prevtree = tid[i].page.prevtree;
        !           104:                                        write_node(tid[i].page.nexttree, &temp);
        !           105:                                }
        !           106:                                return_page(page[i]);
        !           107:                        }
        !           108:                        else
        !           109:                                write_node(page[i], &tid[i].page);
        !           110:                }
        !           111:        }
        !           112:        return(0);
        !           113: }
        !           114: 
        !           115: /*     Returns an empty page to the empty file space list.  Removes key/ptr
        !           116: **     pair corresponding to empty node from tree.  Combines and distributes
        !           117: **     pairs if a node has less than the minimum number of values.  Adjusts
        !           118: **     all values up the tree.
        !           119: **
        !           120: **     Parameters :
        !           121: **             tree - BTree filename (I)
        !           122: **             empty - empty node (I)
        !           123: */
        !           124: 
        !           125: delete_key(rootpage, empty)
        !           126: 
        !           127: long rootpage;
        !           128: register struct locator *empty;
        !           129: {
        !           130:        struct locator          prt, gprt, sibling;
        !           131:        register int            i;
        !           132:        struct BTreeNode        new, temp;
        !           133:        long                    pkey, skey;
        !           134:        extern char             *Fileset;
        !           135:        char                    replbatch[MAXNAME + 4];
        !           136:        FILE                    *fp;
        !           137:        long                    count, page;
        !           138:        TID                     oldtid, newtid;
        !           139: 
        !           140:        /* find parent corresponding to empty node, and remove ptr/key pair
        !           141:        ** from parent */
        !           142:        prt.pageno = empty->page.parent;
        !           143:        parentkey(empty->pageno, &prt);
        !           144:        if (prt.offset != prt.page.nelmts - 1)
        !           145:        {
        !           146:                for (i = prt.offset; i < prt.page.nelmts; ++i)
        !           147:                {
        !           148:                        prt.page.node.intnode.ptr[i] = 
        !           149:                                prt.page.node.intnode.ptr[i + 1];
        !           150:                        prt.page.node.intnode.key[i] =
        !           151:                                prt.page.node.intnode.key[i + 1];
        !           152:                }
        !           153:        }
        !           154:        --prt.page.nelmts;
        !           155: 
        !           156:        if (empty->page.nodetype == 'L')
        !           157:        /* adjust previous and next fields of leaves */
        !           158:        {
        !           159:                if (empty->page.node.leafnode.nextleaf != 0)
        !           160:                {
        !           161:                        get_node(empty->page.node.leafnode.nextleaf, &temp);
        !           162:                        temp.node.leafnode.prevleaf = empty->page.node.leafnode.prevleaf;
        !           163:                        write_node(empty->page.node.leafnode.nextleaf, &temp);
        !           164:                }
        !           165:                if (empty->page.node.leafnode.prevleaf != 0)
        !           166:                {
        !           167:                        get_node(empty->page.node.leafnode.prevleaf, &temp);
        !           168:                        temp.node.leafnode.nextleaf = empty->page.node.leafnode.nextleaf;
        !           169:                        write_node(empty->page.node.leafnode.prevleaf, &temp);
        !           170:                }
        !           171:        }
        !           172: 
        !           173:        /* return empty node to empty file space */
        !           174:        return_page(empty->pageno);
        !           175: 
        !           176:        if (prt.page.nelmts >= (int) ((float) MAXPTRS / 2 + 0.5))
        !           177:        {
        !           178:                write_node(prt.pageno, &prt.page);
        !           179:                /* node still has proper number of elements, decrement key  
        !           180:                ** values up the tree */
        !           181:                tracepath(rootpage, &prt, -1);
        !           182:        }
        !           183: 
        !           184:        else if (prt.pageno == rootpage && prt.page.nelmts < 2)
        !           185:        /* root has only one child, a leaf; root becomes leaf node */
        !           186:        {
        !           187:                /* move leaf values into root; root's position always remains
        !           188:                ** the same */
        !           189:                get_node(prt.page.node.intnode.ptr[0], &new);
        !           190:                new.parent = prt.page.parent;
        !           191:                write_node(rootpage, &new);
        !           192:                return_page(prt.page.node.intnode.ptr[0]);
        !           193:                if (new.nodetype  == 'I')
        !           194:                {
        !           195:                        for (i = 0; i < new.nelmts; ++i)
        !           196:                        {
        !           197:                                get_node(new.node.intnode.ptr[i], &temp);
        !           198:                                temp.parent = rootpage;
        !           199:                                write_node(new.node.intnode.ptr[i], &temp);
        !           200:                        }
        !           201:                }
        !           202:                else
        !           203:                {
        !           204:                        /* btree tid is being changed, must be reflected in
        !           205:                        ** secondary btree relation
        !           206:                        */
        !           207:                        concat(REPL_IN, Fileset, replbatch);
        !           208:                        if ((fp = fopen(replbatch, "w")) == NULL)
        !           209:                                syserr("can't open replbatch in delete_btree");
        !           210:                        count = 0;
        !           211:                        page = 0l;
        !           212:                        stuff_page(&newtid, &page);
        !           213:                        stuff_page(&oldtid, &prt.page.node.intnode.ptr[0]);
        !           214:                        for (i = 0; i < new.nelmts; ++i)
        !           215:                        {
        !           216:                                oldtid.line_id = newtid.line_id = new.node.leafnode.tid_loc[i];
        !           217:                                if (fwrite(&oldtid, 1, LIDSIZE, fp) != LIDSIZE)
        !           218:                                        syserr("write error in delete_btree");
        !           219:                                if (fwrite(&newtid, 1, LIDSIZE, fp) != LIDSIZE)
        !           220:                                        syserr("write error in delete_btree");
        !           221:                                ++count;
        !           222:                        }
        !           223:                        fclose(fp);
        !           224:                        repl_btree(replbatch, count);
        !           225:                        unlink(replbatch);
        !           226:                        unlink(ztack(REPL_OUT, Fileset));
        !           227:                }
        !           228:        }
        !           229: 
        !           230:        else if (prt.pageno != rootpage)
        !           231:        {
        !           232:                /* find the grandparent of the empty node */
        !           233:                gprt.pageno = prt.page.parent;
        !           234:                parentkey(prt.pageno, &gprt);
        !           235:                if (gprt.page.nelmts - 1 != gprt.offset)
        !           236:                {
        !           237:                        /* determine the right sibling of the parent node */
        !           238:                        sibling.pageno = gprt.page.node.intnode.ptr[gprt.offset + 1];
        !           239:                        get_node(sibling.pageno, &sibling.page);
        !           240: 
        !           241:                        if (sibling.page.nelmts > MAXPTRS / 2 + 1)
        !           242:                        /* distribute key/ptr pairs of parent and right sibling
        !           243:                        ** between the two nodes (since there are sufficient
        !           244:                        ** pairs to guarantee that both will have at the least
        !           245:                        ** the minimum number of required children) */
        !           246:                        {
        !           247:                                distribute(&prt, &sibling, &pkey, &skey);
        !           248:                                /* adjust key values in grandparent */
        !           249:                                gprt.page.node.intnode.key[gprt.offset] = pkey;
        !           250:                                gprt.page.node.intnode.key[gprt.offset + 1] = skey;
        !           251:                                write_node(gprt.pageno, &gprt.page);
        !           252:                                tracepath(rootpage, &gprt, -1);
        !           253:                                return;
        !           254:                        }
        !           255:                }
        !           256:                if (gprt.offset != 0)
        !           257:                {
        !           258:                        /* determine the left sibling of the parent node */
        !           259:                        sibling.pageno = gprt.page.node.intnode.ptr[gprt.offset - 1];
        !           260:                        get_node(sibling.pageno, &sibling.page);
        !           261: 
        !           262:                        if (sibling.page.nelmts > MAXPTRS / 2 + 1)
        !           263:                        /* distribute key/ptr pairs of parent and left sibling
        !           264:                        ** between the two nodes */
        !           265:                        {
        !           266:                                distribute(&sibling, &prt, &skey, &pkey);
        !           267:                                gprt.page.node.intnode.key[gprt.offset - 1] = skey;
        !           268:                                gprt.page.node.intnode.key[gprt.offset] = pkey;
        !           269:                                write_node(gprt.pageno, &gprt.page);
        !           270:                                tracepath(rootpage, &gprt, -1);
        !           271:                                return;
        !           272:                        }
        !           273:                }
        !           274: 
        !           275:                if (gprt.page.nelmts - 1 != gprt.offset)
        !           276:                /* combine parent node with its right sibling */
        !           277:                {
        !           278:                        sibling.pageno = gprt.page.node.intnode.ptr[gprt.offset + 1];
        !           279:                        get_node(sibling.pageno, &sibling.page);
        !           280:                        combine(&prt, &sibling);
        !           281:                }
        !           282:                else
        !           283:                /* combine parent node with its left sibling */
        !           284:                {
        !           285:                        sibling.pageno = gprt.page.node.intnode.ptr[gprt.offset - 1];
        !           286:                        get_node(sibling.pageno, &sibling.page);
        !           287:                        combine(&sibling, &prt);
        !           288:                        /* grandparent should point to newly combined block,
        !           289:                        ** the left sibling */
        !           290:                        --gprt.offset;
        !           291:                }
        !           292: 
        !           293:                get_node(gprt.page.node.intnode.ptr[gprt.offset], &new);
        !           294:                if (gprt.pageno == rootpage && gprt.page.nelmts == 2)
        !           295:                /* root has only one child, reduce B-Tree level */
        !           296:                {
        !           297:                        /* only child becomes root */
        !           298:                        new.parent = gprt.page.parent;
        !           299:                        write_node(rootpage, &new);
        !           300: 
        !           301:                        /* make sure "new's" children's parent is the root */
        !           302:                        for (i = 0; i < new.nelmts; ++i)
        !           303:                        {
        !           304:                                get_node(new.node.intnode.ptr[i], &temp);
        !           305:                                temp.parent = rootpage;
        !           306:                                write_node(new.node.intnode.ptr[i], &temp);
        !           307:                        }
        !           308:                        /* both of root's children empty */
        !           309:                        return_page(gprt.page.node.intnode.ptr[gprt.offset + 1]);
        !           310:                        return_page(gprt.page.node.intnode.ptr[gprt.offset]);
        !           311:                }
        !           312: 
        !           313:                else
        !           314:                {
        !           315:                        /* adjust key value in grandparent node */
        !           316:                        pkey = 0;
        !           317:                        for (i = 0; i < new.nelmts; ++i)
        !           318:                                pkey += new.node.intnode.key[i];
        !           319:                        gprt.page.node.intnode.key[gprt.offset] = pkey;
        !           320:                        write_node(gprt.pageno, &gprt.page);
        !           321: 
        !           322:                        /* remove ptr/key pair corresponding to empty node */
        !           323:                        gprt.pageno = gprt.page.node.intnode.ptr[gprt.offset + 1];
        !           324:                        get_node(gprt.pageno, &gprt.page);
        !           325:                        delete_key(rootpage, &gprt);
        !           326:                }
        !           327:        
        !           328:        }
        !           329: }
        !           330: 
        !           331: /*     Divides key/ptr pairs between the left and right nodes, so both will
        !           332: **     have the proper number of elements.
        !           333: **
        !           334: **     Parameters :
        !           335: **             tree - BTree filename (I)
        !           336: **             left - left node (I, O)
        !           337: **             right - "left's" right sibling (I, O)
        !           338: **             lkey - key value of the parent of left node (O)
        !           339: **             rkey - key value of the parent of right node (O)
        !           340: */
        !           341: 
        !           342: distribute(left, right, lkey, rkey)
        !           343: 
        !           344: register struct locator *left, *right;
        !           345: int *lkey, *rkey;
        !           346: {
        !           347:        register int            i, move;
        !           348:        struct BTreeNode        temp;
        !           349: 
        !           350:        if (right->page.nelmts > left->page.nelmts)
        !           351:        /* move elements from the right node to the left node */
        !           352:        {
        !           353:                move = MAXPTRS / 2 - left->page.nelmts;
        !           354: 
        !           355:                for (i = 1; i <= move; ++i)
        !           356:                /* move first part of right node into the end of the left node */
        !           357:                {
        !           358:                        left->page.node.intnode.ptr[i + left->page.nelmts] =
        !           359:                                right->page.node.intnode.ptr[i - 1];
        !           360:                        left->page.node.intnode.key[i + left->page.nelmts] =
        !           361:                                right->page.node.intnode.key[i - 1];
        !           362:                        /* adjust parents of children whose parents have been
        !           363:                        ** moved */
        !           364:                        get_node(left->page.node.intnode.ptr[i + left->page.nelmts], &temp);
        !           365:                        temp.parent = left->pageno;
        !           366:                        write_node(left->page.node.intnode.ptr[i + left->page.nelmts], &temp);
        !           367:                }
        !           368:                left->page.nelmts += move;
        !           369: 
        !           370:                for (i = move; i < right->page.nelmts; ++i)
        !           371:                /* flush right node values to the left */
        !           372:                {
        !           373:                        right->page.node.intnode.ptr[i - move] =
        !           374:                                right->page.node.intnode.ptr[i];
        !           375:                        right->page.node.intnode.key[i - move] =
        !           376:                                right->page.node.intnode.key[i];
        !           377:                }
        !           378:                right->page.nelmts -= move;
        !           379:        }
        !           380: 
        !           381:        else
        !           382:        /*  move left node values to the right node */
        !           383:        {
        !           384:                move = MAXPTRS / 2 - right->page.nelmts + 1;
        !           385: 
        !           386:                /* move right node values to the right to make room for left
        !           387:                ** node values */
        !           388:                for (i = right->page.nelmts - 1; i >= 0; --i)
        !           389:                {
        !           390:                        right->page.node.intnode.ptr[i + move] =
        !           391:                                right->page.node.intnode.ptr[i];
        !           392:                        right->page.node.intnode.key[i + move] =
        !           393:                                right->page.node.intnode.key[i];
        !           394:                }
        !           395: 
        !           396:                /* move latter part of left node into the now free space at the
        !           397:                ** beginning of the right node */
        !           398:                for (i = 0; i < move; ++i)
        !           399:                {
        !           400:                        right->page.node.intnode.ptr[i] = 
        !           401:                                left->page.node.intnode.ptr[left->page.nelmts - move + i];
        !           402:                        right->page.node.intnode.key[i] =
        !           403:                                left->page.node.intnode.key[left->page.nelmts - move + i];
        !           404:                        /* adjust parents of children whose parents have been
        !           405:                        ** moved */
        !           406:                        get_node(right->page.node.intnode.ptr[i], &temp);
        !           407:                        temp.parent = right->pageno;
        !           408:                        write_node(right->page.node.intnode.ptr[i], &temp);
        !           409:                }
        !           410:                left->page.nelmts -= move;
        !           411:                right->page.nelmts += move;
        !           412:        }
        !           413: 
        !           414:        /* calculate key values for parents of the left and right nodes */
        !           415:        *lkey = 0;
        !           416:        for (i = 0; i < left->page.nelmts; ++i)
        !           417:                *lkey += left->page.node.intnode.key[i];
        !           418:        *rkey = 0;
        !           419:        for (i = 0; i < right->page.nelmts; ++i)
        !           420:                *rkey += right->page.node.intnode.key[i];
        !           421:        write_node(left->pageno, &left->page);
        !           422:        write_node(right->pageno, &right->page);
        !           423: }
        !           424: 
        !           425: /*     Combines left and right nodes together to form one node.
        !           426: **
        !           427: **     Parameters :
        !           428: **             tree - BTree filename (I)
        !           429: **             left - left node (I, O)
        !           430: **             right - "left's" right sibling (I)
        !           431: */
        !           432: 
        !           433: combine(left, right)
        !           434: 
        !           435: register struct locator *left, *right;
        !           436: {
        !           437:        register int            i;
        !           438:        struct BTreeNode        temp;
        !           439: 
        !           440:        /* move all ptr/key values in the right node to the end of the left node */
        !           441:        for (i = 0; i < right->page.nelmts; ++i)
        !           442:        {
        !           443:                left->page.node.intnode.ptr[left->page.nelmts + i] =
        !           444:                        right->page.node.intnode.ptr[i];
        !           445:                left->page.node.intnode.key[left->page.nelmts + i] =
        !           446:                        right->page.node.intnode.key[i];
        !           447:                /* adjust parents of children whose parents have been moved */
        !           448:                get_node(left->page.node.intnode.ptr[left->page.nelmts + i], &temp);
        !           449:                temp.parent = left->pageno;
        !           450:                write_node(left->page.node.intnode.ptr[left->page.nelmts + i], &temp);
        !           451:        }
        !           452:        left->page.nelmts += right->page.nelmts;
        !           453:        write_node(left->pageno, &left->page);
        !           454: }

unix.superglobalmegacorp.com

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