Commit 92be5bc8 authored by John Esmet's avatar John Esmet Committed by Yoni Fogel

[t:5133] properly fix the memory leak introduced earlier today.

the big idea is that we need to allocate space for a leaf entry and keep it around if we want to create a ULE for it. so now the provisional info holds a pointer to both the le and the ule so the caller can free it later.


git-svn-id: file:///svn/toku/tokudb@45071 c7de825b-a66e-492c-adef-691d508d4ae1
parent 6df381af
......@@ -516,7 +516,8 @@ ule_cleanup(ULE ule) {
}
}
// Purpose of le_unpack() is to populate our private workspace with the contents of the given le.
// populate an unpacked leafentry using pointers into the given leafentry.
// thus, the memory referenced by 'le' must live as long as the ULE.
void
le_unpack(ULE ule, LEAFENTRY le) {
//Read the keylen
......
......@@ -28,7 +28,12 @@ struct indexer_commit_keys {
// a cursor callback that provides exclusive access to the source DB
// with respect to txn commit and abort
struct ule_prov_info {
// these are pointers to the allocated leafentry and ule needed to calculate
// provisional info. we only borrow them - whoever created the provisional info
// is responsible for cleaning up the leafentry and ule when done.
LEAFENTRY le;
ULEHANDLE ule;
// provisional txn info for the ule
uint32_t num_provisional;
uint32_t num_committed;
TXNID *prov_ids;
......
......@@ -279,12 +279,12 @@ toku_indexer_is_key_right_of_le_cursor(DB_INDEXER *indexer, const DBT *key) {
return toku_le_cursor_is_key_greater(indexer->i->lec, key);
}
// initialize provisional info by allocating enough space to
// hold provisional ids, states, and txns for each of the
// provisional entries in the ule. the ule remains owned by
// the caller, not the prov info.
// initialize provisional info by allocating enough space to hold provisional
// ids, states, and txns for each of the provisional entries in the ule. the
// ule and le remain owned by the caller, not this struct.
static void
ule_prov_info_init(struct ule_prov_info *prov_info, ULEHANDLE ule) {
ule_prov_info_init(struct ule_prov_info *prov_info, LEAFENTRY le, ULEHANDLE ule) {
prov_info->le = le;
prov_info->ule = ule;
prov_info->num_provisional = ule_get_num_provisional(ule);
prov_info->num_committed = ule_get_num_committed(ule);
......@@ -370,15 +370,16 @@ le_cursor_callback(ITEMLEN UU(keylen), bytevec UU(key), ITEMLEN UU(vallen), byte
} else {
struct le_cursor_extra *cursor_extra = extra;
struct ule_prov_info *prov_info = cursor_extra->prov_info;
// the val here is a leafentry. ule_create copies the contents of a
// leafentry into its own buffers, so we don't need to malloc space
// for this value to exist outside the callback.
//
// blast away the const from bytevec by casting to LEAFENTRY
LEAFENTRY le = (LEAFENTRY) val;
// the val here is a leafentry. ule_create does not copy the entire
// contents of the leafentry it is given into its own buffers, so we
// must allocate space for a leafentry and keep it around with the ule.
LEAFENTRY le = toku_xmemdup(val, vallen);
ULEHANDLE ule = toku_ule_create(le);
invariant(ule);
ule_prov_info_init(prov_info, ule);
// when we initialize prov info, we also pass in the leafentry and ule
// pointers so the caller can access them later. it's their job to free
// them when they're not needed.
ule_prov_info_init(prov_info, le, ule);
indexer_fill_prov_info(cursor_extra->indexer, prov_info);
}
return 0;
......@@ -425,7 +426,9 @@ build_index(DB_INDEXER *indexer) {
}
}
else {
invariant(prov_info.le);
invariant(prov_info.ule);
LEAFENTRY le = prov_info.le;
ULEHANDLE ule = prov_info.ule;
for (int which_db = 0; (which_db < indexer->i->N) && (result == 0); which_db++) {
DB *db = indexer->i->dest_dbs[which_db];
......@@ -437,8 +440,11 @@ build_index(DB_INDEXER *indexer) {
indexer->i->error_callback(db, which_db, result, &key, NULL, indexer->i->error_extra);
toku_destroy_dbt(&key);
}
toku_ule_free(prov_info.ule);
}
// the leafentry and ule are not owned by the prov_info,
// and are still our responsibility to free
toku_free(prov_info.le);
toku_ule_free(prov_info.ule);
}
toku_indexer_unlock(indexer);
......@@ -579,7 +585,8 @@ static int
test_indexer_undo_do(DB_INDEXER *indexer, DB *hotdb, ULEHANDLE ule) {
struct ule_prov_info prov_info;
memset(&prov_info, 0, sizeof(prov_info));
ule_prov_info_init(&prov_info, ule);
// pass null for the leafentry - we don't need it, neither does the info
ule_prov_info_init(&prov_info, NULL, ule);
indexer_fill_prov_info(indexer, &prov_info);
int r = indexer_undo_do(indexer, hotdb, ule, &prov_info);
ule_prov_info_destroy(&prov_info);
......
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