home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / online / source / c / compilers / Tickle-4.0.sit.hqx / Tickle-4.0 / cbtree / src / updutils.c < prev    next >
Text File  |  1993-05-22  |  3KB  |  136 lines

  1.  
  2. #include <types.h>
  3. #include "db.h"
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "btree.h"
  7.  
  8. /*
  9.  *  _BT_FIXSCAN -- Adjust a scan to cope with a change in tree structure.
  10.  *
  11.  *    If the user has an active scan on the database, and we delete an
  12.  *    item from the page the cursor is pointing at, we need to figure
  13.  *    out what to do about it.  Basically, the solution is to point
  14.  *    "between" keys in the tree, using the CRSR_BEFORE flag.  The
  15.  *    requirement is that the user should not miss any data in the
  16.  *    tree during a scan, just because he happened to do some deletions
  17.  *    or insertions while it was active.
  18.  *
  19.  *    In order to guarantee that the scan progresses properly, we need
  20.  *    to save the key of any deleted item we were pointing at, so that
  21.  *    we can check later insertions against it.
  22.  *
  23.  *    Parameters:
  24.  *        t -- tree to adjust
  25.  *        index -- index of item at which change was made
  26.  *        newd -- new datum (for insertions only)
  27.  *        op -- operation (DELETE or INSERT) causing change
  28.  *
  29.  *    Returns:
  30.  *        RET_SUCCESS, RET_ERROR (errno is set).
  31.  *
  32.  *    Side Effects:
  33.  *        None.
  34.  */
  35.  
  36. int
  37. _bt_fixscan(t, index, newd, op)
  38.     BTREE_P t;
  39.     index_t index;
  40.     DATUM *newd;
  41.     int op;
  42. {
  43.     CURSOR *c;
  44.     DATUM *d;
  45.  
  46.     c = &(t->bt_cursor);
  47.  
  48.     if (op == DELETE) {
  49.         if (index < c->c_index)
  50.             c->c_index--;
  51.         else if (index == c->c_index) {
  52.             if (!(c->c_flags & CRSR_BEFORE)) {
  53.                 if (_bt_crsrkey(t) == RET_ERROR)
  54.                     return (RET_ERROR);
  55.                 c->c_flags |= CRSR_BEFORE;
  56.             }
  57.         }
  58.     } else {
  59.         /*
  60.          *  If we previously deleted the object at this location,
  61.          *  and now we're inserting a new one, we need to do the
  62.          *  right thing -- the cursor should come either before
  63.          *  or after the new item, depending on the key that was
  64.          *  here, and the new one.
  65.          */
  66.  
  67.         if (c->c_flags & CRSR_BEFORE) {
  68.             if (index <= c->c_index) {
  69.                 char *tmp;
  70.                 int itmp;
  71.                 pgno_t chain;
  72.                 int r;
  73.  
  74.                 d = (DATUM *) GETDATUM(t->bt_curpage, index);
  75.                 if (d->d_flags & D_BIGKEY) {
  76.                     bcopy(&(newd->d_bytes[0]),
  77.                           (char *) &chain,
  78.                           sizeof(chain));
  79.                     if (_bt_getbig(t, chain, &tmp, &itmp)
  80.                          == RET_ERROR)
  81.                         return (RET_ERROR);
  82.                 } else
  83.                     tmp = &(newd->d_bytes[0]);
  84.  
  85.                 r = (*(t->bt_compare))(tmp, c->c_key);
  86.                 if (r < 0)
  87.                     c->c_index++;
  88.  
  89.                 if (d->d_flags & D_BIGKEY)
  90.                     free (tmp);
  91.             }
  92.         } else if (index <= c->c_index)
  93.             c->c_index++;
  94.     }
  95.     return (RET_SUCCESS);
  96. }
  97.  
  98. /*
  99.  *  _BT_CRSRKEY -- Save a copy of the key of the record that the cursor
  100.  *           is pointing to.  The record is about to be deleted.
  101.  *
  102.  *    Parameters:
  103.  *        t -- btree
  104.  *
  105.  *    Returns:
  106.  *        RET_SUCCESS, RET_ERROR.
  107.  *
  108.  *    Side Effects:
  109.  *        Allocates memory for the copy which should be released when
  110.  *        it is no longer needed.
  111.  */
  112.  
  113. int
  114. _bt_crsrkey(t)
  115.     BTREE_P t;
  116. {
  117.     CURSOR *c;
  118.     DATUM *d;
  119.     pgno_t pgno;
  120.     int ignore;
  121.  
  122.     c = &(t->bt_cursor);
  123.     d = (DATUM *) GETDATUM(t->bt_curpage, c->c_index);
  124.  
  125.     if (d->d_flags & D_BIGKEY) {
  126.         bcopy(&(d->d_bytes[0]), (char *) &pgno, sizeof(pgno));
  127.         return (_bt_getbig(t, pgno, &(c->c_key), &ignore));
  128.     } else {
  129.         if ((c->c_key = (char *) cbMALLOC(d->d_ksize)) == (char *) NULL)
  130.             return (RET_ERROR);
  131.  
  132.         bcopy(&(d->d_bytes[0]), c->c_key, (size_t) (d->d_ksize));
  133.     }
  134.     return (RET_SUCCESS);
  135. }
  136.