Additional 4.4 update requirements -
12-13-2005
, 09:51 AM
The upgrade instructions for Berkeley DB 4.4 lack some items:
DB_CREATE must be specified when opening in-memory databases.
If DBC->c_get is invoked with two DBTs with the DB_DBT_USERMEM flag,
and the flag is DB_NEXT, and the key DBT is too small, and the value
in the database is empty, DBC->c_get returns a DB_BUFFER_SMALL error
code *and* advances the cursor. No solution is known, perhaps this is
a bug.
I've attached a test program below (this code is not representative of
what I usually write; error conditions are checked in my code). The
output with Berkeley DB 4.3 is:
AA:
B: 1
C: 2
With 4.4, I only get:
B: 1
C: 2
(It is not important if the critical record is the first one in the
database or not.)
#include <db.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
DB *db;
static void
assign_string (const char *str, DBT *dbt)
{
dbt->data = (void *)str;;
dbt->size = strlen (str);
dbt->ulen = 0;
dbt->flags = DB_DBT_USERMEM;
}
static void
add (const char *key, const char *value)
{
DBT k, v;
assign_string (key, &k);
assign_string (value, &v);
db->put (db, NULL, &k, &v, 0);
}
static void
alloc_dbt (DBT *dbt)
{
dbt->data = malloc (1);
dbt->size = 0;
dbt->ulen = 1;
dbt->flags = DB_DBT_USERMEM;
}
static void
realloc_dbt (DBT *dbt)
{
if (dbt->size > dbt->ulen)
{
size_t newlen = dbt->size;
dbt->data = realloc (dbt->data, newlen);
dbt->ulen = newlen;
}
}
static void
print (void)
{
DBC *dbc;
DBT k, v;
db->cursor (db, NULL, &dbc, 0);
alloc_dbt (&k);
alloc_dbt (&v);
while (1)
{
int result = dbc->c_get (dbc, &k, &v, DB_NEXT);
if (result == DB_NOTFOUND)
break;
if (result == DB_BUFFER_SMALL)
{
realloc_dbt (&k);
realloc_dbt (&v);
continue;
}
fwrite (k.data, 1, k.size, stdout);
putc (':', stdout);
putc (' ', stdout);
fwrite (v.data, 1, v.size, stdout);
putc ('\n', stdout);
}
}
int
main (void)
{
db_create (&db, NULL, 0);
db->open (db, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0);
add ("AA", "");
add ("B", "1");
add ("C", "2");
print ();
return 0;
} |