Commit 30803152 authored by Rich Prohaska's avatar Rich Prohaska

add Db::set_dup_compare closes #236

git-svn-id: file:///svn/tokudb@1440 c7de825b-a66e-492c-adef-691d508d4ae1
parent 7cec2925
......@@ -110,18 +110,45 @@ int Db::remove(const char *file, const char *database, u_int32_t flags) {
return the_Env->maybe_throw_error(ret);
}
extern "C" int toku_bt_compare_callback_c(DB *db_c, const DBT *a, const DBT *b) {
Db *db_cxx=Db::get_Db(db_c);
return db_cxx->bt_compare_callback_cxx(db_cxx, Dbt::get_const_Dbt(a), Dbt::get_const_Dbt(b));
}
int Db::set_bt_compare(int (*bt_compare_callback)(Db *, const Dbt *, const Dbt *)) {
bt_compare_callback_cxx = bt_compare_callback;
int ret = the_db->set_bt_compare(the_db, toku_bt_compare_callback_c);
return the_Env->maybe_throw_error(ret);
}
int Db::set_bt_compare(bt_compare_fcn_type bt_compare_fcn) {
int ret = the_db->set_bt_compare(the_db, bt_compare_fcn);
return the_Env->maybe_throw_error(ret);
}
int Db::set_dup_compare(dup_compare_fcn_type dup_compare_fcn) {
int ret = the_db->set_dup_compare(the_db, dup_compare_fcn);
return the_Env->maybe_throw_error(ret);
}
extern "C" int toku_dup_compare_callback_c(DB *db_c, const DBT *a, const DBT *b) {
Db *db_cxx=Db::get_Db(db_c);
return db_cxx->dup_compare_callback_cxx(db_cxx, Dbt::get_const_Dbt(a), Dbt::get_const_Dbt(b));
}
int Db::set_dup_compare(int (*dup_compare_callback)(Db *, const Dbt *, const Dbt *)) {
dup_compare_callback_cxx = dup_compare_callback;
int ret = the_db->set_dup_compare(the_db, toku_dup_compare_callback_c);
return the_Env->maybe_throw_error(ret);
}
// Q: How to convert callback types in the most simple way?
// A: (Bradley) I see three ways to do this: The issue is that we have a C++ callback function, and we want to pass it to a C function.
// The fastest way is wrong: You cannot just pass the C++ function pointer since you cannot mix function pointers to C and C++.
// The "right" way is to declare an "extern C" function and do all the conversions. Create a Dbt from a DBT, and then call the C function. For returned data we would have do something too. But it turns out that DBT and Dbt pointers are interchangable so that leads to
// The "fast" way. Declare an "extern C" function, and then use Dbt::get_const_Dbt() to do the conversion quickly.
extern "C" int associate_callback_c (DB*db_c, const DBT *k, const DBT *d, DBT *result) {
extern "C" int toku_associate_callback_c (DB*db_c, const DBT *k, const DBT *d, DBT *result) {
assert(db_c!=0);
Db *db_cxx=Db::get_Db(db_c);
assert(db_cxx);
......@@ -131,6 +158,6 @@ extern "C" int associate_callback_c (DB*db_c, const DBT *k, const DBT *d, DBT *r
int Db::associate(DbTxn *txnid, Db *secondary, int (*callback)(Db *secondary, const Dbt *key, const Dbt *data, Dbt *result), u_int32_t flags) {
// secondary->set_associate_callback(callback);
secondary->associate_callback_cxx = callback;
int ret = the_db->associate(the_db, txnid->get_DB_TXN(), secondary->get_DB(), associate_callback_c, flags);
int ret = the_db->associate(the_db, txnid->get_DB_TXN(), secondary->get_DB(), toku_associate_callback_c, flags);
return the_Env->maybe_throw_error(ret);
}
......@@ -74,6 +74,7 @@ class Dbt : private DBT {
extern "C" {
typedef int (*bt_compare_fcn_type)(DB *db, const DBT *dbt1, const DBT *dbt2);
typedef int (*dup_compare_fcn_type)(DB *db, const DBT *dbt1, const DBT *dbt2);
};
class Db {
......@@ -108,10 +109,15 @@ class Db {
int set_pagesize(u_int32_t);
int remove(const char *file, const char *database, u_int32_t flags);
int set_bt_compare(bt_compare_fcn_type bt_compare_fcn);
int set_bt_compare(int (*)(Db *, const Dbt *, const Dbt *));
int set_dup_compare(dup_compare_fcn_type dup_compare_fcn);
int set_dup_compare(int (*)(Db *, const Dbt *, const Dbt *));
int associate(DbTxn *, Db *, int (*)(Db *, const Dbt *, const Dbt *, Dbt *), u_int32_t);
/* the cxx callbacks must be public so they can be called by the c callback. But it's really private. */
int (*associate_callback_cxx)(Db *, const Dbt *, const Dbt *, Dbt*);
int (*bt_compare_callback_cxx)(Db *, const Dbt *, const Dbt *);
int (*dup_compare_callback_cxx)(Db *, const Dbt *, const Dbt *);
private:
DB *the_db;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment