//Listing 7: const_db_btree.C #include #include #include "except_util.h" #include "dbindex.h" namespace { template DBT pod2dbt(T & x) { DBT t; t.size = sizeof(T); t.data = (void *)&x; return t; } template 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; }