Commit 3b200ebe authored by Zardosht Kasheff's avatar Zardosht Kasheff

refs Tokutek/mongo#886, change get_last_key to use a callback instead of...

refs Tokutek/mongo#886, change get_last_key to use a callback instead of copying data, so that we don't have
mongo code freeing data that fractal tree allocated.
parent d8b9fb11
......@@ -551,7 +551,7 @@ static void print_db_struct (void) {
"int (*get_fractal_tree_info64)(DB*,uint64_t*,uint64_t*,uint64_t*,uint64_t*)",
"int (*iterate_fractal_tree_block_map)(DB*,int(*)(uint64_t,int64_t,int64_t,int64_t,int64_t,void*),void*)",
"const char *(*get_dname)(DB *db)",
"int (*get_last_key)(DB *db, DBT*, uint32_t)",
"int (*get_last_key)(DB *db, YDB_CALLBACK_FUNCTION func, void* extra)",
NULL};
sort_and_dump_fields("db", true, extra);
}
......
......@@ -173,34 +173,25 @@ static void cleanup_env_and_db(DB_ENV * env, DB * db)
r = env->close(env, 0); { int chk_r = r; CKERR(chk_r); }
}
static void check_dbt_matches(DB *db, int expect_r, int key, DBT *kdbt) {
int r = db->get_last_key(db, kdbt, 0);
CKERR2(r, expect_r);
if (r==0) {
invariant(kdbt->size == sizeof(int));
int found_key = *(int*)kdbt->data;
invariant(key == (int)ntohl(found_key));
static int get_last_key_cb(const DBT *key, const DBT *value, void *extra) {
if (key->data) {
invariant(value == NULL);
int expected_key = *(int*)extra;
int found_key = *(int*)key->data;
invariant(expected_key == (int)ntohl(found_key));
}
return 0;
}
static void check_last_key_matches(DB *db, int expect_r, int key) {
DBT kdbt;
dbt_init(&kdbt, nullptr, 0);
check_dbt_matches(db, expect_r, key, &kdbt);
dbt_init_malloc(&kdbt);
check_dbt_matches(db, expect_r, key, &kdbt);
if (kdbt.data) {
toku_free(kdbt.data);
}
static void check_dbt_matches(DB *db, int expect_r, int key) {
int r = db->get_last_key(db, get_last_key_cb, &key);
CKERR2(r, expect_r);
}
dbt_init_realloc(&kdbt);
check_dbt_matches(db, expect_r, key, &kdbt);
if (kdbt.data) {
toku_free(kdbt.data);
}
static void check_last_key_matches(DB *db, int expect_r, int key) {
check_dbt_matches(db, expect_r, key);
check_dbt_matches(db, expect_r, key);
check_dbt_matches(db, expect_r, key);
}
static void do_test(size_t ct_size, int num_keys)
......
......@@ -945,30 +945,32 @@ locked_db_optimize(DB *db) {
struct last_key_extra {
DBT * const key_dbt;
DB * db;
YDB_CALLBACK_FUNCTION func;
void* extra;
};
static int
db_get_last_key_callback(ITEMLEN keylen, bytevec key, ITEMLEN vallen UU(), bytevec val UU(), void *extra, bool lock_only) {
if (!lock_only) {
DBT keydbt;
toku_fill_dbt(&keydbt, key, keylen);
struct last_key_extra * CAST_FROM_VOIDP(info, extra);
toku_dbt_set(keylen, key, info->key_dbt, &info->db->i->skey);
info->func(&keydbt, NULL, info->extra);
}
return 0;
}
static int
toku_db_get_last_key(DB * db, DB_TXN *txn, DBT * key, uint32_t flags UU()) {
toku_db_get_last_key(DB * db, DB_TXN *txn, YDB_CALLBACK_FUNCTION func, void* extra) {
int r;
LE_CURSOR cursor = nullptr;
struct last_key_extra extra = { .key_dbt = key, .db = db };
struct last_key_extra last_extra = { .func = func, .extra = extra };
r = toku_le_cursor_create(&cursor, db->i->ft_handle, db_txn_struct_i(txn)->tokutxn);
if (r != 0) { goto cleanup; }
// Goes in reverse order. First key returned is last in dictionary.
r = toku_le_cursor_next(cursor, db_get_last_key_callback, &extra);
r = toku_le_cursor_next(cursor, db_get_last_key_callback, &last_extra);
if (r != 0) { goto cleanup; }
cleanup:
......@@ -979,14 +981,14 @@ cleanup:
}
static int
autotxn_db_get_last_key(DB* db, DBT* key, uint32_t flags) {
autotxn_db_get_last_key(DB* db, YDB_CALLBACK_FUNCTION func, void* extra) {
bool changed; int r;
DB_TXN *txn = nullptr;
// Cursors inside require transactions, but this is _not_ a transactional function.
// Create transaction in a wrapper and then later close it.
r = toku_db_construct_autotxn(db, &txn, &changed, false);
if (r!=0) return r;
r = toku_db_get_last_key(db, txn, key, flags);
r = toku_db_get_last_key(db, txn, func, extra);
return toku_db_destruct_autotxn(txn, r, changed);
}
......
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