DB-SPEEDYB
view release on metacpan or search on metacpan
c/speedyb.c view on Meta::CPAN
#include "speedyb.h"
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#define MAGIC 0x1818
//#define DEBUG(M, ...) fprintf(stderr, "%s %s %5d: ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, M, __VA_ARGS__); fprintf(stderr, "\n");
#define DEBUG(M, ...)
//#define ERETURN(X) DEBUG("ERROR returning '%s'=%d\n", #X, (X)); return(X);
#define ERETURN(X) return X;
#define ASSERT_OPEN if(!r->store) { ERETURN(SPEEDYB_ENOPEN); }
typedef speedyb_reader_t dbh_t;
speedyb_rc_t speedyb_open(dbh_t *dbh, char *fn) {
void *db;
struct stat statbuf;
speedyb_header_t *header;
bzero(dbh, sizeof(dbh_t));
if((dbh->fd = open(fn, O_RDONLY)) < 0) {
ERETURN(SPEEDYB_EOPEN);
}
if(stat(fn, &statbuf)) {
ERETURN(SPEEDYB_EOPEN);
}
if(MAP_FAILED == (db = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, dbh->fd, 0))) {
ERETURN(SPEEDYB_EOPEN);
}
header = (speedyb_header_t*) db;
if(header->magic != MAGIC) {
ERETURN(SPEEDYB_EMAGIC);
}
if(header->proto_ver != 1) {
ERETURN(SPEEDYB_EVER);
}
dbh->g = (int*)(db + sizeof(speedyb_header_t));
dbh->v = dbh->g + header->nkeys;
dbh->nkeys = header->nkeys;
dbh->store = (char*)(dbh->v + header->nkeys);
dbh->store_len = statbuf.st_size - sizeof(speedyb_header_t) - 2 * dbh->nkeys * sizeof(int);
dbh->munmap_ptr = db;
dbh->munmap_len = statbuf.st_size;
DEBUG("header: %x %d\n", header->magic, header->nkeys);
return SPEEDYB_OK;
}
speedyb_rc_t speedyb_close(dbh_t *dbh) {
if(!dbh->store) {
ERETURN(SPEEDYB_ENOPEN);
}
if(munmap(dbh->munmap_ptr, dbh->munmap_len)) {
ERETURN(SPEEDYB_EIO);
}
if(close(dbh->fd)) {
ERETURN(SPEEDYB_EIO);
}
return SPEEDYB_OK;
}
/* d is 64-bit for compat with python. when we assign the result to 32-bit,
the upper bits are discarded */
static uint hash(uint64_t d, unsigned char *v, int vlen) {
int i;
//int od = d;
if(d == 0) {
d = 0x01000193;
}
// Use the FNV algorithm from http://isthe.com/chongo/tech/comp/fnv/
for(i=0; i<vlen; i++) {
d = ( (d * 0x01000193) ^ v[i] ) & 0xffffffff;
}
DEBUG("hash(%d, '%*.*s') = %ld", od, vlen, vlen, v, d);
return d;
}
/* Given a key, return offset into store of possible kv pair */
static int raw_hash_lookup(dbh_t *dbh, char *key, int keylen) {
uint hc, hcm;
int d; // negative = onceler
hc = hash(0, (unsigned char*)key, keylen);
hcm = hc % dbh->nkeys;
( run in 2.157 seconds using v1.01-cache-2.11-cpan-98e64b0badf )