diff options
Diffstat (limited to 'ext/dba/libcdb')
-rw-r--r-- | ext/dba/libcdb/cdb.c | 194 | ||||
-rw-r--r-- | ext/dba/libcdb/cdb.h | 57 | ||||
-rw-r--r-- | ext/dba/libcdb/cdb_make.c | 244 | ||||
-rw-r--r-- | ext/dba/libcdb/cdb_make.h | 64 | ||||
-rw-r--r-- | ext/dba/libcdb/uint32.c | 49 | ||||
-rw-r--r-- | ext/dba/libcdb/uint32.h | 39 |
6 files changed, 647 insertions, 0 deletions
diff --git a/ext/dba/libcdb/cdb.c b/ext/dba/libcdb/cdb.c new file mode 100644 index 0000000..2b101f8 --- /dev/null +++ b/ext/dba/libcdb/cdb.c @@ -0,0 +1,194 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: bc4ee08831fe552aab0f3fdce506f7b734dde461 $ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#include <sys/types.h> +#include <sys/stat.h> +#ifndef PHP_WIN32 +#include <sys/mman.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> +#include "cdb.h" + +#ifndef EPROTO +# define EPROTO -15 /* cdb 0.75's default for PROTOless systems */ +#endif + +/* {{{ cdb_match */ +static int cdb_match(struct cdb *c, char *key, unsigned int len, uint32 pos TSRMLS_DC) +{ + char buf[32]; + unsigned int n; + + while (len > 0) { + n = sizeof(buf); + if (n > len) + n = len; + if (cdb_read(c, buf, n, pos TSRMLS_CC) == -1) + return -1; + if (memcmp(buf, key, n)) + return 0; + pos += n; + key += n; + len -= n; + } + return 1; +} +/* }}} */ + +/* {{{ cdb_hash */ +uint32 cdb_hash(char *buf, unsigned int len) +{ + uint32 h; + const unsigned char * b = (unsigned char *)buf; + + h = CDB_HASHSTART; + while (len--) { + h = ( h + (h << 5)) ^ (*b++); + } + return h; +} +/* }}} */ + +/* {{{ cdb_free */ +void cdb_free(struct cdb *c TSRMLS_DC) +{ +} +/* }}} */ + +/* {{{ cdb_findstart */ +void cdb_findstart(struct cdb *c TSRMLS_DC) +{ + c->loop = 0; +} +/* }}} */ + +/* {{{ cdb_init */ +void cdb_init(struct cdb *c, php_stream *fp TSRMLS_DC) +{ + cdb_free(c TSRMLS_CC); + cdb_findstart(c TSRMLS_CC); + c->fp = fp; +} +/* }}} */ + +/* {{{ cdb_read */ +int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos TSRMLS_DC) +{ + if (php_stream_seek(c->fp, pos, SEEK_SET) == -1) { + errno = EPROTO; + return -1; + } + while (len > 0) { + int r; + do { + r = php_stream_read(c->fp, buf, len); + } while ((r == -1) && (errno == EINTR)); + if (r == -1) + return -1; + if (r == 0) { + errno = EPROTO; + return -1; + } + buf += r; + len -= r; + } + return 0; +} +/* }}} */ + +/* {{{ cdb_findnext */ +int cdb_findnext(struct cdb *c, char *key, unsigned int len TSRMLS_DC) +{ + char buf[8]; + uint32 pos; + uint32 u; + + if (!c->loop) { + u = cdb_hash(key, len); + if (cdb_read(c, buf, 8, (u << 3) & 2047 TSRMLS_CC) == -1) + return -1; + uint32_unpack(buf + 4,&c->hslots); + if (!c->hslots) + return 0; + uint32_unpack(buf, &c->hpos); + c->khash = u; + u >>= 8; + u %= c->hslots; + u <<= 3; + c->kpos = c->hpos + u; + } + + while (c->loop < c->hslots) { + if (cdb_read(c, buf, 8, c->kpos TSRMLS_CC) == -1) + return -1; + uint32_unpack(buf + 4, &pos); + if (!pos) + return 0; + c->loop += 1; + c->kpos += 8; + if (c->kpos == c->hpos + (c->hslots << 3)) + c->kpos = c->hpos; + uint32_unpack(buf, &u); + if (u == c->khash) { + if (cdb_read(c, buf, 8, pos TSRMLS_CC) == -1) + return -1; + uint32_unpack(buf, &u); + if (u == len) + switch(cdb_match(c, key, len, pos + 8 TSRMLS_CC)) { + case -1: + return -1; + case 1: + uint32_unpack(buf + 4, &c->dlen); + c->dpos = pos + 8 + len; + return 1; + } + } + } + + return 0; +} +/* }}} */ + +/* {{{ cdb_find */ +int cdb_find(struct cdb *c, char *key, unsigned int len TSRMLS_DC) +{ + cdb_findstart(c TSRMLS_CC); + return cdb_findnext(c, key, len TSRMLS_CC); +} +/* }}} */ + +/* {{{ cdb_version */ +char *cdb_version() +{ + return "0.75, $Id: bc4ee08831fe552aab0f3fdce506f7b734dde461 $"; +} +/* }}} */ diff --git a/ext/dba/libcdb/cdb.h b/ext/dba/libcdb/cdb.h new file mode 100644 index 0000000..5be8ec4 --- /dev/null +++ b/ext/dba/libcdb/cdb.h @@ -0,0 +1,57 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifndef CDB_H +#define CDB_H + +#include "uint32.h" + +#define CDB_HASHSTART 5381 + +struct cdb { + php_stream *fp; + uint32 loop; /* number of hash slots searched under this key */ + uint32 khash; /* initialized if loop is nonzero */ + uint32 kpos; /* initialized if loop is nonzero */ + uint32 hpos; /* initialized if loop is nonzero */ + uint32 hslots; /* initialized if loop is nonzero */ + uint32 dpos; /* initialized if cdb_findnext() returns 1 */ + uint32 dlen; /* initialized if cdb_findnext() returns 1 */ +}; + +uint32 cdb_hash(char *, unsigned int); + +void cdb_free(struct cdb * TSRMLS_DC); +void cdb_init(struct cdb *, php_stream *fp TSRMLS_DC); + +int cdb_read(struct cdb *, char *, unsigned int, uint32 TSRMLS_DC); + +void cdb_findstart(struct cdb * TSRMLS_DC); +int cdb_findnext(struct cdb *, char *, unsigned int TSRMLS_DC); +int cdb_find(struct cdb *, char *, unsigned int TSRMLS_DC); + +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) + +char *cdb_version(); + +#endif diff --git a/ext/dba/libcdb/cdb_make.c b/ext/dba/libcdb/cdb_make.c new file mode 100644 index 0000000..606b56e --- /dev/null +++ b/ext/dba/libcdb/cdb_make.c @@ -0,0 +1,244 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id: 154118c15260d2e1f134cf7534ff244ba31b4353 $ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include "cdb.h" +#include "cdb_make.h" +#include "uint32.h" + +/* {{{ cdb_make_write */ +static int cdb_make_write(struct cdb_make *c, char *buf, uint32 sz TSRMLS_DC) { + return php_stream_write(c->fp, buf, sz) == sz ? 0 : -1; +} + +/* {{{ cdb_posplus */ +static int cdb_posplus(struct cdb_make *c, uint32 len) +{ + uint32 newpos = c->pos + len; + if (newpos < len) { + errno = ENOMEM; + return -1; + } + c->pos = newpos; + return 0; +} +/* }}} */ + +/* {{{ cdb_make_start */ +int cdb_make_start(struct cdb_make *c, php_stream * f TSRMLS_DC) +{ + c->head = 0; + c->split = 0; + c->hash = 0; + c->numentries = 0; + c->fp = f; + c->pos = sizeof(c->final); + if (php_stream_seek(f, c->pos, SEEK_SET) == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Fseek failed"); + return -1; + } + return php_stream_tell(c->fp); +} +/* }}} */ + +/* {{{ cdb_make_addend */ +int cdb_make_addend(struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h TSRMLS_DC) +{ + struct cdb_hplist *head; + + head = c->head; + if (!head || (head->num >= CDB_HPLIST)) { + head = (struct cdb_hplist *) emalloc(sizeof(struct cdb_hplist)); + if (!head) + return -1; + head->num = 0; + head->next = c->head; + c->head = head; + } + head->hp[head->num].h = h; + head->hp[head->num].p = c->pos; + ++head->num; + ++c->numentries; + if (cdb_posplus(c,8) == -1) + return -1; + if (cdb_posplus(c, keylen) == -1) + return -1; + if (cdb_posplus(c, datalen) == -1) + return -1; + return 0; +} +/* }}} */ + +/* {{{ cdb_make_addbegin */ +int cdb_make_addbegin(struct cdb_make *c, unsigned int keylen, unsigned int datalen TSRMLS_DC) +{ + char buf[8]; + + if (keylen > 0xffffffff) { + errno = ENOMEM; + return -1; + } + if (datalen > 0xffffffff) { + errno = ENOMEM; + return -1; + } + + uint32_pack(buf, keylen); + uint32_pack(buf + 4, datalen); + if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) + return -1; + return 0; +} + +/* {{{ cdb_make_add */ +int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen TSRMLS_DC) +{ + if (cdb_make_addbegin(c, keylen, datalen TSRMLS_CC) == -1) + return -1; + if (cdb_make_write(c, key, keylen TSRMLS_CC) != 0) + return -1; + if (cdb_make_write(c, data, datalen TSRMLS_CC) != 0) + return -1; + return cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen) TSRMLS_CC); +} +/* }}} */ + +/* {{{ cdb_make_finish */ +int cdb_make_finish(struct cdb_make *c TSRMLS_DC) +{ + char buf[8]; + int i; + uint32 len; + uint32 u; + uint32 memsize; + uint32 count; + uint32 where; + struct cdb_hplist *x; + struct cdb_hp *hp; + + for (i = 0;i < 256;++i) + c->count[i] = 0; + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) + ++c->count[255 & x->hp[i].h]; + } + + memsize = 1; + for (i = 0;i < 256;++i) { + u = c->count[i] * 2; + if (u > memsize) + memsize = u; + } + + memsize += c->numentries; /* no overflow possible up to now */ + u = (uint32) 0 - (uint32) 1; + u /= sizeof(struct cdb_hp); + if (memsize > u) { + errno = ENOMEM; + return -1; + } + + c->split = (struct cdb_hp *) safe_emalloc(memsize, sizeof(struct cdb_hp), 0); + if (!c->split) + return -1; + + c->hash = c->split + c->numentries; + + u = 0; + for (i = 0;i < 256;++i) { + u += c->count[i]; /* bounded by numentries, so no overflow */ + c->start[i] = u; + } + + for (x = c->head; x; x = x->next) { + i = x->num; + while (i--) + c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; + } + + for (i = 0;i < 256;++i) { + count = c->count[i]; + + len = count + count; /* no overflow possible */ + uint32_pack(c->final + 8 * i,c->pos); + uint32_pack(c->final + 8 * i + 4,len); + + for (u = 0;u < len;++u) + c->hash[u].h = c->hash[u].p = 0; + + hp = c->split + c->start[i]; + for (u = 0;u < count;++u) { + where = (hp->h >> 8) % len; + while (c->hash[where].p) + if (++where == len) + where = 0; + c->hash[where] = *hp++; + } + + for (u = 0;u < len;++u) { + uint32_pack(buf, c->hash[u].h); + uint32_pack(buf + 4, c->hash[u].p); + if (cdb_make_write(c, buf, 8 TSRMLS_CC) != 0) + return -1; + if (cdb_posplus(c, 8) == -1) + return -1; + } + } + + if (c->split) + efree(c->split); + + for (x = c->head; x; c->head = x) { + x = x->next; + efree(c->head); + } + + if (php_stream_flush(c->fp) != 0) + return -1; + php_stream_rewind(c->fp); + if (php_stream_tell(c->fp) != 0) + return -1; + if (cdb_make_write(c, c->final, sizeof(c->final) TSRMLS_CC) != 0) + return -1; + return php_stream_flush(c->fp); +} +/* }}} */ + +/* {{{ cdb_make_version */ +char *cdb_make_version() +{ + return "0.75, $Id: 154118c15260d2e1f134cf7534ff244ba31b4353 $"; +} diff --git a/ext/dba/libcdb/cdb_make.h b/ext/dba/libcdb/cdb_make.h new file mode 100644 index 0000000..5bb0ddf --- /dev/null +++ b/ext/dba/libcdb/cdb_make.h @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifndef CDB_MAKE_H +#define CDB_MAKE_H + +#include <stdio.h> +#include "uint32.h" + +#define CDB_HPLIST 1000 + +struct cdb_hp { + uint32 h; + uint32 p; +}; + +struct cdb_hplist { + struct cdb_hp hp[CDB_HPLIST]; + struct cdb_hplist *next; + int num; +} ; + +struct cdb_make { + /* char bspace[8192]; */ + char final[2048]; + uint32 count[256]; + uint32 start[256]; + struct cdb_hplist *head; + struct cdb_hp *split; /* includes space for hash */ + struct cdb_hp *hash; + uint32 numentries; + /* buffer b; */ + uint32 pos; + /* int fd; */ + php_stream * fp; +}; + +int cdb_make_start(struct cdb_make *, php_stream * TSRMLS_DC); +int cdb_make_addbegin(struct cdb_make *, unsigned int, unsigned int TSRMLS_DC); +int cdb_make_addend(struct cdb_make *, unsigned int, unsigned int, uint32 TSRMLS_DC); +int cdb_make_add(struct cdb_make *, char *, unsigned int, char *, unsigned int TSRMLS_DC); +int cdb_make_finish(struct cdb_make * TSRMLS_DC); +char *cdb_make_version(); + +#endif diff --git a/ext/dba/libcdb/uint32.c b/ext/dba/libcdb/uint32.c new file mode 100644 index 0000000..803a3d5 --- /dev/null +++ b/ext/dba/libcdb/uint32.c @@ -0,0 +1,49 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#include "uint32.h" + +/* {{{ uint32_pack */ +void uint32_pack(char *out, uint32 in) +{ + out[0] = in&0xff; in>>=8; + out[1] = in&0xff; in>>=8; + out[2] = in&0xff; in>>=8; + out[3] = in&0xff; +} +/* }}} */ + +/* {{{ uint32_unpack */ +void uint32_unpack(const char *in, uint32 *out) +{ + *out = (((uint32)(unsigned char)in[3])<<24) | + (((uint32)(unsigned char)in[2])<<16) | + (((uint32)(unsigned char)in[1])<<8) | + (((uint32)(unsigned char)in[0])); +} +/* }}} */ diff --git a/ext/dba/libcdb/uint32.h b/ext/dba/libcdb/uint32.h new file mode 100644 index 0000000..ac44f05 --- /dev/null +++ b/ext/dba/libcdb/uint32.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +/* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ + +#ifndef UINT32_H +#define UINT32_H + +#if SIZEOF_INT == 4 +/* Most 32-bit and 64-bit systems have 32-bit ints */ +typedef unsigned int uint32; +#elif SIZEOF_LONG == 4 +/* 16-bit systems? */ +typedef unsigned long uint32; +#else +#error Need type which holds 32 bits +#endif + +void uint32_pack(char *out, uint32 in); +void uint32_unpack(const char *in, uint32 *out); + +#endif |