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