1 /* ISC license. */
2 
3 #include <stdint.h>
4 #include <string.h>
5 #include <skalibs/uint32.h>
6 #include <skalibs/cdb.h>
7 
match(struct cdb * c,char const * key,unsigned int len,uint32_t pos)8 static int match (struct cdb *c, char const *key, unsigned int len, uint32_t pos)
9 {
10   char buf[1024] ;
11   while (len > 0)
12   {
13     unsigned int n = 1024 ;
14     if (n > len) n = len ;
15     if (cdb_read(c, buf, n, pos) < 0) return -1 ;
16     if (memcmp(buf, key, n)) return 0 ;
17     pos += n ; key += n ; len -= n ;
18   }
19   return 1 ;
20 }
21 
cdb_findnext(struct cdb * c,char const * key,unsigned int len)22 int cdb_findnext (struct cdb *c, char const *key, unsigned int len)
23 {
24   char buf[8] ;
25   uint32_t pos ;
26   uint32_t u ;
27 
28   if (!c->loop)
29   {
30     u = cdb_hash(key, len) ;
31     if (cdb_read(c, buf, 8, (u << 3) & 2047) < 0) return -1 ;
32     uint32_unpack(buf + 4, &c->hslots) ;
33     if (!c->hslots) return 0 ;
34     uint32_unpack(buf, &c->hpos) ;
35     c->khash = u ;
36     u >>= 8 ;
37     u %= c->hslots ;
38     u <<= 3 ;
39     c->kpos = c->hpos + u ;
40   }
41 
42   while (c->loop < c->hslots)
43   {
44     if (cdb_read(c, buf, 8, c->kpos) < 0) return -1 ;
45     uint32_unpack(buf + 4, &pos) ;
46     if (!pos) return 0 ;
47     c->loop++ ;
48     c->kpos += 8 ;
49     if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos ;
50     uint32_unpack(buf, &u) ;
51     if (u == c->khash)
52     {
53       if (cdb_read(c, buf, 8, pos) < 0) return -1 ;
54       uint32_unpack(buf, &u) ;
55       if (u == len)
56 	  switch (match(c, key, len, pos + 8))
57       {
58         case -1:
59           return -1 ;
60         case 1:
61           uint32_unpack(buf + 4, &c->dlen) ;
62           c->dpos = pos + 8 + len ;
63           return 1 ;
64       }
65     }
66   }
67   return 0 ;
68 }
69