|
|
5dff07f |
diff --git a/dbm/sdbm/sdbm.c b/dbm/sdbm/sdbm.c
|
|
|
5dff07f |
index a1ce695..a62b009 100644
|
|
|
5dff07f |
--- a/dbm/sdbm/sdbm.c
|
|
|
5dff07f |
+++ b/dbm/sdbm/sdbm.c
|
|
|
5dff07f |
@@ -40,7 +40,7 @@
|
|
|
5dff07f |
*/
|
|
|
5dff07f |
static int getdbit (apr_sdbm_t *, long);
|
|
|
5dff07f |
static apr_status_t setdbit(apr_sdbm_t *, long);
|
|
|
5dff07f |
-static apr_status_t getpage(apr_sdbm_t *db, long);
|
|
|
5dff07f |
+static apr_status_t getpage(apr_sdbm_t *db, long, int, int);
|
|
|
5dff07f |
static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db);
|
|
|
5dff07f |
static apr_status_t makroom(apr_sdbm_t *, long, int);
|
|
|
5dff07f |
|
|
|
5dff07f |
@@ -93,6 +93,7 @@ static apr_status_t prep(apr_sdbm_t **pdb, const char *dirname, const char *pagn
|
|
|
5dff07f |
|
|
|
5dff07f |
db = malloc(sizeof(*db));
|
|
|
5dff07f |
memset(db, 0, sizeof(*db));
|
|
|
5dff07f |
+ db->pagbno = -1L;
|
|
|
5dff07f |
|
|
|
5dff07f |
db->pool = p;
|
|
|
5dff07f |
|
|
|
5dff07f |
@@ -193,7 +194,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_fetch(apr_sdbm_t *db, apr_sdbm_datum_t *val,
|
|
|
5dff07f |
if ((status = apr_sdbm_lock(db, APR_FLOCK_SHARED)) != APR_SUCCESS)
|
|
|
5dff07f |
return status;
|
|
|
5dff07f |
|
|
|
5dff07f |
- if ((status = getpage(db, exhash(key))) == APR_SUCCESS) {
|
|
|
5dff07f |
+ if ((status = getpage(db, exhash(key), 0, 1)) == APR_SUCCESS) {
|
|
|
5dff07f |
*val = getpair(db->pagbuf, key);
|
|
|
5dff07f |
/* ### do we want a not-found result? */
|
|
|
5dff07f |
}
|
|
|
5dff07f |
@@ -227,7 +228,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_delete(apr_sdbm_t *db,
|
|
|
5dff07f |
if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS)
|
|
|
5dff07f |
return status;
|
|
|
5dff07f |
|
|
|
5dff07f |
- if ((status = getpage(db, exhash(key))) == APR_SUCCESS) {
|
|
|
5dff07f |
+ if ((status = getpage(db, exhash(key), 0, 1)) == APR_SUCCESS) {
|
|
|
5dff07f |
if (!delpair(db->pagbuf, key))
|
|
|
5dff07f |
/* ### should we define some APRUTIL codes? */
|
|
|
5dff07f |
status = APR_EGENERAL;
|
|
|
5dff07f |
@@ -261,7 +262,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_store(apr_sdbm_t *db, apr_sdbm_datum_t key,
|
|
|
5dff07f |
if ((status = apr_sdbm_lock(db, APR_FLOCK_EXCLUSIVE)) != APR_SUCCESS)
|
|
|
5dff07f |
return status;
|
|
|
5dff07f |
|
|
|
5dff07f |
- if ((status = getpage(db, (hash = exhash(key)))) == APR_SUCCESS) {
|
|
|
5dff07f |
+ if ((status = getpage(db, (hash = exhash(key)), 0, 1)) == APR_SUCCESS) {
|
|
|
5dff07f |
|
|
|
5dff07f |
/*
|
|
|
5dff07f |
* if we need to replace, delete the key/data pair
|
|
|
5dff07f |
@@ -376,17 +377,19 @@ static apr_status_t makroom(apr_sdbm_t *db, long hash, int need)
|
|
|
5dff07f |
|
|
|
5dff07f |
/* Reads 'len' bytes from file 'f' at offset 'off' into buf.
|
|
|
5dff07f |
* 'off' is given relative to the start of the file.
|
|
|
5dff07f |
- * If EOF is returned while reading, this is taken as success.
|
|
|
5dff07f |
+ * If 'create' is asked and EOF is returned while reading, this is taken
|
|
|
5dff07f |
+ * as success (i.e. a cleared buffer is returned).
|
|
|
5dff07f |
*/
|
|
|
5dff07f |
static apr_status_t read_from(apr_file_t *f, void *buf,
|
|
|
5dff07f |
- apr_off_t off, apr_size_t len)
|
|
|
5dff07f |
+ apr_off_t off, apr_size_t len,
|
|
|
5dff07f |
+ int create)
|
|
|
5dff07f |
{
|
|
|
5dff07f |
apr_status_t status;
|
|
|
5dff07f |
|
|
|
5dff07f |
if ((status = apr_file_seek(f, APR_SET, &off)) != APR_SUCCESS ||
|
|
|
5dff07f |
((status = apr_file_read_full(f, buf, len, NULL)) != APR_SUCCESS)) {
|
|
|
5dff07f |
/* if EOF is reached, pretend we read all zero's */
|
|
|
5dff07f |
- if (status == APR_EOF) {
|
|
|
5dff07f |
+ if (status == APR_EOF && create) {
|
|
|
5dff07f |
memset(buf, 0, len);
|
|
|
5dff07f |
status = APR_SUCCESS;
|
|
|
5dff07f |
}
|
|
|
5dff07f |
@@ -410,9 +413,7 @@ APU_DECLARE(apr_status_t) apr_sdbm_firstkey(apr_sdbm_t *db,
|
|
|
5dff07f |
/*
|
|
|
5dff07f |
* start at page 0
|
|
|
5dff07f |
*/
|
|
|
5dff07f |
- if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(0), PBLKSIZ))
|
|
|
5dff07f |
- == APR_SUCCESS) {
|
|
|
5dff07f |
- db->pagbno = 0;
|
|
|
5dff07f |
+ if ((status = getpage(db, 0, 1, 1)) == APR_SUCCESS) {
|
|
|
5dff07f |
db->blkptr = 0;
|
|
|
5dff07f |
db->keyptr = 0;
|
|
|
5dff07f |
status = getnext(key, db);
|
|
|
5dff07f |
@@ -441,24 +442,28 @@ APU_DECLARE(apr_status_t) apr_sdbm_nextkey(apr_sdbm_t *db,
|
|
|
5dff07f |
/*
|
|
|
5dff07f |
* all important binary tree traversal
|
|
|
5dff07f |
*/
|
|
|
5dff07f |
-static apr_status_t getpage(apr_sdbm_t *db, long hash)
|
|
|
5dff07f |
+static apr_status_t getpage(apr_sdbm_t *db, long hash, int by_num, int create)
|
|
|
5dff07f |
{
|
|
|
5dff07f |
- register int hbit;
|
|
|
5dff07f |
- register long dbit;
|
|
|
5dff07f |
- register long pagb;
|
|
|
5dff07f |
apr_status_t status;
|
|
|
5dff07f |
+ register long pagb;
|
|
|
5dff07f |
|
|
|
5dff07f |
- dbit = 0;
|
|
|
5dff07f |
- hbit = 0;
|
|
|
5dff07f |
- while (dbit < db->maxbno && getdbit(db, dbit))
|
|
|
5dff07f |
- dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
|
|
|
5dff07f |
+ if (by_num) {
|
|
|
5dff07f |
+ pagb = hash;
|
|
|
5dff07f |
+ }
|
|
|
5dff07f |
+ else {
|
|
|
5dff07f |
+ register int hbit = 0;
|
|
|
5dff07f |
+ register long dbit = 0;
|
|
|
5dff07f |
|
|
|
5dff07f |
- debug(("dbit: %d...", dbit));
|
|
|
5dff07f |
+ while (dbit < db->maxbno && getdbit(db, dbit))
|
|
|
5dff07f |
+ dbit = 2 * dbit + ((hash & (1 << hbit++)) ? 2 : 1);
|
|
|
5dff07f |
+ debug(("dbit: %d...", dbit));
|
|
|
5dff07f |
|
|
|
5dff07f |
- db->curbit = dbit;
|
|
|
5dff07f |
- db->hmask = masks[hbit];
|
|
|
5dff07f |
+ db->curbit = dbit;
|
|
|
5dff07f |
+ db->hmask = masks[hbit];
|
|
|
5dff07f |
+
|
|
|
5dff07f |
+ pagb = hash & db->hmask;
|
|
|
5dff07f |
+ }
|
|
|
5dff07f |
|
|
|
5dff07f |
- pagb = hash & db->hmask;
|
|
|
5dff07f |
/*
|
|
|
5dff07f |
* see if the block we need is already in memory.
|
|
|
5dff07f |
* note: this lookaside cache has about 10% hit rate.
|
|
|
5dff07f |
@@ -470,12 +475,14 @@ static apr_status_t getpage(apr_sdbm_t *db, long hash)
|
|
|
5dff07f |
* ### joe: this assumption was surely never correct? but
|
|
|
5dff07f |
* ### we make it so in read_from anyway.
|
|
|
5dff07f |
*/
|
|
|
5dff07f |
- if ((status = read_from(db->pagf, db->pagbuf, OFF_PAG(pagb), PBLKSIZ))
|
|
|
5dff07f |
- != APR_SUCCESS)
|
|
|
5dff07f |
+ if ((status = read_from(db->pagf, db->pagbuf,
|
|
|
5dff07f |
+ OFF_PAG(pagb), PBLKSIZ,
|
|
|
5dff07f |
+ create)) != APR_SUCCESS)
|
|
|
5dff07f |
return status;
|
|
|
5dff07f |
|
|
|
5dff07f |
if (!chkpage(db->pagbuf))
|
|
|
5dff07f |
return APR_ENOSPC; /* ### better error? */
|
|
|
5dff07f |
+
|
|
|
5dff07f |
db->pagbno = pagb;
|
|
|
5dff07f |
|
|
|
5dff07f |
debug(("pag read: %d\n", pagb));
|
|
|
5dff07f |
@@ -492,8 +499,9 @@ static int getdbit(apr_sdbm_t *db, long dbit)
|
|
|
5dff07f |
dirb = c / DBLKSIZ;
|
|
|
5dff07f |
|
|
|
5dff07f |
if (dirb != db->dirbno) {
|
|
|
5dff07f |
- if (read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ)
|
|
|
5dff07f |
- != APR_SUCCESS)
|
|
|
5dff07f |
+ if (read_from(db->dirf, db->dirbuf,
|
|
|
5dff07f |
+ OFF_DIR(dirb), DBLKSIZ,
|
|
|
5dff07f |
+ 1) != APR_SUCCESS)
|
|
|
5dff07f |
return 0;
|
|
|
5dff07f |
|
|
|
5dff07f |
db->dirbno = dirb;
|
|
|
5dff07f |
@@ -515,8 +523,9 @@ static apr_status_t setdbit(apr_sdbm_t *db, long dbit)
|
|
|
5dff07f |
dirb = c / DBLKSIZ;
|
|
|
5dff07f |
|
|
|
5dff07f |
if (dirb != db->dirbno) {
|
|
|
5dff07f |
- if ((status = read_from(db->dirf, db->dirbuf, OFF_DIR(dirb), DBLKSIZ))
|
|
|
5dff07f |
- != APR_SUCCESS)
|
|
|
5dff07f |
+ if ((status = read_from(db->dirf, db->dirbuf,
|
|
|
5dff07f |
+ OFF_DIR(dirb), DBLKSIZ,
|
|
|
5dff07f |
+ 1)) != APR_SUCCESS)
|
|
|
5dff07f |
return status;
|
|
|
5dff07f |
|
|
|
5dff07f |
db->dirbno = dirb;
|
|
|
5dff07f |
@@ -553,21 +562,12 @@ static apr_status_t getnext(apr_sdbm_datum_t *key, apr_sdbm_t *db)
|
|
|
5dff07f |
* try the next one... If we lost our position on the
|
|
|
5dff07f |
* file, we will have to seek.
|
|
|
5dff07f |
*/
|
|
|
5dff07f |
+ db->blkptr++;
|
|
|
5dff07f |
db->keyptr = 0;
|
|
|
5dff07f |
- if (db->pagbno != db->blkptr++) {
|
|
|
5dff07f |
- apr_off_t off = OFF_PAG(db->blkptr);
|
|
|
5dff07f |
- if ((status = apr_file_seek(db->pagf, APR_SET, &off))
|
|
|
5dff07f |
- != APR_SUCCESS)
|
|
|
5dff07f |
- return status;
|
|
|
5dff07f |
- }
|
|
|
5dff07f |
|
|
|
5dff07f |
- db->pagbno = db->blkptr;
|
|
|
5dff07f |
/* ### EOF acceptable here too? */
|
|
|
5dff07f |
- if ((status = apr_file_read_full(db->pagf, db->pagbuf, PBLKSIZ, NULL))
|
|
|
5dff07f |
- != APR_SUCCESS)
|
|
|
5dff07f |
+ if ((status = getpage(db, db->blkptr, 1, 0)) != APR_SUCCESS)
|
|
|
5dff07f |
return status;
|
|
|
5dff07f |
- if (!chkpage(db->pagbuf))
|
|
|
5dff07f |
- return APR_EGENERAL; /* ### need better error */
|
|
|
5dff07f |
}
|
|
|
5dff07f |
|
|
|
5dff07f |
/* NOTREACHED */
|
|
|
5dff07f |
diff --git a/dbm/sdbm/sdbm_pair.c b/dbm/sdbm/sdbm_pair.c
|
|
|
5dff07f |
index 2130200..af70614 100644
|
|
|
5dff07f |
--- a/dbm/sdbm/sdbm_pair.c
|
|
|
5dff07f |
+++ b/dbm/sdbm/sdbm_pair.c
|
|
|
5dff07f |
@@ -308,7 +308,8 @@ char *pag;
|
|
|
5dff07f |
if (n > 0) {
|
|
|
5dff07f |
off = PBLKSIZ;
|
|
|
5dff07f |
for (ino++; n > 0; ino += 2) {
|
|
|
5dff07f |
- if (ino[0] > off || ino[1] > off ||
|
|
|
5dff07f |
+ if (ino[0] < 0 || ino[0] > off ||
|
|
|
5dff07f |
+ ino[1] < 0 || ino[1] > off ||
|
|
|
5dff07f |
ino[1] > ino[0])
|
|
|
5dff07f |
return 0;
|
|
|
5dff07f |
off = ino[1];
|