Commit 3b3d4c6d authored by Leif Walsh's avatar Leif Walsh Committed by Yoni Fogel

refs #5206 address review comments: only use refs when ref-to-const, otherwise use ptr


git-svn-id: file:///svn/toku/tokudb@45941 c7de825b-a66e-492c-adef-691d508d4ae1
parent 3d6e8bef
...@@ -2643,10 +2643,11 @@ set_filenum_in_array(OMTVALUE hv, u_int32_t index, void*arrayv) { ...@@ -2643,10 +2643,11 @@ set_filenum_in_array(OMTVALUE hv, u_int32_t index, void*arrayv) {
} }
int int
log_open_txn (const TOKUTXN &txn, const uint32_t UU(index), CACHETABLE &ct); log_open_txn (const TOKUTXN &txn, const uint32_t UU(index), CACHETABLE *const ctp);
int int
log_open_txn (const TOKUTXN &txn, const uint32_t UU(index), CACHETABLE &ct) { log_open_txn (const TOKUTXN &txn, const uint32_t UU(index), CACHETABLE *const ctp) {
int r; int r;
CACHETABLE ct = *ctp;
TOKULOGGER logger = txn->logger; TOKULOGGER logger = txn->logger;
FILENUMS open_filenums; FILENUMS open_filenums;
uint32_t num_filenums = toku_omt_size(txn->open_fts); uint32_t num_filenums = toku_omt_size(txn->open_fts);
...@@ -2767,7 +2768,7 @@ toku_cachetable_begin_checkpoint (CACHETABLE ct, TOKULOGGER logger) { ...@@ -2767,7 +2768,7 @@ toku_cachetable_begin_checkpoint (CACHETABLE ct, TOKULOGGER logger) {
{ {
int r = toku_txn_manager_iter_over_live_txns<CACHETABLE, log_open_txn>( int r = toku_txn_manager_iter_over_live_txns<CACHETABLE, log_open_txn>(
logger->txn_manager, logger->txn_manager,
ct &ct
); );
assert(r==0); assert(r==0);
} }
......
...@@ -3775,16 +3775,16 @@ struct copy_to_stale_extra { ...@@ -3775,16 +3775,16 @@ struct copy_to_stale_extra {
}; };
// template-only function, but must be extern // template-only function, but must be extern
int copy_to_stale(const long &offset, const uint32_t UU(idx), struct copy_to_stale_extra &extra); int copy_to_stale(const long &offset, const uint32_t UU(idx), struct copy_to_stale_extra *const extra)
int __attribute__((nonnull(3)));
copy_to_stale(const long &offset, const uint32_t UU(idx), struct copy_to_stale_extra &extra) int copy_to_stale(const long &offset, const uint32_t UU(idx), struct copy_to_stale_extra *const extra)
{ {
struct fifo_entry *entry = (struct fifo_entry *) toku_fifo_get_entry(extra.bnc->buffer, offset); struct fifo_entry *entry = (struct fifo_entry *) toku_fifo_get_entry(extra->bnc->buffer, offset);
entry->is_fresh = false; entry->is_fresh = false;
DBT keydbt; DBT keydbt;
DBT *key = fill_dbt_for_fifo_entry(&keydbt, entry); DBT *key = fill_dbt_for_fifo_entry(&keydbt, entry);
struct toku_fifo_entry_key_msn_heaviside_extra heaviside_extra = { .desc = &extra.ft_handle->ft->cmp_descriptor, .cmp = extra.ft_handle->ft->compare_fun, .fifo = extra.bnc->buffer, .key = key, .msn = entry->msn }; struct toku_fifo_entry_key_msn_heaviside_extra heaviside_extra = { .desc = &extra->ft_handle->ft->cmp_descriptor, .cmp = extra->ft_handle->ft->compare_fun, .fifo = extra->bnc->buffer, .key = key, .msn = entry->msn };
int r = extra.bnc->stale_message_tree.insert<struct toku_fifo_entry_key_msn_heaviside_extra, toku_fifo_entry_key_msn_heaviside>(offset, heaviside_extra, nullptr); int r = extra->bnc->stale_message_tree.insert<struct toku_fifo_entry_key_msn_heaviside_extra, toku_fifo_entry_key_msn_heaviside>(offset, heaviside_extra, nullptr);
assert_zero(r); assert_zero(r);
return r; return r;
} }
...@@ -3795,12 +3795,12 @@ struct store_fifo_offset_extra { ...@@ -3795,12 +3795,12 @@ struct store_fifo_offset_extra {
}; };
// template-only function, but must be extern // template-only function, but must be extern
int store_fifo_offset(const long &offset, const uint32_t UU(idx), struct store_fifo_offset_extra &extra); int store_fifo_offset(const long &offset, const uint32_t UU(idx), struct store_fifo_offset_extra *const extra)
int __attribute__((nonnull(3)));
store_fifo_offset(const long &offset, const uint32_t UU(idx), struct store_fifo_offset_extra &extra) int store_fifo_offset(const long &offset, const uint32_t UU(idx), struct store_fifo_offset_extra *const extra)
{ {
extra.offsets[extra.i] = offset; extra->offsets[extra->i] = offset;
extra.i++; extra->i++;
return 0; return 0;
} }
...@@ -3873,13 +3873,13 @@ struct iterate_do_bn_apply_cmd_extra { ...@@ -3873,13 +3873,13 @@ struct iterate_do_bn_apply_cmd_extra {
}; };
// template-only function, but must be extern // template-only function, but must be extern
int iterate_do_bn_apply_cmd(const long &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_cmd_extra &e); int iterate_do_bn_apply_cmd(const long &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_cmd_extra *const e)
int __attribute__((nonnull(3)));
iterate_do_bn_apply_cmd(const long &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_cmd_extra &e) int iterate_do_bn_apply_cmd(const long &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_cmd_extra *const e)
{ {
NONLEAF_CHILDINFO bnc = BNC(e.ancestor, e.childnum); NONLEAF_CHILDINFO bnc = BNC(e->ancestor, e->childnum);
const struct fifo_entry *entry = toku_fifo_get_entry(bnc->buffer, offset); const struct fifo_entry *entry = toku_fifo_get_entry(bnc->buffer, offset);
do_bn_apply_cmd(e.t, e.bn, e.ancestor, e.childnum, entry, e.stats_to_update); do_bn_apply_cmd(e->t, e->bn, e->ancestor, e->childnum, entry, e->stats_to_update);
return 0; return 0;
} }
...@@ -4032,15 +4032,15 @@ bnc_apply_messages_to_basement_node( ...@@ -4032,15 +4032,15 @@ bnc_apply_messages_to_basement_node(
struct store_fifo_offset_extra sfo_extra = { .offsets = offsets, .i = 0 }; struct store_fifo_offset_extra sfo_extra = { .offsets = offsets, .i = 0 };
// Populate offsets array with offsets to stale messages // Populate offsets array with offsets to stale messages
r = bnc->stale_message_tree.iterate_on_range<struct store_fifo_offset_extra, store_fifo_offset>(stale_lbi, stale_ube, sfo_extra); r = bnc->stale_message_tree.iterate_on_range<struct store_fifo_offset_extra, store_fifo_offset>(stale_lbi, stale_ube, &sfo_extra);
assert_zero(r); assert_zero(r);
// Then store fresh offsets // Then store fresh offsets
r = bnc->fresh_message_tree.iterate_on_range<struct store_fifo_offset_extra, store_fifo_offset>(fresh_lbi, fresh_ube, sfo_extra); r = bnc->fresh_message_tree.iterate_on_range<struct store_fifo_offset_extra, store_fifo_offset>(fresh_lbi, fresh_ube, &sfo_extra);
assert_zero(r); assert_zero(r);
// Store offsets of all broadcast messages. // Store offsets of all broadcast messages.
r = bnc->broadcast_list.iterate<struct store_fifo_offset_extra, store_fifo_offset>(sfo_extra); r = bnc->broadcast_list.iterate<struct store_fifo_offset_extra, store_fifo_offset>(&sfo_extra);
assert_zero(r); assert_zero(r);
invariant(sfo_extra.i == buffer_size); invariant(sfo_extra.i == buffer_size);
...@@ -4060,7 +4060,7 @@ bnc_apply_messages_to_basement_node( ...@@ -4060,7 +4060,7 @@ bnc_apply_messages_to_basement_node(
// No stale messages to apply, we just apply fresh messages. // No stale messages to apply, we just apply fresh messages.
struct iterate_do_bn_apply_cmd_extra iter_extra = { .t = t, .bn = bn, .ancestor = ancestor, .childnum = childnum, .stats_to_update = &stats_delta}; struct iterate_do_bn_apply_cmd_extra iter_extra = { .t = t, .bn = bn, .ancestor = ancestor, .childnum = childnum, .stats_to_update = &stats_delta};
if (fresh_ube - fresh_lbi > 0) *msgs_applied = TRUE; if (fresh_ube - fresh_lbi > 0) *msgs_applied = TRUE;
r = bnc->fresh_message_tree.iterate_on_range<struct iterate_do_bn_apply_cmd_extra, iterate_do_bn_apply_cmd>(fresh_lbi, fresh_ube, iter_extra); r = bnc->fresh_message_tree.iterate_on_range<struct iterate_do_bn_apply_cmd_extra, iterate_do_bn_apply_cmd>(fresh_lbi, fresh_ube, &iter_extra);
assert_zero(r); assert_zero(r);
} else if (fresh_lbi == fresh_ube) { } else if (fresh_lbi == fresh_ube) {
// No fresh messages to apply, we just apply stale messages. // No fresh messages to apply, we just apply stale messages.
...@@ -4068,7 +4068,7 @@ bnc_apply_messages_to_basement_node( ...@@ -4068,7 +4068,7 @@ bnc_apply_messages_to_basement_node(
if (stale_ube - stale_lbi > 0) *msgs_applied = TRUE; if (stale_ube - stale_lbi > 0) *msgs_applied = TRUE;
struct iterate_do_bn_apply_cmd_extra iter_extra = { .t = t, .bn = bn, .ancestor = ancestor, .childnum = childnum , .stats_to_update = &stats_delta}; struct iterate_do_bn_apply_cmd_extra iter_extra = { .t = t, .bn = bn, .ancestor = ancestor, .childnum = childnum , .stats_to_update = &stats_delta};
r = bnc->stale_message_tree.iterate_on_range<struct iterate_do_bn_apply_cmd_extra, iterate_do_bn_apply_cmd>(stale_lbi, stale_ube, iter_extra); r = bnc->stale_message_tree.iterate_on_range<struct iterate_do_bn_apply_cmd_extra, iterate_do_bn_apply_cmd>(stale_lbi, stale_ube, &iter_extra);
assert_zero(r); assert_zero(r);
} else { } else {
// We have stale and fresh messages but no broadcasts. We can // We have stale and fresh messages but no broadcasts. We can
...@@ -4157,7 +4157,7 @@ bnc_apply_messages_to_basement_node( ...@@ -4157,7 +4157,7 @@ bnc_apply_messages_to_basement_node(
// procedures because we're still looking at the fresh tree. Instead // procedures because we're still looking at the fresh tree. Instead
// we have to move messages after we're done looking at it. // we have to move messages after we're done looking at it.
struct copy_to_stale_extra cts_extra = { .ft_handle = t, .bnc = bnc }; struct copy_to_stale_extra cts_extra = { .ft_handle = t, .bnc = bnc };
r = bnc->fresh_message_tree.iterate_on_range<struct copy_to_stale_extra, copy_to_stale>(fresh_lbi, fresh_ube, cts_extra); r = bnc->fresh_message_tree.iterate_on_range<struct copy_to_stale_extra, copy_to_stale>(fresh_lbi, fresh_ube, &cts_extra);
assert_zero(r); assert_zero(r);
for (uint32_t ube = fresh_ube; fresh_lbi < ube; --ube) { for (uint32_t ube = fresh_ube; fresh_lbi < ube; --ube) {
// When we delete the message at the fresh_lbi index, everything // When we delete the message at the fresh_lbi index, everything
......
...@@ -106,13 +106,13 @@ struct count_msgs_extra { ...@@ -106,13 +106,13 @@ struct count_msgs_extra {
}; };
// template-only function, but must be extern // template-only function, but must be extern
int count_msgs(const long &offset, const uint32_t UU(idx), struct count_msgs_extra &e); int count_msgs(const long &offset, const uint32_t UU(idx), struct count_msgs_extra *const e)
int __attribute__((nonnull(3)));
count_msgs(const long &offset, const uint32_t UU(idx), struct count_msgs_extra &e) int count_msgs(const long &offset, const uint32_t UU(idx), struct count_msgs_extra *const e)
{ {
const struct fifo_entry *entry = toku_fifo_get_entry(e.fifo, offset); const struct fifo_entry *entry = toku_fifo_get_entry(e->fifo, offset);
if (entry->msn.msn == e.msn.msn) { if (entry->msn.msn == e->msn.msn) {
e.count++; e->count++;
} }
return 0; return 0;
} }
...@@ -128,27 +128,27 @@ struct verify_message_tree_extra { ...@@ -128,27 +128,27 @@ struct verify_message_tree_extra {
}; };
// template-only function, but must be extern // template-only function, but must be extern
int verify_message_tree(const long &offset, const uint32_t UU(idx), struct verify_message_tree_extra &e); int verify_message_tree(const long &offset, const uint32_t UU(idx), struct verify_message_tree_extra *const e)
int __attribute__((nonnull(3)));
verify_message_tree(const long &offset, const uint32_t UU(idx), struct verify_message_tree_extra &e) int verify_message_tree(const long &offset, const uint32_t UU(idx), struct verify_message_tree_extra *const e)
{ {
int verbose = e.verbose; int verbose = e->verbose;
BLOCKNUM blocknum = e.blocknum; BLOCKNUM blocknum = e->blocknum;
int keep_going_on_failure = e.keep_going_on_failure; int keep_going_on_failure = e->keep_going_on_failure;
int result = 0; int result = 0;
const struct fifo_entry *entry = toku_fifo_get_entry(e.fifo, offset); const struct fifo_entry *entry = toku_fifo_get_entry(e->fifo, offset);
if (e.broadcast) { if (e->broadcast) {
VERIFY_ASSERTION(ft_msg_type_applies_all((enum ft_msg_type) entry->type) || ft_msg_type_does_nothing((enum ft_msg_type) entry->type), VERIFY_ASSERTION(ft_msg_type_applies_all((enum ft_msg_type) entry->type) || ft_msg_type_does_nothing((enum ft_msg_type) entry->type),
e.i, "message found in broadcast list that is not a broadcast"); e->i, "message found in broadcast list that is not a broadcast");
} else { } else {
VERIFY_ASSERTION(ft_msg_type_applies_once((enum ft_msg_type) entry->type), VERIFY_ASSERTION(ft_msg_type_applies_once((enum ft_msg_type) entry->type),
e.i, "message found in fresh or stale message tree that does not apply once"); e->i, "message found in fresh or stale message tree that does not apply once");
if (e.is_fresh) { if (e->is_fresh) {
VERIFY_ASSERTION(entry->is_fresh, VERIFY_ASSERTION(entry->is_fresh,
e.i, "message found in fresh message tree that is not fresh"); e->i, "message found in fresh message tree that is not fresh");
} else { } else {
VERIFY_ASSERTION(!entry->is_fresh, VERIFY_ASSERTION(!entry->is_fresh,
e.i, "message found in stale message tree that is fresh"); e->i, "message found in stale message tree that is fresh");
} }
} }
done: done:
...@@ -296,19 +296,19 @@ toku_verify_ftnode (FT_HANDLE brt, ...@@ -296,19 +296,19 @@ toku_verify_ftnode (FT_HANDLE brt,
} else { } else {
VERIFY_ASSERTION(ft_msg_type_applies_all(type) || ft_msg_type_does_nothing(type), i, "a message was found that does not apply either to all or to only one key"); VERIFY_ASSERTION(ft_msg_type_applies_all(type) || ft_msg_type_does_nothing(type), i, "a message was found that does not apply either to all or to only one key");
struct count_msgs_extra extra = { .count = 0, .msn = msn, .fifo = bnc->buffer }; struct count_msgs_extra extra = { .count = 0, .msn = msn, .fifo = bnc->buffer };
bnc->broadcast_list.iterate<struct count_msgs_extra, count_msgs>(extra); bnc->broadcast_list.iterate<struct count_msgs_extra, count_msgs>(&extra);
VERIFY_ASSERTION(extra.count == 1, i, "a broadcast message was not found in the broadcast list"); VERIFY_ASSERTION(extra.count == 1, i, "a broadcast message was not found in the broadcast list");
} }
last_msn = msn; last_msn = msn;
})); }));
struct verify_message_tree_extra extra = { .fifo = bnc->buffer, .broadcast = false, .is_fresh = true, .i = i, .verbose = verbose, .blocknum = node->thisnodename, .keep_going_on_failure = keep_going_on_failure }; struct verify_message_tree_extra extra = { .fifo = bnc->buffer, .broadcast = false, .is_fresh = true, .i = i, .verbose = verbose, .blocknum = node->thisnodename, .keep_going_on_failure = keep_going_on_failure };
int r = bnc->fresh_message_tree.iterate<struct verify_message_tree_extra, verify_message_tree>(extra); int r = bnc->fresh_message_tree.iterate<struct verify_message_tree_extra, verify_message_tree>(&extra);
if (r != 0) { result = r; goto done; } if (r != 0) { result = r; goto done; }
extra.is_fresh = false; extra.is_fresh = false;
r = bnc->stale_message_tree.iterate<struct verify_message_tree_extra, verify_message_tree>(extra); r = bnc->stale_message_tree.iterate<struct verify_message_tree_extra, verify_message_tree>(&extra);
if (r != 0) { result = r; goto done; } if (r != 0) { result = r; goto done; }
extra.broadcast = true; extra.broadcast = true;
r = bnc->broadcast_list.iterate<struct verify_message_tree_extra, verify_message_tree>(extra); r = bnc->broadcast_list.iterate<struct verify_message_tree_extra, verify_message_tree>(&extra);
if (r != 0) { result = r; goto done; } if (r != 0) { result = r; goto done; }
} }
else { else {
......
...@@ -971,13 +971,13 @@ deserialize_child_buffer(NONLEAF_CHILDINFO bnc, struct rbuf *rbuf, ...@@ -971,13 +971,13 @@ deserialize_child_buffer(NONLEAF_CHILDINFO bnc, struct rbuf *rbuf,
r = toku::sort<long, const struct toku_fifo_entry_key_msn_cmp_extra, toku_fifo_entry_key_msn_cmp>::mergesort_r(fresh_offsets, nfresh, extra); r = toku::sort<long, const struct toku_fifo_entry_key_msn_cmp_extra, toku_fifo_entry_key_msn_cmp>::mergesort_r(fresh_offsets, nfresh, extra);
assert_zero(r); assert_zero(r);
bnc->fresh_message_tree.destroy(); bnc->fresh_message_tree.destroy();
bnc->fresh_message_tree.create_steal_sorted_array(fresh_offsets, nfresh, n_in_this_buffer); bnc->fresh_message_tree.create_steal_sorted_array(&fresh_offsets, nfresh, n_in_this_buffer);
r = toku::sort<long, const struct toku_fifo_entry_key_msn_cmp_extra, toku_fifo_entry_key_msn_cmp>::mergesort_r(stale_offsets, nstale, extra); r = toku::sort<long, const struct toku_fifo_entry_key_msn_cmp_extra, toku_fifo_entry_key_msn_cmp>::mergesort_r(stale_offsets, nstale, extra);
assert_zero(r); assert_zero(r);
bnc->stale_message_tree.destroy(); bnc->stale_message_tree.destroy();
bnc->stale_message_tree.create_steal_sorted_array(stale_offsets, nstale, n_in_this_buffer); bnc->stale_message_tree.create_steal_sorted_array(&stale_offsets, nstale, n_in_this_buffer);
bnc->broadcast_list.destroy(); bnc->broadcast_list.destroy();
bnc->broadcast_list.create_steal_sorted_array(broadcast_offsets, nbroadcast_offsets, n_in_this_buffer); bnc->broadcast_list.create_steal_sorted_array(&broadcast_offsets, nbroadcast_offsets, n_in_this_buffer);
} }
} }
...@@ -1862,9 +1862,9 @@ deserialize_and_upgrade_internal_node(FTNODE node, ...@@ -1862,9 +1862,9 @@ deserialize_and_upgrade_internal_node(FTNODE node,
r = key_msn_sort::mergesort_r(fresh_offsets, nfresh, extra); r = key_msn_sort::mergesort_r(fresh_offsets, nfresh, extra);
assert_zero(r); assert_zero(r);
bnc->fresh_message_tree.destroy(); bnc->fresh_message_tree.destroy();
bnc->fresh_message_tree.create_steal_sorted_array(fresh_offsets, nfresh, n_in_this_buffer); bnc->fresh_message_tree.create_steal_sorted_array(&fresh_offsets, nfresh, n_in_this_buffer);
bnc->broadcast_list.destroy(); bnc->broadcast_list.destroy();
bnc->broadcast_list.create_steal_sorted_array(broadcast_offsets, nbroadcast_offsets, n_in_this_buffer); bnc->broadcast_list.create_steal_sorted_array(&broadcast_offsets, nbroadcast_offsets, n_in_this_buffer);
} }
} }
......
...@@ -55,22 +55,26 @@ namespace toku { ...@@ -55,22 +55,26 @@ namespace toku {
/** /**
* *
*/ */
void create_steal_sorted_array(omtdata_t *&values, const uint32_t numvalues, const uint32_t capacity_) __attribute__((nonnull(2)))
void create_steal_sorted_array(omtdata_t **const values, const uint32_t numvalues, const uint32_t capacity_)
{ {
invariant_notnull(values);
this->create_internal_no_array(capacity_); this->create_internal_no_array(capacity_);
this->d.a.num_values = numvalues; this->d.a.num_values = numvalues;
this->d.a.values = values; this->d.a.values = *values;
values = nullptr; *values = nullptr;
} }
/** /**
* *
*/ */
void split_at(omt &newomt, const uint32_t idx) { __attribute__((nonnull(2)))
void split_at(omt *const newomt, const uint32_t idx) {
invariant_notnull(newomt);
if (idx > this->size()) { return EINVAL; } if (idx > this->size()) { return EINVAL; }
this->convert_to_array(); this->convert_to_array();
const uint32_t newsize = this->size() - idx; const uint32_t newsize = this->size() - idx;
newomt.create_from_sorted_array(&this->d.a.values[this->d.a.start_idx + idx], newsize); newomt->create_from_sorted_array(&this->d.a.values[this->d.a.start_idx + idx], newsize);
this->d.a.num_values = idx; this->d.a.num_values = idx;
this->maybe_resize_array(); this->maybe_resize_array();
} }
...@@ -78,37 +82,40 @@ namespace toku { ...@@ -78,37 +82,40 @@ namespace toku {
/** /**
* *
*/ */
void merge(omt &leftomt, omt &rightomt) { __attribute__((nonnull(2,3)))
const uint32_t leftsize = leftomt.size(); void merge(omt *const leftomt, omt *const rightomt) {
const uint32_t rightsize = rightomt.size(); invariant_notnull(leftomt);
invariant_notnull(rightomt);
const uint32_t leftsize = leftomt->size();
const uint32_t rightsize = rightomt->size();
const uint32_t newsize = leftsize + rightsize; const uint32_t newsize = leftsize + rightsize;
if (leftomt.is_array) { if (leftomt->is_array) {
if (leftomt.capacity - (leftomt.d.a.start_idx + leftomt.d.a.num_values) >= rightsize) { if (leftomt->capacity - (leftomt->d.a.start_idx + leftomt->d.a.num_values) >= rightsize) {
this->create_steal_sorted_array(leftomt.d.a.values, leftomt.d.a.num_values, leftomt.capacity); this->create_steal_sorted_array(leftomt->d.a.values, leftomt->d.a.num_values, leftomt->capacity);
this->d.a.start_idx = leftomt.d.a.start_idx; this->d.a.start_idx = leftomt->d.a.start_idx;
} else { } else {
this->create_internal(newsize); this->create_internal(newsize);
memcpy(&this->d.a.values[0], memcpy(&this->d.a.values[0],
&leftomt.d.a.values[leftomt.d.a.start_idx], &leftomt->d.a.values[leftomt->d.a.start_idx],
leftomt.d.a.num_values * (sizeof this->d.a.values[0])); leftomt->d.a.num_values * (sizeof this->d.a.values[0]));
} }
} else { } else {
this->create_internal(newsize); this->create_internal(newsize);
leftomt.fill_array_with_subtree_values(&this->d.a.values[0], leftomt.d.t.root); leftomt->fill_array_with_subtree_values(&this->d.a.values[0], leftomt->d.t.root);
} }
leftomt.destroy(); leftomt->destroy();
this->d.a.num_values = leftsize; this->d.a.num_values = leftsize;
if (rightomt.is_array) { if (rightomt->is_array) {
memcpy(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values], memcpy(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values],
&rightomt.d.a.values[rightomt.d.a.start_idx], &rightomt->d.a.values[rightomt->d.a.start_idx],
rightomt.d.a.num_values * (sizeof this->d.a.values[0])); rightomt->d.a.num_values * (sizeof this->d.a.values[0]));
} else { } else {
rightomt.fill_array_with_subtree_values(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values], rightomt->fill_array_with_subtree_values(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values],
rightomt.d.t.root); rightomt->d.t.root);
} }
rightomt.destroy(); rightomt->destroy();
this->d.a.num_values += rightsize; this->d.a.num_values += rightsize;
invariant(this->size() == newsize); invariant(this->size() == newsize);
} }
...@@ -133,7 +140,7 @@ namespace toku { ...@@ -133,7 +140,7 @@ namespace toku {
void deep_clone(const omt &src) void deep_clone(const omt &src)
{ {
this->create_internal(src.size()); this->create_internal(src.size());
int r = src.iterate<omt, deep_clone_iter>(*this); int r = src.iterate<omt, deep_clone_iter>(this);
lazy_assert_zero(r); lazy_assert_zero(r);
this->d.a.num_values = src.size(); this->d.a.num_values = src.size();
} }
...@@ -229,9 +236,9 @@ namespace toku { ...@@ -229,9 +236,9 @@ namespace toku {
} }
else { else {
node_idx *rebalance_idx = nullptr; node_idx *rebalance_idx = nullptr;
this->insert_internal(&this->d.t.root, value, idx, rebalance_idx); this->insert_internal(&this->d.t.root, value, idx, &rebalance_idx);
if (rebalance_idx != nullptr) { if (rebalance_idx != nullptr) {
this->rebalance(*rebalance_idx); this->rebalance(rebalance_idx);
} }
} }
return 0; return 0;
...@@ -270,10 +277,9 @@ namespace toku { ...@@ -270,10 +277,9 @@ namespace toku {
this->d.a.num_values--; this->d.a.num_values--;
} else { } else {
node_idx *rebalance_idx = nullptr; node_idx *rebalance_idx = nullptr;
omt_node unused; this->delete_internal(&this->d.t.root, idx, nullptr, &rebalance_idx);
this->delete_internal(&this->d.t.root, idx, unused, rebalance_idx);
if (rebalance_idx != nullptr) { if (rebalance_idx != nullptr) {
this->rebalance(*rebalance_idx); this->rebalance(rebalance_idx);
} }
} }
return 0; return 0;
...@@ -283,8 +289,8 @@ namespace toku { ...@@ -283,8 +289,8 @@ namespace toku {
* *
*/ */
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t &)> int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)>
int iterate(iterate_extra_t &iterate_extra) const { int iterate(iterate_extra_t *const iterate_extra) const {
return this->iterate_on_range<iterate_extra_t, f>(0, this->size(), iterate_extra); return this->iterate_on_range<iterate_extra_t, f>(0, this->size(), iterate_extra);
} }
...@@ -292,8 +298,8 @@ namespace toku { ...@@ -292,8 +298,8 @@ namespace toku {
* *
*/ */
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t &)> int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)>
int iterate_on_range(const uint32_t left, const uint32_t right, iterate_extra_t &iterate_extra) const { int iterate_on_range(const uint32_t left, const uint32_t right, iterate_extra_t *const iterate_extra) const {
if (right > this->size()) { return EINVAL; } if (right > this->size()) { return EINVAL; }
if (this->is_array) { if (this->is_array) {
return this->iterate_internal_array<iterate_extra_t, f>(left, right, iterate_extra); return this->iterate_internal_array<iterate_extra_t, f>(left, right, iterate_extra);
...@@ -305,8 +311,8 @@ namespace toku { ...@@ -305,8 +311,8 @@ namespace toku {
* *
*/ */
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(omtdata_t *, const uint32_t, iterate_extra_t &)> int (*f)(omtdata_t *, const uint32_t, iterate_extra_t *const)>
void iterate_ptr(iterate_extra_t &iterate_extra) { void iterate_ptr(iterate_extra_t *const iterate_extra) {
if (this->is_array) { if (this->is_array) {
this->iterate_ptr_internal_array<iterate_extra_t, f>(0, this->size(), iterate_extra); this->iterate_ptr_internal_array<iterate_extra_t, f>(0, this->size(), iterate_extra);
} else { } else {
...@@ -315,8 +321,7 @@ namespace toku { ...@@ -315,8 +321,7 @@ namespace toku {
} }
void free_items(void) { void free_items(void) {
int unused = 0; this->iterate_ptr<void, free_items_iter>(nullptr);
this->iterate_ptr<int, free_items_iter>(unused);
} }
/** /**
...@@ -338,16 +343,16 @@ namespace toku { ...@@ -338,16 +343,16 @@ namespace toku {
*/ */
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
int find_zero(const omtcmp_t &extra, omtdataout_t *value, uint32_t *idx) const int find_zero(const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const
{ {
uint32_t tmp_index; uint32_t tmp_index;
if (idx==nullptr) idx=&tmp_index; uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index;
int r; int r;
if (this->is_array) { if (this->is_array) {
r = this->find_internal_zero_array<omtcmp_t, h>(extra, value, *idx); r = this->find_internal_zero_array<omtcmp_t, h>(extra, value, child_idxp);
} }
else { else {
r = this->find_internal_zero<omtcmp_t, h>(this->d.t.root, extra, value, *idx); r = this->find_internal_zero<omtcmp_t, h>(this->d.t.root, extra, value, child_idxp);
} }
return r; return r;
} }
...@@ -357,23 +362,23 @@ namespace toku { ...@@ -357,23 +362,23 @@ namespace toku {
*/ */
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
int find(const omtcmp_t &extra, int direction, omtdataout_t *value, uint32_t *idx) const int find(const omtcmp_t &extra, int direction, omtdataout_t *const value, uint32_t *const idxp) const
{ {
uint32_t tmp_index; uint32_t tmp_index;
if (idx == nullptr) { idx = &tmp_index; } uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index;
if (direction == 0) { if (direction == 0) {
abort(); abort();
} else if (direction < 0) { } else if (direction < 0) {
if (this->is_array) { if (this->is_array) {
return this->find_internal_minus_array<omtcmp_t, h>(extra, value, *idx); return this->find_internal_minus_array<omtcmp_t, h>(extra, value, child_idxp);
} else { } else {
return this->find_internal_minus<omtcmp_t, h>(this->d.t.root, extra, value, *idx); return this->find_internal_minus<omtcmp_t, h>(this->d.t.root, extra, value, child_idxp);
} }
} else { } else {
if (this->is_array) { if (this->is_array) {
return this->find_internal_plus_array<omtcmp_t, h>(extra, value, *idx); return this->find_internal_plus_array<omtcmp_t, h>(extra, value, child_idxp);
} else { } else {
return this->find_internal_plus<omtcmp_t, h>(this->d.t.root, extra, value, *idx); return this->find_internal_plus<omtcmp_t, h>(this->d.t.root, extra, value, child_idxp);
} }
} }
} }
...@@ -466,9 +471,10 @@ namespace toku { ...@@ -466,9 +471,10 @@ namespace toku {
} }
} }
inline void fill_array_with_subtree_values(omtdata_t *array, const node_idx tree_idx) const { __attribute__((nonnull(2)))
inline void fill_array_with_subtree_values(omtdata_t *const array, const node_idx tree_idx) const {
if (tree_idx==NODE_NULL) return; if (tree_idx==NODE_NULL) return;
omt_node &tree = this->d.t.nodes[tree_idx]; const omt_node &tree = this->d.t.nodes[tree_idx];
this->fill_array_with_subtree_values(&array[0], tree.left); this->fill_array_with_subtree_values(&array[0], tree.left);
array[this->nweight(tree.left)] = tree.value; array[this->nweight(tree.left)] = tree.value;
this->fill_array_with_subtree_values(&array[this->nweight(tree.left) + 1], tree.right); this->fill_array_with_subtree_values(&array[this->nweight(tree.left) + 1], tree.right);
...@@ -491,18 +497,19 @@ namespace toku { ...@@ -491,18 +497,19 @@ namespace toku {
} }
} }
inline void rebuild_from_sorted_array(node_idx *n_idxp, omtdata_t *values, const uint32_t numvalues) { __attribute__((nonnull(2,3)))
inline void rebuild_from_sorted_array(node_idx *const n_idxp, const omtdata_t *const values, const uint32_t numvalues) {
if (numvalues==0) { if (numvalues==0) {
*n_idxp = NODE_NULL; *n_idxp = NODE_NULL;
} else { } else {
const uint32_t halfway = numvalues/2; const uint32_t halfway = numvalues/2;
const node_idx newidx = this->node_malloc(); const node_idx newidx = this->node_malloc();
omt_node &newnode = this->d.t.nodes[newidx]; omt_node *const newnode = &this->d.t.nodes[newidx];
newnode.weight = numvalues; newnode->weight = numvalues;
newnode.value = values[halfway]; newnode->value = values[halfway];
*n_idxp = newidx; // update everything before the recursive calls so the second call can be a tail call. *n_idxp = newidx; // update everything before the recursive calls so the second call can be a tail call.
this->rebuild_from_sorted_array(&newnode.left, &values[0], halfway); this->rebuild_from_sorted_array(&newnode->left, &values[0], halfway);
this->rebuild_from_sorted_array(&newnode.right, &values[halfway+1], numvalues - (halfway+1)); this->rebuild_from_sorted_array(&newnode->right, &values[halfway+1], numvalues - (halfway+1));
} }
} }
...@@ -513,8 +520,8 @@ namespace toku { ...@@ -513,8 +520,8 @@ namespace toku {
new_size = new_size < 4 ? 4 : new_size; new_size = new_size < 4 ? 4 : new_size;
omt_node *XMALLOC_N(new_size, new_nodes); omt_node *XMALLOC_N(new_size, new_nodes);
omtdata_t *values = this->d.a.values; omtdata_t *const values = this->d.a.values;
omtdata_t *tmp_values = &values[this->d.a.start_idx]; omtdata_t *const tmp_values = &values[this->d.a.start_idx];
this->is_array = false; this->is_array = false;
this->d.t.nodes = new_nodes; this->d.t.nodes = new_nodes;
this->capacity = new_size; this->capacity = new_size;
...@@ -541,7 +548,7 @@ namespace toku { ...@@ -541,7 +548,7 @@ namespace toku {
inline bool will_need_rebalance(const node_idx n_idx, const int leftmod, const int rightmod) const { inline bool will_need_rebalance(const node_idx n_idx, const int leftmod, const int rightmod) const {
if (n_idx==NODE_NULL) { return false; } if (n_idx==NODE_NULL) { return false; }
omt_node &n = this->d.t.nodes[n_idx]; const omt_node &n = this->d.t.nodes[n_idx];
// one of the 1's is for the root. // one of the 1's is for the root.
// the other is to take ceil(n/2) // the other is to take ceil(n/2)
const uint32_t weight_left = this->nweight(n.left) + leftmod; const uint32_t weight_left = this->nweight(n.left) + leftmod;
...@@ -551,32 +558,32 @@ namespace toku { ...@@ -551,32 +558,32 @@ namespace toku {
(1+weight_right < (1+1+weight_left)/2)); (1+weight_right < (1+1+weight_left)/2));
} }
__attribute__((nonnull(5)))
inline void insert_internal(node_idx *n_idxp, const omtdata_t &value, const uint32_t idx, node_idx *&rebalance_idx) { inline void insert_internal(node_idx *n_idxp, const omtdata_t &value, const uint32_t idx, node_idx **const rebalance_idx) {
if (*n_idxp == NODE_NULL) { if (*n_idxp == NODE_NULL) {
invariant_zero(idx); invariant_zero(idx);
const node_idx newidx = this->node_malloc(); const node_idx newidx = this->node_malloc();
omt_node &newnode = this->d.t.nodes[newidx]; omt_node *const newnode = &this->d.t.nodes[newidx];
newnode.weight = 1; newnode->weight = 1;
newnode.left = NODE_NULL; newnode->left = NODE_NULL;
newnode.right = NODE_NULL; newnode->right = NODE_NULL;
newnode.value = value; newnode->value = value;
*n_idxp = newidx; *n_idxp = newidx;
} else { } else {
const node_idx thisidx = *n_idxp; const node_idx thisidx = *n_idxp;
omt_node &n = this->d.t.nodes[thisidx]; omt_node *const n = &this->d.t.nodes[thisidx];
n.weight++; n->weight++;
if (idx <= this->nweight(n.left)) { if (idx <= this->nweight(n->left)) {
if (rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 1, 0)) { if (*rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 1, 0)) {
rebalance_idx = n_idxp; *rebalance_idx = n_idxp;
} }
this->insert_internal(&n.left, value, idx, rebalance_idx); this->insert_internal(&n->left, value, idx, rebalance_idx);
} else { } else {
if (rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 0, 1)) { if (*rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 0, 1)) {
rebalance_idx = n_idxp; *rebalance_idx = n_idxp;
} }
uint32_t sub_index = idx - this->nweight(n.left) - 1; const uint32_t sub_index = idx - this->nweight(n->left) - 1;
this->insert_internal(&n.right, value, sub_index, rebalance_idx); this->insert_internal(&n->right, value, sub_index, rebalance_idx);
} }
} }
} }
...@@ -587,61 +594,66 @@ namespace toku { ...@@ -587,61 +594,66 @@ namespace toku {
inline void set_at_internal(const node_idx n_idx, const omtdata_t &value, const uint32_t idx) { inline void set_at_internal(const node_idx n_idx, const omtdata_t &value, const uint32_t idx) {
invariant(n_idx != NODE_NULL); invariant(n_idx != NODE_NULL);
omt_node &n = this->d.t.nodes[n_idx]; omt_node *const n = &this->d.t.nodes[n_idx];
const uint32_t leftweight = this->nweight(n.left); const uint32_t leftweight = this->nweight(n->left);
if (idx < leftweight) { if (idx < leftweight) {
this->set_at_internal(n.left, value, idx); this->set_at_internal(n->left, value, idx);
} else if (idx == leftweight) { } else if (idx == leftweight) {
n.value = value; n->value = value;
} else { } else {
this->set_at_internal(n.right, value, idx - leftweight - 1); this->set_at_internal(n->right, value, idx - leftweight - 1);
} }
} }
inline void delete_internal(node_idx *n_idxp, const uint32_t idx, omt_node &copyn, node_idx *&rebalance_idx) { __attribute__((nonnull(2,5)))
inline void delete_internal(node_idx *const n_idxp, const uint32_t idx, omt_node *const copyn, node_idx **const rebalance_idx) {
invariant(*n_idxp != NODE_NULL); invariant(*n_idxp != NODE_NULL);
omt_node &n = this->d.t.nodes[*n_idxp]; omt_node *const n = &this->d.t.nodes[*n_idxp];
const uint32_t leftweight = this->nweight(n.left); const uint32_t leftweight = this->nweight(n->left);
if (idx < leftweight) { if (idx < leftweight) {
n.weight--; n->weight--;
if (rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, -1, 0)) { if (*rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, -1, 0)) {
rebalance_idx = n_idxp; *rebalance_idx = n_idxp;
} }
this->delete_internal(&n.left, idx, copyn, rebalance_idx); this->delete_internal(&n->left, idx, copyn, rebalance_idx);
} else if (idx == leftweight) { } else if (idx == leftweight) {
if (n.left == NODE_NULL) { if (n->left == NODE_NULL) {
const uint32_t oldidx = *n_idxp; const uint32_t oldidx = *n_idxp;
*n_idxp = n.right; *n_idxp = n->right;
copyn.value = n.value; if (copyn != nullptr) {
copyn->value = n->value;
}
this->node_free(oldidx); this->node_free(oldidx);
} else if (n.right == NODE_NULL) { } else if (n->right == NODE_NULL) {
const uint32_t oldidx = *n_idxp; const uint32_t oldidx = *n_idxp;
*n_idxp = n.left; *n_idxp = n->left;
copyn.value = n.value; if (copyn != nullptr) {
copyn->value = n->value;
}
this->node_free(oldidx); this->node_free(oldidx);
} else { } else {
if (rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) { if (*rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) {
rebalance_idx = n_idxp; *rebalance_idx = n_idxp;
} }
// don't need to copy up value, it's only used by this // don't need to copy up value, it's only used by this
// next call, and when that gets to the bottom there // next call, and when that gets to the bottom there
// won't be any more recursion // won't be any more recursion
n.weight--; n->weight--;
this->delete_internal(&n.right, 0, n, rebalance_idx); this->delete_internal(&n->right, 0, n, rebalance_idx);
} }
} else { } else {
n.weight--; n->weight--;
if (rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) { if (*rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) {
rebalance_idx = n_idxp; *rebalance_idx = n_idxp;
} }
this->delete_internal(&n.right, idx - leftweight - 1, copyn, rebalance_idx); this->delete_internal(&n->right, idx - leftweight - 1, copyn, rebalance_idx);
} }
} }
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t &)> int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)>
inline int iterate_internal_array(const uint32_t left, const uint32_t right, inline int iterate_internal_array(const uint32_t left, const uint32_t right,
iterate_extra_t &iterate_extra) const { iterate_extra_t *const iterate_extra) const {
int r; int r;
for (uint32_t i = left; i < right; ++i) { for (uint32_t i = left; i < right; ++i) {
r = f(this->d.a.values[this->d.a.start_idx + i], i, iterate_extra); r = f(this->d.a.values[this->d.a.start_idx + i], i, iterate_extra);
...@@ -653,30 +665,30 @@ namespace toku { ...@@ -653,30 +665,30 @@ namespace toku {
} }
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(omtdata_t *, const uint32_t, iterate_extra_t &)> int (*f)(omtdata_t *, const uint32_t, iterate_extra_t *const)>
inline void iterate_ptr_internal(const uint32_t left, const uint32_t right, inline void iterate_ptr_internal(const uint32_t left, const uint32_t right,
const node_idx n_idx, const uint32_t idx, const node_idx n_idx, const uint32_t idx,
iterate_extra_t &iterate_extra) { iterate_extra_t *const iterate_extra) {
if (n_idx != NODE_NULL) { if (n_idx != NODE_NULL) {
omt_node &n = this->d.t.nodes[n_idx]; omt_node *const n = this->d.t.nodes[n_idx];
const uint32_t idx_root = idx + this->nweight(n.left); const uint32_t idx_root = idx + this->nweight(n->left);
if (left < idx_root) { if (left < idx_root) {
this->iterate_ptr_internal<iterate_extra_t, f>(left, right, n.left, idx, iterate_extra); this->iterate_ptr_internal<iterate_extra_t, f>(left, right, n->left, idx, iterate_extra);
} }
if (left <= idx_root && idx_root < right) { if (left <= idx_root && idx_root < right) {
int r = f(&n.value, idx_root, iterate_extra); int r = f(&n->value, idx_root, iterate_extra);
lazy_assert_zero(r); lazy_assert_zero(r);
} }
if (idx_root + 1 < right) { if (idx_root + 1 < right) {
this->iterate_ptr_internal<iterate_extra_t, f>(left, right, n.right, idx_root + 1, iterate_extra); this->iterate_ptr_internal<iterate_extra_t, f>(left, right, n->right, idx_root + 1, iterate_extra);
} }
} }
} }
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(omtdata_t *, const uint32_t, iterate_extra_t &)> int (*f)(omtdata_t *, const uint32_t, iterate_extra_t *const)>
inline void iterate_ptr_internal_array(const uint32_t left, const uint32_t right, inline void iterate_ptr_internal_array(const uint32_t left, const uint32_t right,
iterate_extra_t &iterate_extra) { iterate_extra_t *const iterate_extra) {
for (uint32_t i = left; i < right; ++i) { for (uint32_t i = left; i < right; ++i) {
int r = f(&this->d.a.values[this->d.a.start_idx + i], i, iterate_extra); int r = f(&this->d.a.values[this->d.a.start_idx + i], i, iterate_extra);
lazy_assert_zero(r); lazy_assert_zero(r);
...@@ -684,13 +696,13 @@ namespace toku { ...@@ -684,13 +696,13 @@ namespace toku {
} }
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t &)> int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)>
inline int iterate_internal(const uint32_t left, const uint32_t right, inline int iterate_internal(const uint32_t left, const uint32_t right,
const node_idx n_idx, const uint32_t idx, const node_idx n_idx, const uint32_t idx,
iterate_extra_t &iterate_extra) const { iterate_extra_t *const iterate_extra) const {
if (n_idx == NODE_NULL) { return 0; } if (n_idx == NODE_NULL) { return 0; }
int r; int r;
omt_node &n = this->d.t.nodes[n_idx]; const omt_node &n = this->d.t.nodes[n_idx];
const uint32_t idx_root = idx + this->nweight(n.left); const uint32_t idx_root = idx + this->nweight(n.left);
if (left < idx_root) { if (left < idx_root) {
r = this->iterate_internal<iterate_extra_t, f>(left, right, n.left, idx, iterate_extra); r = this->iterate_internal<iterate_extra_t, f>(left, right, n.left, idx, iterate_extra);
...@@ -708,51 +720,54 @@ namespace toku { ...@@ -708,51 +720,54 @@ namespace toku {
inline void fetch_internal_array(const uint32_t i, omtdataout_t *value) const { inline void fetch_internal_array(const uint32_t i, omtdataout_t *value) const {
if (value != nullptr) { if (value != nullptr) {
copyout(*value, this->d.a.values[this->d.a.start_idx + i]); copyout(value, &this->d.a.values[this->d.a.start_idx + i]);
} }
} }
inline void fetch_internal(const node_idx idx, const uint32_t i, omtdataout_t *value) const { inline void fetch_internal(const node_idx idx, const uint32_t i, omtdataout_t *value) const {
omt_node &n = this->d.t.nodes[idx]; omt_node *const n = &this->d.t.nodes[idx];
const uint32_t leftweight = this->nweight(n.left); const uint32_t leftweight = this->nweight(n->left);
if (i < leftweight) { if (i < leftweight) {
this->fetch_internal(n.left, i, value); this->fetch_internal(n->left, i, value);
} else if (i == leftweight) { } else if (i == leftweight) {
if (value != nullptr) { if (value != nullptr) {
copyout(*value, n); copyout(value, n);
} }
} else { } else {
this->fetch_internal(n.right, i - leftweight - 1, value); this->fetch_internal(n->right, i - leftweight - 1, value);
} }
} }
inline void fill_array_with_subtree_idxs(node_idx *array, const node_idx tree_idx) const { __attribute__((nonnull(2)))
inline void fill_array_with_subtree_idxs(node_idx *const array, const node_idx tree_idx) const {
if (tree_idx != NODE_NULL) { if (tree_idx != NODE_NULL) {
omt_node &tree = this->d.t.nodes[tree_idx]; const omt_node &tree = this->d.t.nodes[tree_idx];
this->fill_array_with_subtree_idxs(&array[0], tree.left); this->fill_array_with_subtree_idxs(&array[0], tree.left);
array[this->nweight(tree.left)] = tree_idx; array[this->nweight(tree.left)] = tree_idx;
this->fill_array_with_subtree_idxs(&array[this->nweight(tree.left) + 1], tree.right); this->fill_array_with_subtree_idxs(&array[this->nweight(tree.left) + 1], tree.right);
} }
} }
inline void rebuild_subtree_from_idxs(node_idx *n_idxp, const node_idx *idxs, const uint32_t numvalues) { __attribute__((nonnull(2,3)))
inline void rebuild_subtree_from_idxs(node_idx *const n_idxp, const node_idx *const idxs, const uint32_t numvalues) {
if (numvalues==0) { if (numvalues==0) {
*n_idxp = NODE_NULL; *n_idxp = NODE_NULL;
} else { } else {
uint32_t halfway = numvalues/2; uint32_t halfway = numvalues/2;
*n_idxp = idxs[halfway]; *n_idxp = idxs[halfway];
//node_idx newidx = idxs[halfway]; //node_idx newidx = idxs[halfway];
omt_node &newnode = this->d.t.nodes[*n_idxp]; omt_node *const newnode = &this->d.t.nodes[*n_idxp];
newnode.weight = numvalues; newnode->weight = numvalues;
// value is already in there. // value is already in there.
this->rebuild_subtree_from_idxs(&newnode.left, &idxs[0], halfway); this->rebuild_subtree_from_idxs(&newnode->left, &idxs[0], halfway);
this->rebuild_subtree_from_idxs(&newnode.right, &idxs[halfway+1], numvalues-(halfway+1)); this->rebuild_subtree_from_idxs(&newnode->right, &idxs[halfway+1], numvalues-(halfway+1));
//n_idx = newidx; //n_idx = newidx;
} }
} }
inline void rebalance(node_idx &n_idx) { __attribute__((nonnull(2)))
node_idx idx = n_idx; inline void rebalance(node_idx *const n_idxp) {
node_idx idx = *n_idxp;
if (idx==this->d.t.root) { if (idx==this->d.t.root) {
//Try to convert to an array. //Try to convert to an array.
//If this fails, (malloc) nothing will have changed. //If this fails, (malloc) nothing will have changed.
...@@ -776,30 +791,35 @@ namespace toku { ...@@ -776,30 +791,35 @@ namespace toku {
XMALLOC_N(n.weight, tmp_array); XMALLOC_N(n.weight, tmp_array);
} }
this->fill_array_with_subtree_idxs(tmp_array, idx); this->fill_array_with_subtree_idxs(tmp_array, idx);
this->rebuild_subtree_from_idxs(&n_idx, tmp_array, n.weight); this->rebuild_subtree_from_idxs(n_idxp, tmp_array, n.weight);
if (malloced) toku_free(tmp_array); if (malloced) toku_free(tmp_array);
} }
} }
static inline void copyout(omtdata_t &out, omt_node &n) { __attribute__((nonnull(1)))
out = n.value; static inline void copyout(omtdata_t *const out, const omt_node *const n) {
*out = n->value;
} }
static inline void copyout(omtdata_t *&out, omt_node &n) { __attribute__((nonnull(1,2)))
out = &n.value; static inline void copyout(omtdata_t **const out, omt_node *const n) {
*out = &n->value;
} }
static inline void copyout(omtdata_t &out, omtdata_t &stored_value) { __attribute__((nonnull(1)))
out = stored_value; static inline void copyout(omtdata_t *const out, const omtdata_t *const stored_value_ptr) {
*out = *stored_value_ptr;
} }
static inline void copyout(omtdata_t *&out, omtdata_t &stored_value) { __attribute__((nonnull(1,2)))
out = &stored_value; static inline void copyout(omtdata_t **const out, omtdata_t *const stored_value_ptr) {
*out = stored_value_ptr;
} }
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
inline int find_internal_zero_array(const omtcmp_t &extra, omtdataout_t *value, uint32_t &idx) const { __attribute__((nonnull(4)))
inline int find_internal_zero_array(const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const {
uint32_t min = this->d.a.start_idx; uint32_t min = this->d.a.start_idx;
uint32_t limit = this->d.a.start_idx + this->d.a.num_values; uint32_t limit = this->d.a.start_idx + this->d.a.num_values;
uint32_t best_pos = NODE_NULL; uint32_t best_pos = NODE_NULL;
...@@ -823,37 +843,38 @@ namespace toku { ...@@ -823,37 +843,38 @@ namespace toku {
if (best_zero!=NODE_NULL) { if (best_zero!=NODE_NULL) {
//Found a zero //Found a zero
if (value != nullptr) { if (value != nullptr) {
copyout(*value, this->d.a.values[best_zero]); copyout(value, &this->d.a.values[best_zero]);
} }
idx = best_zero - this->d.a.start_idx; *idxp = best_zero - this->d.a.start_idx;
return 0; return 0;
} }
if (best_pos!=NODE_NULL) idx = best_pos - this->d.a.start_idx; if (best_pos!=NODE_NULL) *idxp = best_pos - this->d.a.start_idx;
else idx = this->d.a.num_values; else *idxp = this->d.a.num_values;
return DB_NOTFOUND; return DB_NOTFOUND;
} }
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
inline int find_internal_zero(const node_idx n_idx, const omtcmp_t &extra, omtdataout_t *value, uint32_t &idx) const { __attribute__((nonnull(5)))
inline int find_internal_zero(const node_idx n_idx, const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const {
if (n_idx==NODE_NULL) { if (n_idx==NODE_NULL) {
idx = 0; *idxp = 0;
return DB_NOTFOUND; return DB_NOTFOUND;
} }
omt_node &n = this->d.t.nodes[n_idx]; omt_node *const n = &this->d.t.nodes[n_idx];
int hv = h(n.value, extra); int hv = h(n->value, extra);
if (hv<0) { if (hv<0) {
int r = this->find_internal_zero<omtcmp_t, h>(n.right, extra, value, idx); int r = this->find_internal_zero<omtcmp_t, h>(n->right, extra, value, idxp);
idx += this->nweight(n.left)+1; *idxp += this->nweight(n->left)+1;
return r; return r;
} else if (hv>0) { } else if (hv>0) {
return this->find_internal_zero<omtcmp_t, h>(n.left, extra, value, idx); return this->find_internal_zero<omtcmp_t, h>(n->left, extra, value, idxp);
} else { } else {
int r = this->find_internal_zero<omtcmp_t, h>(n.left, extra, value, idx); int r = this->find_internal_zero<omtcmp_t, h>(n->left, extra, value, idxp);
if (r==DB_NOTFOUND) { if (r==DB_NOTFOUND) {
idx = this->nweight(n.left); *idxp = this->nweight(n->left);
if (value != nullptr) { if (value != nullptr) {
copyout(*value, n); copyout(value, n);
} }
r = 0; r = 0;
} }
...@@ -863,7 +884,8 @@ namespace toku { ...@@ -863,7 +884,8 @@ namespace toku {
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
inline int find_internal_plus_array(const omtcmp_t &extra, omtdataout_t *value, uint32_t &idx) const { __attribute__((nonnull(4)))
inline int find_internal_plus_array(const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const {
uint32_t min = this->d.a.start_idx; uint32_t min = this->d.a.start_idx;
uint32_t limit = this->d.a.start_idx + this->d.a.num_values; uint32_t limit = this->d.a.start_idx + this->d.a.num_values;
uint32_t best = NODE_NULL; uint32_t best = NODE_NULL;
...@@ -880,34 +902,35 @@ namespace toku { ...@@ -880,34 +902,35 @@ namespace toku {
} }
if (best == NODE_NULL) { return DB_NOTFOUND; } if (best == NODE_NULL) { return DB_NOTFOUND; }
if (value != nullptr) { if (value != nullptr) {
copyout(*value, this->d.a.values[best]); copyout(value, &this->d.a.values[best]);
} }
idx = best - this->d.a.start_idx; *idxp = best - this->d.a.start_idx;
return 0; return 0;
} }
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
inline int find_internal_plus(const node_idx n_idx, const omtcmp_t &extra, omtdataout_t *value, uint32_t &idx) const { __attribute__((nonnull(5)))
inline int find_internal_plus(const node_idx n_idx, const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const {
if (n_idx==NODE_NULL) { if (n_idx==NODE_NULL) {
return DB_NOTFOUND; return DB_NOTFOUND;
} }
omt_node &n = this->d.t.nodes[n_idx]; omt_node *const n = &this->d.t.nodes[n_idx];
int hv = h(n.value, extra); int hv = h(n->value, extra);
int r; int r;
if (hv > 0) { if (hv > 0) {
r = this->find_internal_plus<omtcmp_t, h>(n.left, extra, value, idx); r = this->find_internal_plus<omtcmp_t, h>(n->left, extra, value, idxp);
if (r == DB_NOTFOUND) { if (r == DB_NOTFOUND) {
idx = this->nweight(n.left); *idxp = this->nweight(n->left);
if (value != nullptr) { if (value != nullptr) {
copyout(*value, n); copyout(value, n);
} }
r = 0; r = 0;
} }
} else { } else {
r = this->find_internal_plus<omtcmp_t, h>(n.right, extra, value, idx); r = this->find_internal_plus<omtcmp_t, h>(n->right, extra, value, idxp);
if (r == 0) { if (r == 0) {
idx += this->nweight(n.left) + 1; *idxp += this->nweight(n->left) + 1;
} }
} }
return r; return r;
...@@ -915,7 +938,8 @@ namespace toku { ...@@ -915,7 +938,8 @@ namespace toku {
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
inline int find_internal_minus_array(const omtcmp_t &extra, omtdataout_t *value, uint32_t &idx) const { __attribute__((nonnull(4)))
inline int find_internal_minus_array(const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const {
uint32_t min = this->d.a.start_idx; uint32_t min = this->d.a.start_idx;
uint32_t limit = this->d.a.start_idx + this->d.a.num_values; uint32_t limit = this->d.a.start_idx + this->d.a.num_values;
uint32_t best = NODE_NULL; uint32_t best = NODE_NULL;
...@@ -932,46 +956,49 @@ namespace toku { ...@@ -932,46 +956,49 @@ namespace toku {
} }
if (best == NODE_NULL) { return DB_NOTFOUND; } if (best == NODE_NULL) { return DB_NOTFOUND; }
if (value != nullptr) { if (value != nullptr) {
copyout(*value, this->d.a.values[best]); copyout(value, &this->d.a.values[best]);
} }
idx = best - this->d.a.start_idx; *idxp = best - this->d.a.start_idx;
return 0; return 0;
} }
template<typename omtcmp_t, template<typename omtcmp_t,
int (*h)(const omtdata_t &, const omtcmp_t &)> int (*h)(const omtdata_t &, const omtcmp_t &)>
inline int find_internal_minus(const node_idx n_idx, const omtcmp_t &extra, omtdataout_t *value, uint32_t &idx) const { __attribute__((nonnull(5)))
inline int find_internal_minus(const node_idx n_idx, const omtcmp_t &extra, omtdataout_t *value, uint32_t *const idxp) const {
if (n_idx==NODE_NULL) { if (n_idx==NODE_NULL) {
return DB_NOTFOUND; return DB_NOTFOUND;
} }
omt_node &n = this->d.t.nodes[n_idx]; omt_node *const n = &this->d.t.nodes[n_idx];
int hv = h(n.value, extra); int hv = h(n->value, extra);
if (hv < 0) { if (hv < 0) {
int r = this->find_internal_minus<omtcmp_t, h>(n.right, extra, value, idx); int r = this->find_internal_minus<omtcmp_t, h>(n->right, extra, value, idxp);
if (r == 0) { if (r == 0) {
idx += this->nweight(n.left) + 1; *idxp += this->nweight(n->left) + 1;
} else if (r == DB_NOTFOUND) { } else if (r == DB_NOTFOUND) {
idx = this->nweight(n.left); *idxp = this->nweight(n->left);
if (value != nullptr) { if (value != nullptr) {
copyout(*value, n); copyout(value, n);
} }
r = 0; r = 0;
} }
return r; return r;
} else { } else {
return this->find_internal_minus<omtcmp_t, h>(n.left, extra, value, idx); return this->find_internal_minus<omtcmp_t, h>(n->left, extra, value, idxp);
} }
} }
static inline int deep_clone_iter(const omtdata_t &value, const uint32_t idx, omt &dest) { __attribute__((nonnull(3)))
static inline int deep_clone_iter(const omtdata_t &value, const uint32_t idx, omt *const dest) {
static_assert(std::is_pointer<omtdata_t>::value, "omtdata_t isn't a pointer, can't do deep clone"); static_assert(std::is_pointer<omtdata_t>::value, "omtdata_t isn't a pointer, can't do deep clone");
invariant(idx == dest.d.a.num_values); invariant_nonnull(dest);
invariant(idx < dest.capacity); invariant(idx == dest->d.a.num_values);
XMEMDUP(dest.d.a.values[dest.d.a.num_values++], value); invariant(idx < dest->capacity);
XMEMDUP(dest->d.a.values[dest->d.a.num_values++], value);
return 0; return 0;
} }
static inline int free_items_iter(omtdata_t *value, const uint32_t idx __attribute__((__unused__)), int &unused __attribute__((__unused__))) { static inline int free_items_iter(omtdata_t *value, const uint32_t UU(idx), void *const UU(unused)) {
static_assert(std::is_pointer<omtdata_t>::value, "omtdata_t isn't a pointer, can't do free items"); static_assert(std::is_pointer<omtdata_t>::value, "omtdata_t isn't a pointer, can't do free items");
invariant_notnull(*value); invariant_notnull(*value);
toku_free(*value); toku_free(*value);
......
...@@ -1243,11 +1243,11 @@ static uint32_t recover_get_num_live_txns(RECOVER_ENV renv) { ...@@ -1243,11 +1243,11 @@ static uint32_t recover_get_num_live_txns(RECOVER_ENV renv) {
} }
// template-only function, but must be extern // template-only function, but must be extern
int is_txn_unprepared (const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN &extra); int is_txn_unprepared(const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN *const extra)
int __attribute__((nonnull(3)));
is_txn_unprepared (const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN &extra) { int is_txn_unprepared(const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN *const extra) {
if (txn->state != TOKUTXN_PREPARING) { if (txn->state != TOKUTXN_PREPARING) {
extra = txn; *extra = txn;
return -1; // return -1 to get iterator to return return -1; // return -1 to get iterator to return
} }
return 0; return 0;
...@@ -1255,13 +1255,13 @@ is_txn_unprepared (const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN &extra) ...@@ -1255,13 +1255,13 @@ is_txn_unprepared (const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN &extra)
static int find_an_unprepared_txn (RECOVER_ENV renv, TOKUTXN *txnp) { static int find_an_unprepared_txn (RECOVER_ENV renv, TOKUTXN *txnp) {
TOKUTXN txn = NULL; TOKUTXN txn = nullptr;
int r = toku_txn_manager_iter_over_live_txns<TOKUTXN, is_txn_unprepared>( int r = toku_txn_manager_iter_over_live_txns<TOKUTXN, is_txn_unprepared>(
renv->logger->txn_manager, renv->logger->txn_manager,
txn &txn
); );
assert(r == 0 || r == -1); assert(r == 0 || r == -1);
if (txn != NULL) { if (txn != nullptr) {
*txnp = txn; *txnp = txn;
return 0; return 0;
} }
...@@ -1269,10 +1269,10 @@ static int find_an_unprepared_txn (RECOVER_ENV renv, TOKUTXN *txnp) { ...@@ -1269,10 +1269,10 @@ static int find_an_unprepared_txn (RECOVER_ENV renv, TOKUTXN *txnp) {
} }
// template-only function, but must be extern // template-only function, but must be extern
int call_prepare_txn_callback_iter (const TOKUTXN &txn, const uint32_t UU(index), RECOVER_ENV &renv); int call_prepare_txn_callback_iter(const TOKUTXN &txn, const uint32_t UU(index), RECOVER_ENV *const renv)
int __attribute__((nonnull(3)));
call_prepare_txn_callback_iter (const TOKUTXN &txn, const uint32_t UU(index), RECOVER_ENV &renv) { int call_prepare_txn_callback_iter(const TOKUTXN &txn, const uint32_t UU(index), RECOVER_ENV *const renv) {
renv->prepared_txn_callback(renv->env, txn); (*renv)->prepared_txn_callback((*renv)->env, txn);
return 0; return 0;
} }
...@@ -1285,7 +1285,7 @@ static void recover_abort_live_txns(RECOVER_ENV renv) { ...@@ -1285,7 +1285,7 @@ static void recover_abort_live_txns(RECOVER_ENV renv) {
// abort the transaction // abort the transaction
r = toku_txn_abort_txn(txn, NULL, NULL); r = toku_txn_abort_txn(txn, NULL, NULL);
assert(r == 0); assert(r == 0);
// close the transaction // close the transaction
toku_txn_close_txn(txn); toku_txn_close_txn(txn);
} else if (r==DB_NOTFOUND) { } else if (r==DB_NOTFOUND) {
...@@ -1298,7 +1298,7 @@ static void recover_abort_live_txns(RECOVER_ENV renv) { ...@@ -1298,7 +1298,7 @@ static void recover_abort_live_txns(RECOVER_ENV renv) {
// Now we have only prepared txns. These prepared txns don't have full DB_TXNs in them, so we need to make some. // Now we have only prepared txns. These prepared txns don't have full DB_TXNs in them, so we need to make some.
int r = toku_txn_manager_iter_over_live_txns<RECOVER_ENV, call_prepare_txn_callback_iter>( int r = toku_txn_manager_iter_over_live_txns<RECOVER_ENV, call_prepare_txn_callback_iter>(
renv->logger->txn_manager, renv->logger->txn_manager,
renv &renv
); );
assert_zero(r); assert_zero(r);
} }
......
...@@ -417,22 +417,22 @@ done: ...@@ -417,22 +417,22 @@ done:
} }
// template-only function, but must be extern // template-only function, but must be extern
int referenced_xids_note_snapshot_txn_end_iter(const TXNID &live_xid, const uint32_t UU(index), rx_omt_t &referenced_xids); int referenced_xids_note_snapshot_txn_end_iter(const TXNID &live_xid, const uint32_t UU(index), rx_omt_t *const referenced_xids)
int __attribute__((nonnull(3)));
referenced_xids_note_snapshot_txn_end_iter(const TXNID &live_xid, const uint32_t UU(index), rx_omt_t &referenced_xids) int referenced_xids_note_snapshot_txn_end_iter(const TXNID &live_xid, const uint32_t UU(index), rx_omt_t *const referenced_xids)
{ {
int r; int r;
uint32_t idx; uint32_t idx;
struct referenced_xid_tuple *tuple; struct referenced_xid_tuple *tuple;
r = referenced_xids.find_zero<TXNID, find_tuple_by_xid>(live_xid, &tuple, &idx); r = referenced_xids->find_zero<TXNID, find_tuple_by_xid>(live_xid, &tuple, &idx);
if (r == DB_NOTFOUND) { if (r == DB_NOTFOUND) {
goto done; goto done;
} }
invariant_zero(r); invariant_zero(r);
invariant(tuple->references > 0); invariant(tuple->references > 0);
if (--tuple->references == 0) { if (--tuple->references == 0) {
r = referenced_xids.delete_at(idx); r = referenced_xids->delete_at(idx);
lazy_assert_zero(r); lazy_assert_zero(r);
} }
done: done:
...@@ -443,7 +443,7 @@ done: ...@@ -443,7 +443,7 @@ done:
static int static int
referenced_xids_note_snapshot_txn_end(TXN_MANAGER mgr, const xid_omt_t &live_root_txn_list) { referenced_xids_note_snapshot_txn_end(TXN_MANAGER mgr, const xid_omt_t &live_root_txn_list) {
int r; int r;
r = live_root_txn_list.iterate<rx_omt_t, referenced_xids_note_snapshot_txn_end_iter>(mgr->referenced_xids); r = live_root_txn_list.iterate<rx_omt_t, referenced_xids_note_snapshot_txn_end_iter>(&mgr->referenced_xids);
invariant_zero(r); invariant_zero(r);
return r; return r;
} }
......
...@@ -73,10 +73,10 @@ uint32_t toku_txn_manager_num_live_txns(TXN_MANAGER txn_manager); ...@@ -73,10 +73,10 @@ uint32_t toku_txn_manager_num_live_txns(TXN_MANAGER txn_manager);
template<typename iterate_extra_t, template<typename iterate_extra_t,
int (*f)(const TOKUTXN &, const uint32_t, iterate_extra_t &)> int (*f)(const TOKUTXN &, const uint32_t, iterate_extra_t *const)>
int toku_txn_manager_iter_over_live_txns( int toku_txn_manager_iter_over_live_txns(
TXN_MANAGER txn_manager, TXN_MANAGER txn_manager,
iterate_extra_t &v iterate_extra_t *const v
) )
{ {
int r = 0; int r = 0;
......
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