cdb_make_find.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:2k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* routines to search in in-progress cdb file
  2.  *
  3.  * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
  4.  * Public domain.
  5.  */
  6. #include "common/setup_before.h"
  7. #include <stdio.h>
  8. #include "cdb_int.h"
  9. #include "common/setup_after.h"
  10. static int
  11. match(FILE *fd, unsigned pos, const char *key, unsigned klen)
  12. {
  13.   unsigned char buf[64]; /*XXX cdb_buf may be used here instead */
  14.   if (fseek(fd, pos, SEEK_SET) || fread(buf, 1, 8, fd) != 8)
  15.     return -1;
  16.   if (cdb_unpack(buf) != klen)
  17.     return 0;
  18.   while(klen > sizeof(buf)) {
  19.     if (fread(buf, 1, sizeof(buf), fd) != sizeof(buf))
  20.       return -1;
  21.     if (memcmp(buf, key, sizeof(buf)) != 0)
  22.       return 0;
  23.     key += sizeof(buf);
  24.     klen -= sizeof(buf);
  25.   }
  26.   if (klen) {
  27.     if (fread(buf, 1, klen, fd) != klen)
  28.       return -1;
  29.     if (memcmp(buf, key, klen) != 0)
  30.       return 0;
  31.   }
  32.   return 1;
  33. }
  34. int
  35. _cdb_make_find(struct cdb_make *cdbmp,
  36.        const void *key, unsigned klen, unsigned hval,
  37.        struct cdb_rl **rlp)
  38. {
  39.   struct cdb_rl *rl = cdbmp->cdb_rec[hval&255];
  40.   int r, i;
  41.   int seeked = 0;
  42.   while(rl) {
  43.     for(i = rl->cnt - 1; i >= 0; --i) { /* search backward */
  44.       if (rl->rec[i].hval != hval)
  45. continue;
  46.       /*XXX this explicit flush may be unnecessary having
  47.        * smarter match() that looks to cdb_buf too, but
  48.        * most of a time here spent in finding hash values
  49.        * (above), not keys */
  50.       if (cdbmp->cdb_bpos != cdbmp->cdb_buf) {
  51.         if (fwrite(cdbmp->cdb_buf, 1,
  52.           cdbmp->cdb_bpos - cdbmp->cdb_buf, cdbmp->cdb_fd) < 0)
  53.           return -1;
  54.         cdbmp->cdb_bpos = cdbmp->cdb_buf;
  55.       }
  56.       seeked = 1;
  57.       r = match(cdbmp->cdb_fd, rl->rec[i].rpos, key, klen);
  58.       if (!r)
  59. continue;
  60.       if (r < 0)
  61. return -1;
  62.       if (fseek(cdbmp->cdb_fd, cdbmp->cdb_dpos, SEEK_SET))
  63.         return -1;
  64.       if (rlp)
  65. *rlp = rl;
  66.       return i + 1;
  67.     }
  68.     rl = rl->next;
  69.   }
  70.   if (seeked && fseek(cdbmp->cdb_fd, cdbmp->cdb_dpos, SEEK_SET))
  71.     return -1;
  72.   return 0;
  73. }
  74. int
  75. cdb_make_exists(struct cdb_make *cdbmp,
  76.                 const void *key, unsigned klen)
  77. {
  78.   return _cdb_make_find(cdbmp, key, klen, cdb_hash(key, klen), NULL);
  79. }