home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 170_01 / isamget.c < prev    next >
Text File  |  1979-12-31  |  4KB  |  172 lines

  1. /*
  2. **                 ISAMC - Written by John M. Dashner
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h>
  7.  
  8. #include <isam.h>
  9.  
  10. /*
  11. **                  GET - Retrieve Index Record by Key
  12. */
  13.  
  14. static int generic;        /* generic search flag */
  15. static char buf[MAXKEY + 2];
  16.  
  17. unsigned isamget(hdr, key)
  18. struct isam *hdr;
  19. char *key;
  20. {
  21.     int rc;
  22.     unsigned lo, hi, cur_rec;
  23.     char wrk[MAXKEY + 1];
  24.  
  25.     if (strlen(key) == 0)
  26.     {
  27.         cur_rec = 2;
  28.         return(_isget(hdr, cur_rec));
  29.     }
  30.     if((strlen(key) == 1) && (*key == '*'))
  31.     {
  32.         cur_rec = hdr->q3 - 1;
  33.         return(_isget(hdr, cur_rec));
  34.     }
  35.     if (strlen(key) < hdr->q6)
  36.         generic = TRUE;             /* set generic search */
  37.     else
  38.         generic = FALSE;
  39.  
  40.     setmem(wrk, MAXKEY + 1, 0);     /* set wrk space to low-values */
  41.     strcpy(wrk, key);
  42.     lo = 2;                         /* set up search variables */
  43.     hi = hdr->q3 - 1;
  44.     cur_rec = (lo + hi) / 2;
  45.     for(;;)
  46.     {
  47.         if (lo > hi)
  48.         {
  49.             isam_err = 1;
  50.             return ERROR;
  51.         }
  52.         if(_isget(hdr, cur_rec) == ERROR)
  53.             return ERROR;
  54.         if (buf[2] == 255)          /* ck for a deleted rec */
  55.         {
  56.             cur_rec--;              /* look dn one */
  57.             if (cur_rec >= lo)      /* ck bounds */
  58.                 continue;
  59.             else
  60.             {
  61.                 lo = (lo + hi) / 2 + 1;
  62.                 cur_rec = (lo + hi) / 2;
  63.                 continue;
  64.             }
  65.         }
  66.         else
  67.         {
  68.             if (generic)
  69.             {
  70.                 if (strcmp(wrk, &buf[2]) > 0)
  71.                     return(_srgen(hdr, wrk, hi));
  72.                 hi = cur_rec - 1;
  73.                 cur_rec = (lo + hi) / 2;
  74.                 continue;
  75.             }
  76.             if ((rc = strcmp(wrk, &buf[2])) == 0)
  77.                 return(_srfrst(hdr, wrk));
  78.             if (rc > 0)
  79.             {
  80.                 lo = cur_rec + 1;
  81.                 cur_rec = (lo + hi) / 2;
  82.                 continue;
  83.             }
  84.             else
  85.             {
  86.                 hi = cur_rec - 1;
  87.                 cur_rec = (lo + hi) / 2;
  88.                 continue;
  89.             }
  90.         }
  91.     }
  92. }
  93.  
  94. static _isget(hdr, rec)        /* utility get routine */
  95. struct isam *hdr;
  96. int rec;
  97. {
  98.     long lrec;
  99.  
  100.     hdr->q4 = rec;
  101.     lrec = rec * (hdr->q6 + 2);
  102.     lseek(hdr->q7, lrec, 0);
  103.     if (read(hdr->q7, buf, hdr->q6 + 2) == ERROR)
  104.     {
  105.         isam_err = 8;
  106.         return ERROR;
  107.     }
  108.     return NULL;
  109. }
  110.  
  111. static _srgen(hdr, okey, key, h)       /* finish up generic search */
  112. struct isam *hdr;
  113. char *okey, *key;
  114. unsigned h;
  115. {
  116.     int i;
  117.     unsigned l, rec;
  118.     struct rec3 *r3;
  119.  
  120.     l = hdr->q4 + 1;             /* set low bound at current rec + 1 */
  121.     rec = (l + h) / 2;
  122.     if (l > h)
  123.     {
  124.         isam_err = 1;       /* no rec which is >= to key */
  125.         return ERROR;
  126.     }
  127.     if (_isget(hdr, rec) == ERROR)
  128.         return ERROR;
  129.     if (strcmp(key, &buf[2]) > 0)
  130.         return(_srgen(hdr, key, h));    /* recursively decrease span */
  131.     for(rec = l;rec <= h;rec++)          /* slide up to it */
  132.     {
  133.         if (_isget(hdr, rec) == ERROR)
  134.             return ERROR;
  135.         if (strcmp(key, &buf[2]) <= 0)
  136.         {
  137.             isam_err = 0;
  138.             r3 = (struct rec3 *) buf;
  139.             for(i=0; i<hdr->q6; i++)     /* return actual key found */
  140.                 okey[i] = r3->idx_key[i];
  141.             return r3->rec_ptr;
  142.         }
  143.     }
  144.     isam_err = 1;       /* didn't make it */
  145.     return ERROR;
  146. }
  147.  
  148. static _srfrst(hdr, key)        /* slide down to first occurence */
  149. struct isam *hdr;
  150. char *key;
  151. {
  152.     struct rec3 *r3;
  153.     unsigned rec;
  154.     r3 = (struct rec3 *) buf;
  155.  
  156.     for(rec = hdr->q4 - 1;rec > 1; rec--)
  157.     {
  158.         if (_isget(hdr, rec) == ERROR)
  159.             return ERROR;
  160.         if (strcmp(key, &r3->idx_key[0]) != 0)
  161.         {
  162.             if(_isget(hdr, rec + 1) == ERROR)
  163.                 return ERROR;
  164.             isam_err = 0;
  165.             return r3->rec_ptr;
  166.         }
  167.     }
  168.     isam_err = 0;
  169.     return r3->rec_ptr;
  170. }
  171.  
  172.