home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 228_01 / isamget.c < prev    next >
Text File  |  1987-07-31  |  5KB  |  185 lines

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