Listing 8: const_db_btree.C
#include <errno.h>
#include <string.h>
#include "except_util.h"
#include "const_db_btree.h"
namespace {
template <class T>
DBT pod2dbt(T & x)
{
DBT t;
t.size = sizeof(T);
t.data = (void *)&x;
return t;
}
template <class T>
void dbt2pod(DBT dbt, T & x)
{ memcpy((void *)&x, dbt.data, dbt.size); }
int compare(DBT const * px, DBT const * py)
{
Date d1, d2;
dbt2pod(*px, d1);
dbt2pod(*py, d2);
return d1 < d2 ? -1 : d1 > d2 ? +1 : 0;
}
}
void const_db_btree::datagen::set(Key * startk, Key * endk)
{
if (startk) {
key = pod2dbt(*startk);
flag = R_CURSOR;
}
else
flag = R_FIRST;
if (endk) {
ek = *endk;
endkey = pod2dbt(ek);
}
else
endkey.data = 0;
}
bool const_db_btree::datagen::next()
{
if (flag == R_SETCURSOR) { // used only in db_btree
int code = dbp->put(dbp, &key, &data, flag);
if (code < 0)
throw unix_error(errno);
}
else {
int code = dbp->seq(dbp, &key, &data, flag);
if (code < 0)
throw unix_error(errno);
else if (code > 0 || endkey.data && compare(&key, &endkey) > 0)
return false;
dbt2pod(key, value_.first);
dbt2pod(data, value_.second);
}
flag = R_NEXT;
return true;
}
void const_db_btree::ctor(
char const * fname, bool multi, int flags, int mode
)
{
BTREEINFO info;
bzero(&info, sizeof(info));
info.prefix = 0; // Null pointer
info.compare = &compare;
if (multi)
info.flags = R_DUP;
body.dbp = dbopen(fname, flags, mode, DB_BTREE, (void *)&info);
if (!body.dbp)
throw unix_error(errno);
}
bool const_db_btree::get(Key k, Data & x) const
{
DBT key = pod2dbt(k), data;
int code = body.dbp->get(body.dbp, &key, &data, 0);
int e = errno;
if (code < 0)
throw unix_error(e);
else if (code > 0)
return false;
dbt2pod(data, x);
return true;
}
//End of File