skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

cdb_findnext.c (1301B)


      1 /* ISC license. */
      2 
      3 #include <stdint.h>
      4 #include <string.h>
      5 
      6 #include <skalibs/uint32.h>
      7 #include <skalibs/cdb.h>
      8 #include "cdb-internal.h"
      9 
     10 int cdb_findnext (cdb const *c, cdb_data *out, char const *key, uint32_t len, cdb_find_state *d)
     11 {
     12   if (!d->loop)
     13   {
     14     uint32_t u = cdb_hash(key, len) ;
     15     char const *p = cdb_p(c, 8, (u << 3) & 2047) ;
     16     if (!p) return -1 ;
     17     uint32_unpack(p + 4, &d->hslots) ;
     18     if (!d->hslots) return 0 ;
     19     uint32_unpack(p, &d->hpos) ;
     20     d->khash = u ;
     21     u >>= 8 ;
     22     u %= d->hslots ;
     23     u <<= 3 ;
     24     d->kpos = d->hpos + u ;
     25   }
     26 
     27   while (d->loop < d->hslots)
     28   {
     29     uint32_t pos, u ;
     30     char const *p = cdb_p(c, 8, d->kpos) ;
     31     if (!p) return -1 ;
     32     uint32_unpack(p + 4, &pos) ;
     33     if (!pos) return 0 ;
     34     d->loop++ ;
     35     d->kpos += 8 ;
     36     if (d->kpos == d->hpos + (d->hslots << 3)) d->kpos = d->hpos ;
     37     uint32_unpack(p, &u) ;
     38     if (u == d->khash)
     39     {
     40       p = cdb_p(c, 8, pos) ;
     41       if (!p) return -1 ;
     42       uint32_unpack(p, &u) ;
     43       if (u == len)
     44       {
     45         char const *k = cdb_p(c, len, pos + 8) ;
     46         if (!k) return -1 ;
     47         if (!memcmp(key, k, len))
     48         {
     49           uint32_unpack(p + 4, &out->len) ;
     50           out->s = c->map + pos + 8 + len ;
     51           return 1 ;
     52         }
     53       }
     54     }
     55   }
     56   return 0 ;
     57 }