home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / CONTRIB / MBASE / MBASE50.TAR / mbase / src / util2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-25  |  11.5 KB  |  492 lines

  1. /*
  2.  * METALBASE 5.0
  3.  *
  4.  * Released October 1st, 1992 by Huan-Ti [ richid@owlnet.rice.edu ]
  5.  *                                       [ t-richj@microsoft.com ]
  6.  */
  7.  
  8. #define UTIL_C
  9. #include "mbase.h"
  10. #include "internal.h"
  11.  
  12. extern int       _started;
  13. extern relation *_list[MAX_REL];
  14.  
  15. /****************************************************************************/
  16.  
  17. mb_err
  18. _balance (rel, rcd, idx, bal)  /* CACHED */
  19. relation *rel;
  20. long           rcd;
  21. int                 idx, bal;
  22. {
  23.    long   rep, rp;
  24.    cache *ptr;
  25.  
  26.    if (! (rep = _find_seq (rel, 0L, rcd, idx, NUM_BAL(bal))) )
  27.       baderr (MB_CORRUPT);
  28.  
  29.    ptr = _read_cache (rel, rep, idx);
  30.    rp = ptr->parent;
  31.  
  32.    _dislink (rel, rep, idx, rcd);
  33.    _replace (rel, rcd, rep, idx);
  34.    _drop    (rel, rcd, idx, rep);
  35.  
  36.    if (rp != rcd)  _check (rel, rp, rep, idx);  /* Stop at _rep_ */
  37.  
  38.    ptr = _read_cache (rel, rcd, idx);
  39.    rp = ptr->parent;
  40.  
  41.    _check (rel, rp, rep, idx);
  42.  
  43.    baderr (MB_OKAY);
  44. }
  45.  
  46. void
  47. _dislink (rel, pos, idx, end)  /* CACHED */
  48. relation *rel;
  49. long           pos,      end;
  50. int                 idx;
  51. {
  52.    char   temp[5];
  53.    long   ch, par, tmp;
  54.    int    dir = 0, tdir;
  55.    cache *ptr;
  56.  
  57.    ptr = _read_cache (rel, pos, idx); /* There will be one child, at most */
  58.    ch = ptr->left;
  59.    if (ch)
  60.       dir = -1;
  61.    else
  62.       {
  63.       ch = ptr->right;     /* We already read in this record! */
  64.       dir = (ch ? 1 : 0);
  65.       }
  66.  
  67.    par = ptr->parent;
  68.    temp[0] = (char)((int)ptr->parbal & PARDIR);
  69.    tdir = temp[0]?1:-1;
  70.  
  71.    ptr = _read_cache (rel, par, idx);
  72.    ptr->changed = 1;
  73.    if (par == 0L)
  74.       {
  75.       _changeqcache (ptr, num, ch);
  76.       }
  77.    else
  78.       {
  79.       if (temp[0]) _changeqcache (ptr, right, ch);
  80.       else         _changeqcache (ptr, left,  ch);
  81.       }
  82.  
  83.    if (ch)
  84.       {
  85.       ptr = _read_cache (rel, ch, idx);
  86.       _change_cache (ptr, parent, par);
  87.       temp[0] = ptr->parbal;
  88.       temp[0] = (char)((int)(temp[0] & BAL) | (tdir == 1 ? PARDIR : 0));
  89.  
  90.       _change_cache (ptr, parbal, temp[0]);
  91.       }
  92.  
  93.    for (tmp=par, dir=tdir; tmp != 0L; )   /* Update balances: */
  94.       {
  95.       ptr = _read_cache (rel, tmp, idx);
  96.       temp[0] = ptr->parbal;
  97.       temp[0] = (char)((int)(temp[0] & PARDIR) | ((temp[0] & BAL) - dir));
  98.  
  99.       _change_cache (ptr, parbal, temp[0]);
  100.  
  101.       dir = (temp[0] & PARDIR) ? 1 : -1;
  102.       if (tmp == end)  break;
  103.  
  104.       tmp = ptr->parent;
  105.       }
  106. }
  107.  
  108. void
  109. _replace (rel, old, new, idx)  /* CACHED */
  110. relation *rel;
  111. long           old, new;
  112. int                      idx;
  113. {
  114.    char   pba;
  115.    long   lef, rig, par;
  116.    cache *ptr;
  117.  
  118.    ptr = _read_cache (rel, old, idx);
  119.       lef = ptr->left;
  120.       rig = ptr->right;
  121.       par = ptr->parent;
  122.       pba = ptr->parbal;
  123.    ptr = _read_cache (rel, new, idx);
  124.       _change_cache (ptr, left,   lef);
  125.       _changeqcache (ptr, right,  rig);
  126.       _changeqcache (ptr, parent, par);
  127.       _changeqcache (ptr, parbal, pba);
  128.  
  129.    if (par == 0L)   /* Parent */
  130.       {
  131.       ptr = _read_cache (rel, 0L, idx);
  132.       _change_cache (ptr, num, new);
  133.       }
  134.    else
  135.       {
  136.       ptr = _read_cache (rel, par, idx);
  137.       if (pba & PARDIR)  _changeqcache (ptr, right, new);
  138.       else               _changeqcache (ptr, left,  new);
  139.       ptr->changed = 1;
  140.       }
  141.  
  142.    if (lef != 0L)  /* Left child */
  143.       {
  144.       ptr = _read_cache (rel, lef, idx);
  145.       _change_cache (ptr, parent, new);
  146.       }
  147.  
  148.    if (rig != 0L)  /* Right child */
  149.       {
  150.       ptr = _read_cache (rel, rig, idx);
  151.       _change_cache (ptr, parent, new);
  152.       }
  153.  
  154.    _zero (rel, old, idx);  /* Remove old record's pointers */
  155. }
  156.  
  157. void
  158. _zero    (rel, pos, idx)  /* CACHED */
  159. relation *rel;
  160. long           pos;
  161. int                 idx;
  162. {
  163.    cache *ptr;
  164.    ptr = _read_cache (rel, pos, idx);
  165.    _change_cache (ptr, parbal, BAL_EV);
  166.    _changeqcache (ptr, left,   0L);
  167.    _changeqcache (ptr, right,  0L);
  168.    _changeqcache (ptr, parent, 0L);
  169. }
  170.  
  171. long
  172. _find_ends (rel, idx, dir)  /* CACHED */
  173. relation   *rel;
  174. int              idx, dir;
  175. {
  176.    long    pos, tmp;
  177.    cache  *ptr;
  178.  
  179.    _strobe (rel, 0);  /* Don't let anyone think we're dead */
  180.  
  181.    ptr = _read_cache (rel, 0L, idx);
  182.    pos = ptr->num;
  183.  
  184.    if (pos == 0L)  return 0L;
  185.  
  186.    for (tmp = pos; ; pos = tmp)
  187.       {
  188.       ptr = _read_cache (rel, tmp, idx);
  189.       tmp = _cache_field (ptr, dir);
  190.  
  191.       if (tmp == 0L)  return pos;
  192.       }
  193. }
  194.  
  195. long
  196. _search  (rel, pos, idx, act, comp)  /* CACHED */
  197. relation *rel;
  198. long           pos;
  199. int                 idx;
  200. mb_action                act;
  201. dataptr                       comp;
  202. {
  203.    long     x;
  204.    int      r,  dir;
  205.    dataptr  rec;
  206.    cache   *ptr;
  207.  
  208.    if (pos == 0L)  return 0;
  209.  
  210.    _strobe (rel, 0);  /* Don't let anyone think we're dead */
  211.  
  212.    ptr = _read_cache (rel, pos, idx);
  213.  
  214.    dir = r = _compare (rel, comp, rec=_rec(rel,pos), idx);
  215.    free (rec);
  216.  
  217.    if (dir == 0)
  218.     { if (act == GTHN || act == LTEQ)                 dir =  1;
  219.       if (act == GTEQ || act == LTHN || act == EQUL)  dir = -1;
  220.     }
  221.  
  222.    if ((x = _search (rel, (dir==1)?ptr->right:ptr->left, idx,act,comp)) != 0L)
  223.       return x;
  224.  
  225.    if  (act != GTHN && act != LTHN  && r    ==  0)  return pos;
  226.    if ((act == GTEQ || act == GTHN) && dir  == -1)  return pos;
  227.    if ((act == LTEQ || act == LTHN) && dir  ==  1)  return pos;
  228.  
  229.    return 0L;
  230. }
  231.  
  232. long
  233. _find_seq (rel, top, rcd, idx, dir)  /* CACHED */
  234. relation  *rel;
  235. long            top, rcd;
  236. int                       idx, dir;
  237. {
  238.    char   temp[5];
  239.    long   pos, tmp;
  240.    cache *ptr;
  241.  
  242.    _strobe (rel, 0);  /* Don't let anyone think we're dead */
  243.  
  244.    ptr = _read_cache (rel, rcd, idx);
  245.    pos = _cache_field (ptr, dir);
  246.  
  247.    if (pos == 0L)
  248.       {
  249.       if (rcd == top)  return 0L;      /* hit top=no sequential available */
  250.       for (pos = rcd; ; pos = tmp)
  251.          {
  252.          ptr = _read_cache (rel, pos, idx);
  253.          tmp = ptr->parent;
  254.  
  255.          if (tmp == top)  return 0L;    /* hit top=no sequential available */
  256.  
  257.          temp[0] = ptr->parbal;
  258.          if (dir == ((temp[0] & PARDIR) ? -1 : 1))  return tmp;
  259.          } 
  260.       } 
  261.  
  262.    for (dir = 0-dir; ; pos = tmp)
  263.       {
  264.       ptr = _read_cache (rel, pos, idx);
  265.       tmp = _cache_field (ptr, dir);
  266.       if (tmp == 0L)  return pos;
  267.       }
  268. }
  269.  
  270. long
  271. _delete  (rel, bad)  /* CACHED */
  272. relation *rel;
  273. long           bad;
  274. {
  275.    static   int  lastmove = -1;
  276.    register int  i;
  277.    long          bp, rep, rp;
  278.    char          buf[5];
  279.    int           bal;
  280.    cache        *ptr;
  281.  
  282.    _free_cache ();
  283.  
  284.    for (i = 0; i < rel->num_i; i++)
  285.       {
  286.       ptr = _read_cache (rel, bad, i);
  287.       bp     = ptr->parent;
  288.       buf[0] = ptr->parbal;
  289.  
  290.       bal= buf[0] & BAL;
  291.  
  292.       if (bal != BAL_EV)
  293.          rep = _find_seq (rel, bad, bad, i, NUM_BAL(bal));
  294.       else
  295.          if (! (rep = _find_seq (rel, bad, bad, i, togg (lastmove))))
  296.             rep = _find_seq (rel, bad, bad, i, togg (lastmove));
  297.  
  298.       if (! rep)
  299.          {
  300.          _dislink (rel, bad, i, 0L);
  301.          }
  302.       else
  303.          {
  304.          ptr = _read_cache (rel, rep, i);
  305.          rp = ptr->parent;
  306.  
  307.          _dislink (rel, rep, i, 0L);
  308.          _replace (rel, bad, rep, i);
  309.          if (rp != bad)
  310.             if (_check (rel, rp, bp, i))
  311.                {
  312.                _flush_cache (rel, i);
  313.                longerr (mb_errno, -1L);
  314.                }
  315.          }
  316.  
  317.       if (_check (rel, bp, 0L, i))
  318.          {
  319.          _flush_cache (rel, i);
  320.          longerr (mb_errno, -1L);
  321.          }
  322.  
  323.       _flush_cache (rel, i);
  324.       }
  325. }
  326.  
  327. int
  328. _compare (rel, ptra, ptrb, idx)  /* -1 == ptra < ptrb */
  329. relation *rel;
  330. dataptr        ptra, ptrb;
  331. int                        idx;
  332. {
  333.    register int  i;
  334.    int           mx, n, p;
  335.    char          temp[5];
  336.  
  337.    strzcpy (temp, rel->idxs[idx], 3);  mx = atoi (temp);
  338.  
  339.    for (i = 0; i < mx; i++)
  340.       {
  341.       strzcpy (temp, &rel->idxs[idx][3*i +3], 3);  p = atoi (temp);
  342.       if ((n = _comp_fld (rel, ptra, ptrb, p)) != 0)  return n;
  343.       }
  344.  
  345.    return 0;
  346. }
  347.  
  348. void
  349. _dumprec (rel, rec)  /* rec must not be encrypted */
  350. relation *rel;
  351. dataptr        rec;
  352. {
  353.    char          buf[128], temp[80], *p;
  354.    register int  i;
  355.  
  356.    buf[0] = 0;
  357.    for (i=0; i<rel->num_f; i++)
  358.       {
  359.       p=(char *)rec +rel->start[i];
  360.       switch (rel->type[i])
  361.          {
  362.          case T_CHAR:    strzcpy (temp, p, rel->siz[i]);               break;
  363.          case T_SHORT:   sprintf (temp,    "%d",  (int)*(short  *)p);  break;
  364.          case T_USHORT:  sprintf (temp,    "%u",  (int)*(ushort *)p);  break;
  365.          case T_LONG:    sprintf (temp,   "%ld", *(long   *)p);        break;
  366.          case T_ULONG:   sprintf (temp,   "%lu", *(ulong  *)p);        break;
  367.          case T_FLOAT:   sprintf (temp,    "%f", *(float  *)p);        break;
  368.          case T_DOUBLE:  sprintf (temp,   "%lf", *(double *)p);        break;
  369.          case T_MONEY:   sprintf (temp,"%-.2lf", *(double *)p);        break;
  370.          case T_TIME:    sprintf (temp,   "%ld", *(long   *)p);        break;
  371.          case T_DATE:    sprintf (temp,   "%ld", *(long   *)p);        break;
  372.          case T_SERIAL:  sprintf (temp,   "%ld", *(long   *)p);        break;
  373.          case T_PHONE:   strzcpy (temp, p, 20);                        break;
  374.          }
  375.       if (strlen (buf) + strlen (temp) > 126)  break;
  376.       strcat (buf, temp);
  377.       strcat (buf, "|");
  378.       }
  379.  
  380.    printf ("%s\n", buf);
  381. }
  382.  
  383. int
  384. _comp_fld (rel, ptra, ptrb, fld)
  385. relation  *rel;
  386. dataptr         ptra, ptrb;
  387. int                         fld;
  388. {
  389.    char  *a, *b;
  390.    int    n;
  391.  
  392.    n = rel->siz[fld];
  393.  
  394.    _cryptf ((dataptr)(a = (char *)ptra +rel->start[fld]), n, rel->mask);
  395.    _cryptf ((dataptr)(b = (char *)ptrb +rel->start[fld]), n, rel->mask);
  396.  
  397.    switch (rel->type[fld])
  398.       {
  399.       case T_SHORT:   n = _comp_short  ((short  *)a, (short  *)b);     break;
  400.       case T_USHORT:  n = _comp_ushort ((ushort *)a, (ushort *)b);     break;
  401.       case T_LONG:    n = _comp_long   ((long   *)a, (long   *)b);     break;
  402.       case T_ULONG:   n = _comp_ulong  ((ulong  *)a, (ulong  *)b);     break;
  403.       case T_FLOAT:   n = _comp_float  ((float  *)a, (float  *)b);     break;
  404.       case T_DOUBLE:  n = _comp_double ((double *)a, (double *)b);     break;
  405.       case T_MONEY:   n = _comp_double ((double *)a, (double *)b);     break;
  406.       case T_TIME:    n = _comp_long   ((long   *)a, (long   *)b);     break;
  407.       case T_DATE:    n = _comp_long   ((long   *)a, (long   *)b);     break;
  408.       case T_SERIAL:  n = _comp_long   ((long   *)a, (long   *)b);     break;
  409.       case T_PHONE:   n = _comp_string (a, b, n);  break;
  410.       default:        n = _comp_string (a, b, n);  break;
  411.       }
  412.  
  413.    _cryptf ((dataptr)a, rel->siz[fld], rel->mask);
  414.    _cryptf ((dataptr)b, rel->siz[fld], rel->mask);
  415.  
  416.    return n;
  417. }
  418.  
  419. int
  420. _comp_short (a, b)
  421. short       *a,*b;
  422. {
  423.    return ((*a < *b) ? -1 : (*a > *b) ? 1 : 0);
  424. }
  425.  
  426. int
  427. _comp_ushort (a, b)
  428. ushort       *a,*b;
  429. {
  430.    return ((*a < *b) ? -1 : (*a > *b) ? 1 : 0);
  431. }
  432.  
  433. int
  434. _comp_long (a, b)
  435. long       *a,*b;
  436. {
  437.    return ((*a < *b) ? -1 : (*a > *b) ? 1 : 0);
  438. }
  439.  
  440. int
  441. _comp_ulong (a, b)
  442. ulong       *a,*b;
  443. {
  444.    return ((*a < *b) ? -1 : (*a > *b) ? 1 : 0);
  445. }
  446.  
  447. int
  448. _comp_float (a, b)
  449. float       *a,*b;
  450. {
  451.    return ((*a < *b) ? -1 : (*a > *b) ? 1 : 0);
  452. }
  453.  
  454. int
  455. _comp_double (a, b)
  456. double       *a,*b;
  457. {
  458.    return ((*a < *b) ? -1 : (*a > *b) ? 1 : 0);
  459. }
  460.  
  461. int
  462. _comp_string (a, b, n)
  463. char         *a,*b;
  464. int                 n;
  465. {
  466.    int  i;
  467.    i = strncmp (a,b,n);            /* THIS WON'T RETURN -1,0,1!! It returns  */
  468.    return (i < 0) ? -1 : (i > 0);  /* different amounts on different systems */
  469. }
  470.  
  471. dataptr
  472. _rec     (rel, rcd)
  473. relation *rel;
  474. long           rcd;
  475. {
  476.    dataptr a;
  477.    a = (dataptr)malloc (1+ rel->rec_len);
  478.    return _memrec (rel, rcd, a);
  479. }
  480.  
  481. dataptr
  482. _memrec  (rel, rcd, a)
  483. relation *rel;
  484. long           rcd;
  485. dataptr             a;
  486. {
  487.    GO_RECID   (rel, rcd);
  488.    readx      (rel->relcode, a, rel->rec_len);
  489.    return a;
  490. }
  491.  
  492.