home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / reviewed / volume03 / chipset2 / 06 < prev    next >
Encoding:
Text File  |  1993-03-13  |  20.9 KB  |  837 lines

  1. From decwrl!athertn!sander.cupertino.ca.us!paul@cs.purdue.edu Wed Jan  6 13:53:29 EST 1993
  2. Submit chipset-2 06/10 
  3. #! /bin/sh
  4. # This is a shell archive.  Remove anything before this line, then unpack
  5. # it by saving it into a file and typing "sh file".  To overwrite existing
  6. # files, type "sh file -c".  You can also feed this as standard input via
  7. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  8. # will see the following message at the end:
  9. #        "End of archive 6 (of 10)."
  10. # Contents:  src/btree/btinsert.c src/btree/btutil.c
  11. # Wrapped by paul@sander on Sun Nov 22 15:41:52 1992
  12. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  13. if test -f src/btree/btinsert.c -a "${1}" != "-c" ; then 
  14.   echo shar: Will not over-write existing file \"src/btree/btinsert.c\"
  15. else
  16. echo shar: Extracting \"src/btree/btinsert.c\" \(10881 characters\)
  17. sed "s/^X//" >src/btree/btinsert.c <<'END_OF_src/btree/btinsert.c'
  18. X/*********************************************************************
  19. X * 
  20. X * btinsert.c -- This file contains functions needed to insert new
  21. X *               items into an in-memory B-tree.
  22. X *
  23. X * This file is part of a suite of programs called Software Chipset.
  24. X * The source code for Software Chipset has been released into the
  25. X * public domain by its author, Paul Sander.
  26. X *
  27. X *********************************************************************/
  28. X
  29. X#include <stdio.h>
  30. X#include "btpriv.h"
  31. X
  32. X
  33. X/*********************************************************************
  34. X *                                                                   *
  35. X * bt_createNode -- This function allocates a node on the heap, and  *
  36. X *                  returns a pointer to it to the caller.  If an    *
  37. X *                  error occurs, any storage allocated is freed,    *
  38. X *                  and NULL is returned.                            *
  39. X *                                                                   *
  40. X *********************************************************************/
  41. X
  42. X#ifdef __STDC__
  43. Xstatic BTNODE *bt_createNode(BTREE tree, int children)
  44. X#else
  45. Xstatic BTNODE *bt_createNode(tree,children)
  46. XBTREE    tree;
  47. Xint    children;
  48. X#endif
  49. X{
  50. X    BTNODE    *new;
  51. X
  52. X    new = (BTNODE*) bt_malloc(sizeof(BTNODE));
  53. X    if (new != NULL)
  54. X    {
  55. X        new->keys = (void **) bt_malloc((tree->order-1)*sizeof(void*));
  56. X        if (new->keys != NULL)
  57. X        {
  58. X            new->data = (void **) bt_malloc(
  59. X                                     (tree->order-1)*sizeof(void*));
  60. X            if (new->data != NULL)
  61. X            {
  62. X                COVER("btinsert.c",1);
  63. X                if (children)
  64. X                {
  65. X                    COVER("btinsert.c",2);
  66. X                    new->children = (BTNODE**) bt_malloc(
  67. X                          (tree->order) * sizeof(BTNODE*));
  68. X                    if (new->children != NULL)
  69. X                    {
  70. X                        return new;
  71. X                    }
  72. X                }
  73. X                else
  74. X                {
  75. X                    COVER("btinsert.c",3);
  76. X                    new->children = NULL;
  77. X                    return new;
  78. X                }
  79. X                bt_free(new->data);
  80. X            }
  81. X            bt_free(new->keys);
  82. X        }
  83. X        bt_free(new);
  84. X    }
  85. X    return NULL;
  86. X}
  87. X
  88. X/*********************************************************************
  89. X *
  90. X * bt_insertKey -- This function inserts a key into a specified node at
  91. X *                 a specified location in its key array.  0 is returned
  92. X *                 if the node is already full, 1 otherwise.
  93. X *
  94. X *********************************************************************/
  95. X
  96. X#ifdef __STDC__
  97. Xstatic int bt_insertKey(BTNODE *node, void *key, int n, int order, void *data)
  98. X#else
  99. Xstatic int bt_insertKey(node,key,n,order,data)
  100. XBTNODE    *node;
  101. Xvoid    *key;
  102. Xint    n;
  103. Xint    order;
  104. Xvoid    *data;
  105. X#endif
  106. X{
  107. X    int    i;
  108. X
  109. X    /* Return FALSE if insertion is not possible */
  110. X    if (node->nkeys >= order - 1)
  111. X    {
  112. X        COVER("btinsert.c",4);
  113. X        return 0;
  114. X    }
  115. X
  116. X    /* Shift keys to make room, then insert new key */
  117. X    COVER("btinsert.c",5);
  118. X    for (i = node->nkeys - 1; i >= n; i--)
  119. X    {
  120. X        COVER("btinsert.c",6);
  121. X        node->keys[i+1] = node->keys[i];
  122. X        node->data[i+1] = node->data[i];
  123. X    }
  124. X    node->keys[n] = key;
  125. X    node->data[n] = data;
  126. X    node->nkeys++;
  127. X    node->tsize++;
  128. X    return 1;
  129. X}
  130. X
  131. X/*********************************************************************
  132. X *
  133. X * bt_burst -- Given a node and an index into its key and child arrays,
  134. X *             this function splits the specified child node in half,
  135. X *             elevating the key at the child's split point into this
  136. X *             specified node.  0 is returned if the child array index
  137. X *             is out of range, or the node is full, or malloc fails;
  138. X *             1 is returned otherwise.
  139. X *
  140. X *********************************************************************/
  141. X
  142. X#ifdef __STDC__
  143. Xstatic int bt_burst(BTREE tree, BTNODE *node, int n)
  144. X#else
  145. Xstatic int bt_burst(tree,node,n)
  146. XBTREE    tree;
  147. XBTNODE    *node;
  148. Xint    n;
  149. X#endif
  150. X{
  151. X    BTNODE    *new;
  152. X    int    i;
  153. X    int    m;
  154. X    BTNODE    *left;
  155. X    int    lkeys;
  156. X
  157. X    /* Test parameters */
  158. X    if ((node->nkeys > 0) && (node->nkeys >= tree->order - 1))
  159. X    {
  160. X        COVER("btinsert.c",7);
  161. X        return 0;
  162. X    }
  163. X    if (n < 0)
  164. X    {
  165. X        /* This should never happen */
  166. X        COVER("btinsert.c",8);
  167. X        return 0;
  168. X    }
  169. X
  170. X    /* Calculate needed partial results */
  171. X    COVER("btinsert.c",9);
  172. X    m = tree->order / 2;
  173. X    left = node->children[n];
  174. X    lkeys = left->nkeys;
  175. X
  176. X    /* Create a new node */
  177. X    new = bt_createNode(tree,(left->children != NULL));
  178. X    if (new != NULL)
  179. X    {
  180. X        new->parent = node;
  181. X        new->tsize = lkeys - m;
  182. X
  183. X        /* Split child array */
  184. X        if (left->children != NULL)
  185. X        {
  186. X            COVER("btinsert.c",10);
  187. X            for (i = 0; i <= lkeys - m; i++)
  188. X            {
  189. X                COVER("btinsert.c",11);
  190. X                new->children[i] = left->children[m + i];
  191. X                new->children[i]->parent = new;
  192. X                new->tsize += new->children[i]->tsize;
  193. X            }
  194. X        }
  195. X
  196. X        /* Split keys */
  197. X        COVER("btinsert.c",12);
  198. X        for (i = 0; i < lkeys - m; i++)
  199. X        {
  200. X            COVER("btinsert.c",13);
  201. X            new->keys[i] = left->keys[m + i];
  202. X            new->data[i] = left->data[m + i];
  203. X        }
  204. X        COVER("btinsert.c",14);
  205. X        new->nkeys = lkeys - m;
  206. X        left->nkeys = m - 1;
  207. X        left->tsize = left->tsize - new->tsize - 1;
  208. X
  209. X        /* Elevate the key where the split was made */
  210. X        for (i = node->nkeys; i > n; i--)
  211. X        {
  212. X            COVER("btinsert.c",15);
  213. X            node->keys[i] = node->keys[i-1];
  214. X            node->data[i] = node->data[i-1];
  215. X            node->children[i+1] = node->children[i];
  216. X        }
  217. X        COVER("btinsert.c",16);
  218. X        node->children[n+1] = new;
  219. X        node->keys[n] = left->keys[m - 1];
  220. X        node->data[n] = left->data[m - 1];
  221. X        node->nkeys++;
  222. X        tree->capacity += tree->order - 1;
  223. X        return 1;
  224. X    }
  225. X
  226. X    /* Failed to allocate new node, return FALSE */
  227. X    return 0;
  228. X}
  229. X
  230. X/*********************************************************************
  231. X *
  232. X * bt_rebalance -- This function tries to rebalance the two adjacent
  233. X *                 nodes.  This is needed when an insertion is attempted
  234. X *                 into a node that is already full but its neighbors are
  235. X *                 not, or when a deletion is made and the node is less
  236. X *                 than half-full.
  237. X *
  238. X *********************************************************************/
  239. X
  240. X#ifdef __STDC__
  241. Xstatic bt_rebalance(BTNODE *node, int n, int order)
  242. X#else
  243. Xstatic bt_rebalance(node,n,order)
  244. XBTNODE    *node;
  245. Xint    n;
  246. Xint    order;
  247. X#endif
  248. X{
  249. X    int    res;
  250. X
  251. X    COVER("btinsert.c",17);
  252. X    if (node->children[n]->nkeys < (order-1)/2)
  253. X    {
  254. X        COVER("btinsert.c",18);
  255. X        res = bt_rotateLeft(node,n,order);
  256. X    }
  257. X    else
  258. X    if ((n < node->nkeys) && (node->children[n+1]->nkeys < (order-1)/2))
  259. X    {
  260. X        /*
  261. X         * It turns out that the only time a tree needs to be
  262. X         * rebalanced by this function is after a burst.  When that
  263. X         * happens, the left child may have one less key than the
  264. X         * right.  If the key is inserted on the right, the left
  265. X         * rotation rebalances.  Otherwise, the key is inserted on
  266. X         * the left, and tree becomes balanced.  Therefore, this
  267. X         * branch should never be taken.
  268. X         */
  269. X        COVER("btinsert.c",19);
  270. X        res = bt_rotateRight(node,n,order);
  271. X    }
  272. X    COVER("btinsert.c",20);
  273. X    return;
  274. X}
  275. X
  276. X/*********************************************************************
  277. X *
  278. X * bt_insertNode -- This function performs a recursive-descent of a b-tree,
  279. X *                  inserting a new key in a leaf node.  If the leaf is
  280. X *                  full, the tree is reorganized to make room.  -1 is
  281. X *                  returned if the insert fails due to a duplicate key.
  282. X *                  0 is returned if the insert fails for some other
  283. X *                  reason.  1 is returned if successful.
  284. X *
  285. X *********************************************************************/
  286. X
  287. X#ifdef __STDC__
  288. Xstatic int bt_insertNode(BTREE tree, BTNODE *node, void *key, void *data)
  289. X#else
  290. Xstatic int bt_insertNode(tree,node,key,data)
  291. XBTREE    tree;
  292. XBTNODE    *node;
  293. Xvoid    *key;
  294. Xvoid    *data;
  295. X#endif
  296. X{
  297. X    int    i;
  298. X    int    res;
  299. X
  300. X    /* Locate proper place for new key in node */
  301. X    i = bt_searchNode(node,key,tree->comp,&res);
  302. X    if (res)
  303. X    {
  304. X        COVER("btinsert.c",21);
  305. X        return -1;
  306. X    }
  307. X
  308. X    /* If no children, insert key in this node */
  309. X    COVER("btinsert.c",22);
  310. X    if (node->children == NULL)
  311. X    {
  312. X        COVER("btinsert.c",23);
  313. X        res = bt_insertKey(node,key,i,tree->order,data);
  314. X        return res;
  315. X    }
  316. X
  317. X    /* Try to insert the new key in a child node */
  318. X    res = bt_insertNode(tree,node->children[i],key,data);
  319. X
  320. X    /* Child is full, reorganize */
  321. X    COVER("btinsert.c",24);
  322. X    if (res == 0)
  323. X    {
  324. X        COVER("btinsert.c",25);
  325. X        /* Try rotating right */
  326. X        if ((res == 0) && (i < node->nkeys) &&
  327. X            (node->children[i+1]->nkeys < tree->order - 2))
  328. X        {
  329. X            COVER("btinsert.c",26);
  330. X            res = bt_rotateRight(node,i,tree->order);
  331. X        }
  332. X
  333. X        /* Try rotating left */
  334. X        COVER("btinsert.c",27);
  335. X        if ((res == 0) && (i > 0) &&
  336. X            (node->children[i-1]->nkeys < tree->order - 2))
  337. X        {
  338. X            COVER("btinsert.c",28);
  339. X            res = bt_rotateLeft(node,i - 1,tree->order);
  340. X        }
  341. X
  342. X        /* Can't rotate, try bursting */
  343. X        COVER("btinsert.c",29);
  344. X        if (res == 0)
  345. X        {
  346. X            COVER("btinsert.c",30);
  347. X            res = bt_burst(tree,node,i);
  348. X        }
  349. X        COVER("btinsert.c",31);
  350. X        if (res > 0)
  351. X        {
  352. X            COVER("btinsert.c",32);
  353. X            res = bt_insertNode(tree,node,key,data);
  354. X            if (res > 0)
  355. X            {
  356. X                COVER("btinsert.c",33);
  357. X                bt_rebalance(node,i,tree->order);
  358. X            }
  359. X        }
  360. X    }
  361. X    else if (res > 0)
  362. X    {
  363. X        COVER("btinsert.c",34);
  364. X        node->tsize++;
  365. X    }
  366. X    COVER("btinsert.c",35);
  367. X    return res;
  368. X}
  369. X
  370. X/*********************************************************************
  371. X *
  372. X * bt_insert -- This function inserts a new key into a b-tree.  -1 is
  373. X *              returned if the insert fails due to a duplicate key.
  374. X *              0 is returned if the insert fails for some other
  375. X *              reason.  1 is returned if successful.
  376. X *
  377. X *********************************************************************/
  378. X
  379. X#ifdef __STDC__
  380. Xint bt_insert(void *ptree, void *key, void *data)
  381. X#else
  382. Xint bt_insert(ptree,key,data)
  383. Xvoid    *ptree;
  384. Xvoid    *key;
  385. Xvoid    *data;
  386. X#endif
  387. X{
  388. X    int    res;
  389. X    BTNODE    *new;
  390. X    BTNODE    *node;
  391. X    BTREE    tree;
  392. X
  393. X    if (ptree == NULL)
  394. X    {
  395. X        COVER("btinsert.c",36);
  396. X        return 0;
  397. X    }
  398. X
  399. X    if (key == NULL)
  400. X    {
  401. X        COVER("btinsert.c",37);
  402. X        return 0;
  403. X    }
  404. X
  405. X    tree = (BTREE) ptree;
  406. X
  407. X    /* Begin at root */
  408. X    node = tree->root;
  409. X
  410. X    /* If root is empty, insert first key */
  411. X    COVER("btinsert.c",38);
  412. X    if (node->nkeys == 0)
  413. X    {
  414. X        COVER("btinsert.c",39);
  415. X        node->keys[0] = key;
  416. X        node->data[0] = data;
  417. X        node->nkeys = 1;
  418. X        node->tsize = 1;
  419. X        tree->currNode = NULL;
  420. X        return 1;
  421. X    }
  422. X
  423. X    /* Try inserting new key */
  424. X    COVER("btinsert.c",40);
  425. X    res = bt_insertNode(tree,node,key,data);
  426. X
  427. X    /* If 0 return, burst the root, rebalance, and try again */
  428. X    if (res == 0)
  429. X    {
  430. X        COVER("btinsert.c",41);
  431. X        new = bt_createNode(tree,1);
  432. X        if (new != NULL)
  433. X        {
  434. X            new->nkeys = 0;
  435. X            new->tsize = node->tsize;
  436. X            new->children[0] = node;
  437. X            new->parent = NULL;
  438. X            node->parent = new;
  439. X            tree->root = new;
  440. X            tree->capacity += tree->order - 1;
  441. X            res = bt_burst(tree,new,0);
  442. X            if (res > 0)
  443. X            {
  444. X                COVER("btinsert.c",42);
  445. X                res = bt_insertNode(tree,new,key,data);
  446. X            }
  447. X            COVER("btinsert.c",43);
  448. X            if (res > 0)
  449. X            {
  450. X                COVER("btinsert.c",44);
  451. X                bt_rebalance(new,0,tree->order);
  452. X                tree->currNode = NULL;
  453. X            }
  454. X            COVER("btinsert.c",45);
  455. X            return res;
  456. X        }
  457. X    }
  458. X    COVER("btinsert.c",46);
  459. X    if (res > 0)
  460. X    {
  461. X        COVER("btinsert.c",47);
  462. X        tree->currNode = NULL;
  463. X    }
  464. X    COVER("btinsert.c",48);
  465. X    return res;
  466. X}
  467. X
  468. X/********** End of file ************/
  469. X
  470. END_OF_src/btree/btinsert.c
  471. if test 10881 -ne `wc -c <src/btree/btinsert.c`; then
  472.     echo shar: \"src/btree/btinsert.c\" unpacked with wrong size!
  473. fi
  474. # end of overwriting check
  475. fi
  476. if test -f src/btree/btutil.c -a "${1}" != "-c" ; then 
  477.   echo shar: Will not over-write existing file \"src/btree/btutil.c\"
  478. else
  479. echo shar: Extracting \"src/btree/btutil.c\" \(7759 characters\)
  480. sed "s/^X//" >src/btree/btutil.c <<'END_OF_src/btree/btutil.c'
  481. X/********************************************************************
  482. X *
  483. X * btutil.c -- This function contains utility functions that are
  484. X *             used for many features of an in-memory B-tree
  485. X *             implementation.
  486. X *
  487. X * This file is part of a suite of programs called Software Chipset.
  488. X * The source code for Software Chipset has been released into the
  489. X * public domain by its author, Paul Sander.
  490. X *
  491. X ********************************************************************/
  492. X
  493. X#define __BTUTIL_C__
  494. X#include <stdio.h>
  495. X#include "btpriv.h"
  496. X
  497. X
  498. X/********************************************************************
  499. X *
  500. X * bt_searchNode -- This function searches a node for a key.  If the key
  501. X *                  is found, its index in the node's key array is
  502. X *                  returned, along with a flag indicating that the key
  503. X *                  was found.  If the key is not found, the index of the
  504. X *                  next higher key in the key array is returned, along
  505. X *                  with a "not found" indication.
  506. X *
  507. X ********************************************************************/
  508. X
  509. X#ifdef __STDC__
  510. Xint bt_searchNode(BTNODE *node, void *target, int (*comp)(), int *eq)
  511. X#else
  512. Xint bt_searchNode(node,target,comp,eq)
  513. XBTNODE    *node;        /* Node to be searched */
  514. Xvoid    *target;    /* Key to search for */
  515. Xint    (*comp)();    /* strcmp()-like comparison function */
  516. Xint    *eq;        /* 0 if not found, non-zero otherwise */
  517. X#endif
  518. X{
  519. X    int    i;
  520. X    int    res;
  521. X    int    hi;
  522. X    int    lo;
  523. X
  524. X    res = -1;
  525. X
  526. X    /*
  527. X     * Perform linear search of node contains 7 keys or less,
  528. X     * otherwise perform binary search
  529. X     */
  530. X    COVER("btutil.c",1);
  531. X    if (node->nkeys <= 7)
  532. X    {
  533. X        COVER("btutil.c",2);
  534. X        for (i = 0; i < node->nkeys; i++)
  535. X        {
  536. X            res = (*comp)(node->keys[i],target);
  537. X            if (res >= 0)
  538. X            {
  539. X                COVER("btutil.c",3);
  540. X                break;
  541. X            }
  542. X        }
  543. X        COVER("btutil.c",4);
  544. X    }
  545. X    else
  546. X    {
  547. X        COVER("btutil.c",5);
  548. X        lo = 0;
  549. X        hi = node->nkeys - 1;
  550. X        while ((lo <= hi) && (res != 0))
  551. X        {
  552. X            i = (lo + hi) / 2;
  553. X            res = (*comp)(node->keys[i],target);
  554. X            if (res < 0)
  555. X            {
  556. X                COVER("btutil.c",6);
  557. X                lo = i + 1;
  558. X            }
  559. X            else if (res > 0)
  560. X            {
  561. X                COVER("btutil.c",7);
  562. X                hi = i - 1;
  563. X            }
  564. X            COVER("btutil.c",8);
  565. X        }
  566. X        if (res < 0)
  567. X        {
  568. X            COVER("btutil.c",9);
  569. X            i++;
  570. X        }
  571. X        COVER("btutil.c",10);
  572. X    }
  573. X    COVER("btutil.c",11);
  574. X    *eq = (res == 0);    /* Indicate successful search */
  575. X    node->currKey = i + *eq - 1;
  576. X    return i;
  577. X}
  578. X
  579. X/******************************************************************
  580. X *
  581. X * bt_rotateRight -- Given a node and an index into its key array, this
  582. X *                   function rotates the node right at the specified
  583. X *                   key.  This is used during insertion and deletion to
  584. X *                   keep the tree balanced.  The return value is 0 if
  585. X *                   the function fails, i.e. the node on the left
  586. X *                   cannot lose keys, the node on the right cannot
  587. X *                   gain keys, or the specified node is a leaf; 1 is
  588. X *                   returned if successful.
  589. X *
  590. X ******************************************************************/
  591. X
  592. X#ifdef __STDC__
  593. Xint bt_rotateRight(BTNODE *node,int n,int order)
  594. X#else
  595. Xint bt_rotateRight(node,n,order)
  596. XBTNODE    *node;
  597. Xint    n;
  598. Xint    order;
  599. X#endif
  600. X{
  601. X    int    i;
  602. X    BTNODE    *right;
  603. X    BTNODE    *left;
  604. X
  605. X    /* Test parameters */
  606. X    if (n >= node->nkeys)
  607. X    {
  608. X        /*
  609. X         * This branch is never taken because callers test this
  610. X         * condition.
  611. X         */
  612. X        COVER("btutil.c",12);
  613. X        return 0;
  614. X    }
  615. X    if (n < 0)
  616. X    {
  617. X        COVER("btutil.c",13);
  618. X        return 0;
  619. X    }
  620. X    COVER("btutil.c",14);
  621. X
  622. X    /* Point to children */
  623. X    left = node->children[n];
  624. X    right = node->children[n+1];
  625. X
  626. X    /* Return FALSE if rotation is not possible */
  627. X    if (left == NULL)
  628. X    {
  629. X        /*
  630. X         * This branch is never taken, because the callers insure
  631. X         * that this node has children.
  632. X         */
  633. X        COVER("btutil.c",15);
  634. X        return 0;
  635. X    }
  636. X    if (left->nkeys <= order/2)
  637. X    {
  638. X        COVER("btutil.c",16);
  639. X        return 0;
  640. X    }
  641. X    if (right->nkeys >= order - 1)
  642. X    {
  643. X        /*
  644. X         * Coverage analysis was unable to stimulate this branch,
  645. X         * but inspection indicates that it is correct.
  646. X         */
  647. X        COVER("btutil.c",17);
  648. X        return 0;
  649. X    }
  650. X    COVER("btutil.c",18);
  651. X
  652. X    /* Shift the right child's keys */
  653. X    for (i = right->nkeys; i > 0; i--)
  654. X    {
  655. X        right->keys[i] = right->keys[i - 1];
  656. X        right->data[i] = right->data[i - 1];
  657. X    }
  658. X
  659. X    /* Rotate keys */
  660. X    right->keys[0] = node->keys[n];
  661. X    right->data[0] = node->data[n];
  662. X    node->keys[n] = left->keys[left->nkeys - 1];
  663. X    node->data[n] = left->data[left->nkeys - 1];
  664. X    left->keys[left->nkeys - 1] = NULL;
  665. X    left->data[left->nkeys - 1] = NULL;
  666. X
  667. X    if (right->children != NULL)
  668. X    {
  669. X        COVER("btutil.c",19);
  670. X        /* Shift the right child's children */
  671. X        for (i = right->nkeys; i >= 0; i--)
  672. X        {
  673. X            right->children[i + 1] = right->children[i];
  674. X        }
  675. X
  676. X        /* Rotate children */
  677. X        right->children[0] = left->children[left->nkeys];
  678. X        right->children[0]->parent = right;
  679. X        left->children[left->nkeys] = NULL;
  680. X        right->tsize += right->children[0]->tsize;
  681. X        left->tsize -= right->children[0]->tsize;
  682. X    }
  683. X    COVER("btutil.c",20);
  684. X
  685. X    /* Update key count and return TRUE */
  686. X    right->nkeys++;
  687. X    right->tsize++;
  688. X    left->nkeys--;
  689. X    left->tsize--;
  690. X    return 1;
  691. X}
  692. X
  693. X/******************************************************************
  694. X *
  695. X * bt_rotateLeft -- Given a node and an index into its key array, this
  696. X *                  function rotates the node left at the specified
  697. X *                  key.  This is used during insertion and deletion to
  698. X *                  keep the tree balanced.  The return value is 0 if
  699. X *                  the function fails, i.e. the node on the right
  700. X *                  cannot lose keys, the node on the left cannot
  701. X *                  gain keys, or the specified node is a leaf; 1 is
  702. X *                  returned when successful.
  703. X *
  704. X ******************************************************************/
  705. X
  706. X#ifdef __STDC__
  707. Xint bt_rotateLeft(BTNODE *node, int n, int order)
  708. X#else
  709. Xint bt_rotateLeft(node,n,order)
  710. XBTNODE    *node;
  711. Xint    n;
  712. Xint    order;
  713. X#endif
  714. X{
  715. X    int    i;
  716. X    BTNODE    *right;
  717. X    BTNODE    *left;
  718. X
  719. X    /* Test parameters */
  720. X    if (n < 0)
  721. X    {
  722. X        /*
  723. X         * This branch is never taken because callers test for this
  724. X         * condition.
  725. X         */
  726. X        COVER("btutil.c",21);
  727. X        return 0;
  728. X    }
  729. X    if (n >= node->nkeys)
  730. X    {
  731. X        COVER("btutil.c",22);
  732. X        return 0;
  733. X    }
  734. X    COVER("btutil.c",23);
  735. X
  736. X    /* Point to children */
  737. X    right = node->children[n+1];
  738. X    left = node->children[n];
  739. X
  740. X    /* Return FALSE if rotation is not possible */
  741. X    if (left == NULL)
  742. X    {
  743. X        /*
  744. X         * This branch is never taken, because the callers insure
  745. X         * that this node has children.
  746. X         */
  747. X        COVER("btutil.c",24);
  748. X        return 0;
  749. X    }
  750. X    if (right->nkeys <= order/2)
  751. X    {
  752. X        COVER("btutil.c",25);
  753. X        return 0;
  754. X    }
  755. X    if (left->nkeys >= order - 1)
  756. X    {
  757. X        /*
  758. X         * Coverage analysis was unable to stimulate this branch,
  759. X         * but inspection indicates that it is correct.
  760. X         */
  761. X        COVER("btutil.c",26);
  762. X        return 0;
  763. X    }
  764. X    COVER("btutil.c",27);
  765. X
  766. X    /* Rotate keys */
  767. X    left->keys[left->nkeys] = node->keys[n];
  768. X    left->data[left->nkeys] = node->data[n];
  769. X    node->keys[n] = right->keys[0];
  770. X    node->data[n] = right->data[0];
  771. X
  772. X    /* Update key counts */
  773. X    left->nkeys ++;
  774. X    right->nkeys --;
  775. X    left->tsize ++;
  776. X    right->tsize --;
  777. X
  778. X    /* Shift the right child's keys */
  779. X    for (i = 0; i < right->nkeys; i++)
  780. X    {
  781. X        right->keys[i] = right->keys[i+1];
  782. X        right->data[i] = right->data[i+1];
  783. X    }
  784. X    right->keys[i] = NULL;
  785. X    right->data[i] = NULL;
  786. X
  787. X    if (left->children != NULL)
  788. X    {
  789. X        COVER("btutil.c",28);
  790. X        left->tsize += right->children[0]->tsize;
  791. X        right->tsize -= right->children[0]->tsize;
  792. X
  793. X        /* Rotate children */
  794. X        left->children[left->nkeys] = right->children[0];
  795. X        left->children[left->nkeys]->parent = left;
  796. X
  797. X        /* Shift the right child's children */
  798. X        for (i = 0; i <= right->nkeys; i++)
  799. X        {
  800. X            right->children[i] = right->children[i+1];
  801. X        }
  802. X        right->children[i] = NULL;
  803. X    }
  804. X    COVER("btutil.c",29);
  805. X
  806. X    /* Return TRUE */
  807. X    return 1;
  808. X}
  809. X
  810. X/*********** End of file ************/
  811. X
  812. END_OF_src/btree/btutil.c
  813. if test 7759 -ne `wc -c <src/btree/btutil.c`; then
  814.     echo shar: \"src/btree/btutil.c\" unpacked with wrong size!
  815. fi
  816. # end of overwriting check
  817. fi
  818. echo shar: End of archive 6 \(of 10\).
  819. cp /dev/null ark6isdone
  820. MISSING=""
  821. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  822.     if test ! -f ark${I}isdone ; then
  823.     MISSING="${MISSING} ${I}"
  824.     fi
  825. done
  826. if test "${MISSING}" = "" ; then
  827.     echo You have unpacked all 10 archives.
  828.     echo "Now edit common.mk and do a 'make all'"
  829.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  830. else
  831.     echo You still need to unpack the following archives:
  832.     echo "        " ${MISSING}
  833. fi
  834. ##  End of shell archive.
  835. exit 0
  836.  
  837.