/[LeafOK_CVS]/pvpgn-1.7.4/src/tinycdb/cdb_seek.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/tinycdb/cdb_seek.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
CVS Tags: pvpgn_1-7-4-0_MIL
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.1 /* old interface for reading cdb file
2     *
3     * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
4     * Public domain.
5     */
6    
7     #include "common/setup_before.h"
8     #include <stdio.h>
9     #include "cdb_int.h"
10     #include "common/setup_after.h"
11    
12     #ifndef SEEK_SET
13     # define SEEK_SET 0
14     #endif
15    
16     /* read a chunk from file, ignoring interrupts (EINTR) */
17    
18     int
19     cdb_bread(FILE *fd, void *buf, int len)
20     {
21     int l;
22     while(len > 0) {
23     do l = fread(buf, 1, len, fd);
24     while(l < 0 && errno == EINTR);
25     if (l <= 0) {
26     if (!l)
27     errno = EIO;
28     return -1;
29     }
30     buf = (char*)buf + l;
31     len -= l;
32     }
33     return 0;
34     }
35    
36     /* find a given key in cdb file, seek a file pointer to it's value and
37     place data length to *dlenp. */
38    
39     int
40     cdb_seek(FILE *fd, const void *key, unsigned klen, unsigned *dlenp)
41     {
42     unsigned htstart; /* hash table start position */
43     unsigned htsize; /* number of elements in a hash table */
44     unsigned httodo; /* hash table elements left to look */
45     unsigned hti; /* hash table index */
46     unsigned pos; /* position in a file */
47     unsigned hval; /* key's hash value */
48     unsigned char rbuf[64]; /* read buffer */
49     int needseek = 1; /* if we should seek to a hash slot */
50    
51     hval = cdb_hash(key, klen);
52     pos = (hval & 0xff) << 3; /* position in TOC */
53     /* read the hash table parameters */
54     if (fseek(fd, pos, SEEK_SET) || cdb_bread(fd, rbuf, 8) < 0)
55     return -1;
56     if ((htsize = cdb_unpack(rbuf + 4)) == 0)
57     return 0;
58     hti = (hval >> 8) % htsize; /* start position in hash table */
59     httodo = htsize;
60     htstart = cdb_unpack(rbuf);
61    
62     for(;;) {
63     if (needseek && fseek(fd, htstart + (hti << 3), SEEK_SET))
64     return -1;
65     if (cdb_bread(fd, rbuf, 8) < 0)
66     return -1;
67     if ((pos = cdb_unpack(rbuf + 4)) == 0) /* not found */
68     return 0;
69    
70     if (cdb_unpack(rbuf) != hval) /* hash value not matched */
71     needseek = 0;
72     else { /* hash value matched */
73     if (fseek(fd, pos, SEEK_SET) || cdb_bread(fd, rbuf, 8) < 0)
74     return -1;
75     if (cdb_unpack(rbuf) == klen) { /* key length matches */
76     /* read the key from file and compare with wanted */
77     unsigned l = klen, c;
78     const char *k = (const char*)key;
79     if (*dlenp)
80     *dlenp = cdb_unpack(rbuf + 4); /* save value length */
81     for(;;) {
82     if (!l) /* the whole key read and matches, return */
83     return 1;
84     c = l > sizeof(rbuf) ? sizeof(rbuf) : l;
85     if (cdb_bread(fd, rbuf, c) < 0)
86     return -1;
87     if (memcmp(rbuf, k, c) != 0) /* no, it differs, stop here */
88     break;
89     k += c; l -= c;
90     }
91     }
92     needseek = 1; /* we're looked to other place, should seek back */
93     }
94     if (!--httodo)
95     return 0;
96     if (++hti == htsize) {
97     hti = 0;
98     needseek = 1;
99     }
100     }
101     }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1