Main Page | Namespace List | Class List | File List | Class Members | File Members | Related Pages

cdb.c

Go to the documentation of this file.
00001 /* Public domain. */
00002 
00003 #include <sys/types.h>
00004 #include <sys/stat.h>
00005 #include <sys/mman.h>
00006 #include "readwrite.h"
00007 #include "error.h"
00008 #include "seek.h"
00009 #include "byte.h"
00010 #include "cdb.h"
00011 
00012 void cdb_free(struct cdb *c)
00013 {
00014   if (c->map) {
00015     munmap(c->map,c->size);
00016     c->map = 0;
00017   }
00018 }
00019 
00020 void cdb_findstart(struct cdb *c)
00021 {
00022   c->loop = 0;
00023 }
00024 
00025 void cdb_init(struct cdb *c,int fd)
00026 {
00027   struct stat st;
00028   char *x;
00029 
00030   cdb_free(c);
00031   cdb_findstart(c);
00032   c->fd = fd;
00033 
00034   if (fstat(fd,&st) == 0)
00035     if (st.st_size <= 0xffffffff) {
00036       x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0);
00037       if (x + 1) {
00038         c->size = st.st_size;
00039         c->map = x;
00040       }
00041     }
00042 }
00043 
00044 int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos)
00045 {
00046   if (c->map) {
00047     if ((pos > c->size) || (c->size - pos < len)) goto FORMAT;
00048     byte_copy(buf,len,c->map + pos);
00049   }
00050   else {
00051     if (seek_set(c->fd,pos) == -1) return -1;
00052     while (len > 0) {
00053       int r;
00054       do
00055         r = read(c->fd,buf,len);
00056       while ((r == -1) && (errno == error_intr));
00057       if (r == -1) return -1;
00058       if (r == 0) goto FORMAT;
00059       buf += r;
00060       len -= r;
00061     }
00062   }
00063   return 0;
00064 
00065   FORMAT:
00066   errno = error_proto;
00067   return -1;
00068 }
00069 
00070 static int match(struct cdb *c,char *key,unsigned int len,uint32 pos)
00071 {
00072   char buf[32];
00073   int n;
00074 
00075   while (len > 0) {
00076     n = sizeof buf;
00077     if (n > len) n = len;
00078     if (cdb_read(c,buf,n,pos) == -1) return -1;
00079     if (byte_diff(buf,n,key)) return 0;
00080     pos += n;
00081     key += n;
00082     len -= n;
00083   }
00084   return 1;
00085 }
00086 
00087 int cdb_findnext(struct cdb *c,char *key,unsigned int len)
00088 {
00089   char buf[8];
00090   uint32 pos;
00091   uint32 u;
00092 
00093   if (!c->loop) {
00094     u = cdb_hash(key,len);
00095     if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1;
00096     uint32_unpack(buf + 4,&c->hslots);
00097     if (!c->hslots) return 0;
00098     uint32_unpack(buf,&c->hpos);
00099     c->khash = u;
00100     u >>= 8;
00101     u %= c->hslots;
00102     u <<= 3;
00103     c->kpos = c->hpos + u;
00104   }
00105 
00106   while (c->loop < c->hslots) {
00107     if (cdb_read(c,buf,8,c->kpos) == -1) return -1;
00108     uint32_unpack(buf + 4,&pos);
00109     if (!pos) return 0;
00110     c->loop += 1;
00111     c->kpos += 8;
00112     if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos;
00113     uint32_unpack(buf,&u);
00114     if (u == c->khash) {
00115       if (cdb_read(c,buf,8,pos) == -1) return -1;
00116       uint32_unpack(buf,&u);
00117       if (u == len)
00118         switch(match(c,key,len,pos + 8)) {
00119           case -1:
00120             return -1;
00121           case 1:
00122             uint32_unpack(buf + 4,&c->dlen);
00123             c->dpos = pos + 8 + len;
00124             return 1;
00125         }
00126     }
00127   }
00128 
00129   return 0;
00130 }
00131 
00132 int cdb_find(struct cdb *c,char *key,unsigned int len)
00133 {
00134   cdb_findstart(c);
00135   return cdb_findnext(c,key,len);
00136 }
00137 

Generated on Mon Apr 26 09:49:22 2004 for ConstantDataStore by doxygen 1.3.6-20040222