mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 06:44:16 +01:00
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
This commit is contained in:
parent
8fa5ec3e82
commit
c010c1e56e
8 changed files with 282 additions and 254 deletions
|
@ -2643,10 +2643,11 @@ set_filenum_in_array(OMTVALUE hv, u_int32_t index, void*arrayv) {
|
|||
}
|
||||
|
||||
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
|
||||
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;
|
||||
CACHETABLE ct = *ctp;
|
||||
TOKULOGGER logger = txn->logger;
|
||||
FILENUMS open_filenums;
|
||||
uint32_t num_filenums = toku_omt_size(txn->open_fts);
|
||||
|
@ -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>(
|
||||
logger->txn_manager,
|
||||
ct
|
||||
&ct
|
||||
);
|
||||
assert(r==0);
|
||||
}
|
||||
|
|
44
ft/ft-ops.cc
44
ft/ft-ops.cc
|
@ -3775,16 +3775,16 @@ struct copy_to_stale_extra {
|
|||
};
|
||||
|
||||
// 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 &extra)
|
||||
int copy_to_stale(const long &offset, const uint32_t UU(idx), struct copy_to_stale_extra *const extra)
|
||||
__attribute__((nonnull(3)));
|
||||
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;
|
||||
DBT keydbt;
|
||||
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 };
|
||||
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);
|
||||
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);
|
||||
assert_zero(r);
|
||||
return r;
|
||||
}
|
||||
|
@ -3795,12 +3795,12 @@ struct store_fifo_offset_extra {
|
|||
};
|
||||
|
||||
// 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 &extra)
|
||||
int store_fifo_offset(const long &offset, const uint32_t UU(idx), struct store_fifo_offset_extra *const extra)
|
||||
__attribute__((nonnull(3)));
|
||||
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.i++;
|
||||
extra->offsets[extra->i] = offset;
|
||||
extra->i++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3873,13 +3873,13 @@ struct iterate_do_bn_apply_cmd_extra {
|
|||
};
|
||||
|
||||
// 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 &e)
|
||||
int iterate_do_bn_apply_cmd(const long &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_cmd_extra *const e)
|
||||
__attribute__((nonnull(3)));
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -4032,15 +4032,15 @@ bnc_apply_messages_to_basement_node(
|
|||
struct store_fifo_offset_extra sfo_extra = { .offsets = offsets, .i = 0 };
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
invariant(sfo_extra.i == buffer_size);
|
||||
|
||||
|
@ -4060,7 +4060,7 @@ bnc_apply_messages_to_basement_node(
|
|||
// 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};
|
||||
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);
|
||||
} else if (fresh_lbi == fresh_ube) {
|
||||
// No fresh messages to apply, we just apply stale messages.
|
||||
|
@ -4068,7 +4068,7 @@ bnc_apply_messages_to_basement_node(
|
|||
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};
|
||||
|
||||
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);
|
||||
} else {
|
||||
// We have stale and fresh messages but no broadcasts. We can
|
||||
|
@ -4157,7 +4157,7 @@ bnc_apply_messages_to_basement_node(
|
|||
// procedures because we're still looking at the fresh tree. Instead
|
||||
// we have to move messages after we're done looking at it.
|
||||
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);
|
||||
for (uint32_t ube = fresh_ube; fresh_lbi < ube; --ube) {
|
||||
// When we delete the message at the fresh_lbi index, everything
|
||||
|
|
|
@ -106,13 +106,13 @@ struct count_msgs_extra {
|
|||
};
|
||||
|
||||
// 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 &e)
|
||||
int count_msgs(const long &offset, const uint32_t UU(idx), struct count_msgs_extra *const e)
|
||||
__attribute__((nonnull(3)));
|
||||
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);
|
||||
if (entry->msn.msn == e.msn.msn) {
|
||||
e.count++;
|
||||
const struct fifo_entry *entry = toku_fifo_get_entry(e->fifo, offset);
|
||||
if (entry->msn.msn == e->msn.msn) {
|
||||
e->count++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -128,27 +128,27 @@ struct verify_message_tree_extra {
|
|||
};
|
||||
|
||||
// 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 &e)
|
||||
int verify_message_tree(const long &offset, const uint32_t UU(idx), struct verify_message_tree_extra *const e)
|
||||
__attribute__((nonnull(3)));
|
||||
int verify_message_tree(const long &offset, const uint32_t UU(idx), struct verify_message_tree_extra *const e)
|
||||
{
|
||||
int verbose = e.verbose;
|
||||
BLOCKNUM blocknum = e.blocknum;
|
||||
int keep_going_on_failure = e.keep_going_on_failure;
|
||||
int verbose = e->verbose;
|
||||
BLOCKNUM blocknum = e->blocknum;
|
||||
int keep_going_on_failure = e->keep_going_on_failure;
|
||||
int result = 0;
|
||||
const struct fifo_entry *entry = toku_fifo_get_entry(e.fifo, offset);
|
||||
if (e.broadcast) {
|
||||
const struct fifo_entry *entry = toku_fifo_get_entry(e->fifo, offset);
|
||||
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),
|
||||
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 {
|
||||
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");
|
||||
if (e.is_fresh) {
|
||||
e->i, "message found in fresh or stale message tree that does not apply once");
|
||||
if (e->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 {
|
||||
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:
|
||||
|
@ -296,19 +296,19 @@ toku_verify_ftnode (FT_HANDLE brt,
|
|||
} 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");
|
||||
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");
|
||||
}
|
||||
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 };
|
||||
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; }
|
||||
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; }
|
||||
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; }
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -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);
|
||||
assert_zero(r);
|
||||
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);
|
||||
assert_zero(r);
|
||||
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.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,
|
|||
r = key_msn_sort::mergesort_r(fresh_offsets, nfresh, extra);
|
||||
assert_zero(r);
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
387
ft/omt-tmpl.h
387
ft/omt-tmpl.h
|
@ -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->d.a.num_values = numvalues;
|
||||
this->d.a.values = values;
|
||||
values = nullptr;
|
||||
this->d.a.values = *values;
|
||||
*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; }
|
||||
this->convert_to_array();
|
||||
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->maybe_resize_array();
|
||||
}
|
||||
|
@ -78,37 +82,40 @@ namespace toku {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
void merge(omt &leftomt, omt &rightomt) {
|
||||
const uint32_t leftsize = leftomt.size();
|
||||
const uint32_t rightsize = rightomt.size();
|
||||
__attribute__((nonnull(2,3)))
|
||||
void merge(omt *const leftomt, omt *const rightomt) {
|
||||
invariant_notnull(leftomt);
|
||||
invariant_notnull(rightomt);
|
||||
const uint32_t leftsize = leftomt->size();
|
||||
const uint32_t rightsize = rightomt->size();
|
||||
const uint32_t newsize = leftsize + rightsize;
|
||||
|
||||
if (leftomt.is_array) {
|
||||
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->d.a.start_idx = leftomt.d.a.start_idx;
|
||||
if (leftomt->is_array) {
|
||||
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->d.a.start_idx = leftomt->d.a.start_idx;
|
||||
} else {
|
||||
this->create_internal(newsize);
|
||||
memcpy(&this->d.a.values[0],
|
||||
&leftomt.d.a.values[leftomt.d.a.start_idx],
|
||||
leftomt.d.a.num_values * (sizeof this->d.a.values[0]));
|
||||
&leftomt->d.a.values[leftomt->d.a.start_idx],
|
||||
leftomt->d.a.num_values * (sizeof this->d.a.values[0]));
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
|
||||
if (rightomt.is_array) {
|
||||
if (rightomt->is_array) {
|
||||
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.num_values * (sizeof this->d.a.values[0]));
|
||||
&rightomt->d.a.values[rightomt->d.a.start_idx],
|
||||
rightomt->d.a.num_values * (sizeof this->d.a.values[0]));
|
||||
} else {
|
||||
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->fill_array_with_subtree_values(&this->d.a.values[this->d.a.start_idx + this->d.a.num_values],
|
||||
rightomt->d.t.root);
|
||||
}
|
||||
rightomt.destroy();
|
||||
rightomt->destroy();
|
||||
this->d.a.num_values += rightsize;
|
||||
invariant(this->size() == newsize);
|
||||
}
|
||||
|
@ -133,7 +140,7 @@ namespace toku {
|
|||
void deep_clone(const omt &src)
|
||||
{
|
||||
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);
|
||||
this->d.a.num_values = src.size();
|
||||
}
|
||||
|
@ -229,9 +236,9 @@ namespace toku {
|
|||
}
|
||||
else {
|
||||
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) {
|
||||
this->rebalance(*rebalance_idx);
|
||||
this->rebalance(rebalance_idx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -270,10 +277,9 @@ namespace toku {
|
|||
this->d.a.num_values--;
|
||||
} else {
|
||||
node_idx *rebalance_idx = nullptr;
|
||||
omt_node unused;
|
||||
this->delete_internal(&this->d.t.root, idx, unused, rebalance_idx);
|
||||
this->delete_internal(&this->d.t.root, idx, nullptr, &rebalance_idx);
|
||||
if (rebalance_idx != nullptr) {
|
||||
this->rebalance(*rebalance_idx);
|
||||
this->rebalance(rebalance_idx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -283,8 +289,8 @@ namespace toku {
|
|||
*
|
||||
*/
|
||||
template<typename iterate_extra_t,
|
||||
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t &)>
|
||||
int iterate(iterate_extra_t &iterate_extra) const {
|
||||
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t *const)>
|
||||
int iterate(iterate_extra_t *const iterate_extra) const {
|
||||
return this->iterate_on_range<iterate_extra_t, f>(0, this->size(), iterate_extra);
|
||||
}
|
||||
|
||||
|
@ -292,8 +298,8 @@ namespace toku {
|
|||
*
|
||||
*/
|
||||
template<typename iterate_extra_t,
|
||||
int (*f)(const omtdata_t &, const uint32_t, iterate_extra_t &)>
|
||||
int iterate_on_range(const uint32_t left, const uint32_t right, iterate_extra_t &iterate_extra) const {
|
||||
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 *const iterate_extra) const {
|
||||
if (right > this->size()) { return EINVAL; }
|
||||
if (this->is_array) {
|
||||
return this->iterate_internal_array<iterate_extra_t, f>(left, right, iterate_extra);
|
||||
|
@ -305,8 +311,8 @@ namespace toku {
|
|||
*
|
||||
*/
|
||||
template<typename iterate_extra_t,
|
||||
int (*f)(omtdata_t *, const uint32_t, iterate_extra_t &)>
|
||||
void iterate_ptr(iterate_extra_t &iterate_extra) {
|
||||
int (*f)(omtdata_t *, const uint32_t, iterate_extra_t *const)>
|
||||
void iterate_ptr(iterate_extra_t *const iterate_extra) {
|
||||
if (this->is_array) {
|
||||
this->iterate_ptr_internal_array<iterate_extra_t, f>(0, this->size(), iterate_extra);
|
||||
} else {
|
||||
|
@ -315,8 +321,7 @@ namespace toku {
|
|||
}
|
||||
|
||||
void free_items(void) {
|
||||
int unused = 0;
|
||||
this->iterate_ptr<int, free_items_iter>(unused);
|
||||
this->iterate_ptr<void, free_items_iter>(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,16 +343,16 @@ namespace toku {
|
|||
*/
|
||||
template<typename 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;
|
||||
if (idx==nullptr) idx=&tmp_index;
|
||||
uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index;
|
||||
int r;
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
@ -357,23 +362,23 @@ namespace toku {
|
|||
*/
|
||||
template<typename 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;
|
||||
if (idx == nullptr) { idx = &tmp_index; }
|
||||
uint32_t *const child_idxp = (idxp != nullptr) ? idxp : &tmp_index;
|
||||
if (direction == 0) {
|
||||
abort();
|
||||
} else if (direction < 0) {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
array[this->nweight(tree.left)] = tree.value;
|
||||
this->fill_array_with_subtree_values(&array[this->nweight(tree.left) + 1], tree.right);
|
||||
|
@ -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) {
|
||||
*n_idxp = NODE_NULL;
|
||||
} else {
|
||||
const uint32_t halfway = numvalues/2;
|
||||
const node_idx newidx = this->node_malloc();
|
||||
omt_node &newnode = this->d.t.nodes[newidx];
|
||||
newnode.weight = numvalues;
|
||||
newnode.value = values[halfway];
|
||||
omt_node *const newnode = &this->d.t.nodes[newidx];
|
||||
newnode->weight = numvalues;
|
||||
newnode->value = values[halfway];
|
||||
*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.right, &values[halfway+1], numvalues - (halfway+1));
|
||||
this->rebuild_from_sorted_array(&newnode->left, &values[0], halfway);
|
||||
this->rebuild_from_sorted_array(&newnode->right, &values[halfway+1], numvalues - (halfway+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,8 +520,8 @@ namespace toku {
|
|||
new_size = new_size < 4 ? 4 : new_size;
|
||||
|
||||
omt_node *XMALLOC_N(new_size, new_nodes);
|
||||
omtdata_t *values = this->d.a.values;
|
||||
omtdata_t *tmp_values = &values[this->d.a.start_idx];
|
||||
omtdata_t *const values = this->d.a.values;
|
||||
omtdata_t *const tmp_values = &values[this->d.a.start_idx];
|
||||
this->is_array = false;
|
||||
this->d.t.nodes = new_nodes;
|
||||
this->capacity = new_size;
|
||||
|
@ -541,7 +548,7 @@ namespace toku {
|
|||
|
||||
inline bool will_need_rebalance(const node_idx n_idx, const int leftmod, const int rightmod) const {
|
||||
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.
|
||||
// the other is to take ceil(n/2)
|
||||
const uint32_t weight_left = this->nweight(n.left) + leftmod;
|
||||
|
@ -551,32 +558,32 @@ namespace toku {
|
|||
(1+weight_right < (1+1+weight_left)/2));
|
||||
}
|
||||
|
||||
|
||||
inline void insert_internal(node_idx *n_idxp, const omtdata_t &value, const uint32_t idx, node_idx *&rebalance_idx) {
|
||||
__attribute__((nonnull(5)))
|
||||
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) {
|
||||
invariant_zero(idx);
|
||||
const node_idx newidx = this->node_malloc();
|
||||
omt_node &newnode = this->d.t.nodes[newidx];
|
||||
newnode.weight = 1;
|
||||
newnode.left = NODE_NULL;
|
||||
newnode.right = NODE_NULL;
|
||||
newnode.value = value;
|
||||
omt_node *const newnode = &this->d.t.nodes[newidx];
|
||||
newnode->weight = 1;
|
||||
newnode->left = NODE_NULL;
|
||||
newnode->right = NODE_NULL;
|
||||
newnode->value = value;
|
||||
*n_idxp = newidx;
|
||||
} else {
|
||||
const node_idx thisidx = *n_idxp;
|
||||
omt_node &n = this->d.t.nodes[thisidx];
|
||||
n.weight++;
|
||||
if (idx <= this->nweight(n.left)) {
|
||||
if (rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 1, 0)) {
|
||||
rebalance_idx = n_idxp;
|
||||
omt_node *const n = &this->d.t.nodes[thisidx];
|
||||
n->weight++;
|
||||
if (idx <= this->nweight(n->left)) {
|
||||
if (*rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 1, 0)) {
|
||||
*rebalance_idx = n_idxp;
|
||||
}
|
||||
this->insert_internal(&n.left, value, idx, rebalance_idx);
|
||||
this->insert_internal(&n->left, value, idx, rebalance_idx);
|
||||
} else {
|
||||
if (rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 0, 1)) {
|
||||
rebalance_idx = n_idxp;
|
||||
if (*rebalance_idx == nullptr && this->will_need_rebalance(thisidx, 0, 1)) {
|
||||
*rebalance_idx = n_idxp;
|
||||
}
|
||||
uint32_t sub_index = idx - this->nweight(n.left) - 1;
|
||||
this->insert_internal(&n.right, value, sub_index, rebalance_idx);
|
||||
const uint32_t sub_index = idx - this->nweight(n->left) - 1;
|
||||
this->insert_internal(&n->right, value, sub_index, rebalance_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -587,61 +594,66 @@ namespace toku {
|
|||
|
||||
inline void set_at_internal(const node_idx n_idx, const omtdata_t &value, const uint32_t idx) {
|
||||
invariant(n_idx != NODE_NULL);
|
||||
omt_node &n = this->d.t.nodes[n_idx];
|
||||
const uint32_t leftweight = this->nweight(n.left);
|
||||
omt_node *const n = &this->d.t.nodes[n_idx];
|
||||
const uint32_t leftweight = this->nweight(n->left);
|
||||
if (idx < leftweight) {
|
||||
this->set_at_internal(n.left, value, idx);
|
||||
this->set_at_internal(n->left, value, idx);
|
||||
} else if (idx == leftweight) {
|
||||
n.value = value;
|
||||
n->value = value;
|
||||
} 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 ©n, 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);
|
||||
omt_node &n = this->d.t.nodes[*n_idxp];
|
||||
const uint32_t leftweight = this->nweight(n.left);
|
||||
omt_node *const n = &this->d.t.nodes[*n_idxp];
|
||||
const uint32_t leftweight = this->nweight(n->left);
|
||||
if (idx < leftweight) {
|
||||
n.weight--;
|
||||
if (rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, -1, 0)) {
|
||||
rebalance_idx = n_idxp;
|
||||
n->weight--;
|
||||
if (*rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, -1, 0)) {
|
||||
*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) {
|
||||
if (n.left == NODE_NULL) {
|
||||
if (n->left == NODE_NULL) {
|
||||
const uint32_t oldidx = *n_idxp;
|
||||
*n_idxp = n.right;
|
||||
copyn.value = n.value;
|
||||
*n_idxp = n->right;
|
||||
if (copyn != nullptr) {
|
||||
copyn->value = n->value;
|
||||
}
|
||||
this->node_free(oldidx);
|
||||
} else if (n.right == NODE_NULL) {
|
||||
} else if (n->right == NODE_NULL) {
|
||||
const uint32_t oldidx = *n_idxp;
|
||||
*n_idxp = n.left;
|
||||
copyn.value = n.value;
|
||||
*n_idxp = n->left;
|
||||
if (copyn != nullptr) {
|
||||
copyn->value = n->value;
|
||||
}
|
||||
this->node_free(oldidx);
|
||||
} else {
|
||||
if (rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) {
|
||||
rebalance_idx = n_idxp;
|
||||
if (*rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) {
|
||||
*rebalance_idx = n_idxp;
|
||||
}
|
||||
// don't need to copy up value, it's only used by this
|
||||
// next call, and when that gets to the bottom there
|
||||
// won't be any more recursion
|
||||
n.weight--;
|
||||
this->delete_internal(&n.right, 0, n, rebalance_idx);
|
||||
n->weight--;
|
||||
this->delete_internal(&n->right, 0, n, rebalance_idx);
|
||||
}
|
||||
} else {
|
||||
n.weight--;
|
||||
if (rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) {
|
||||
rebalance_idx = n_idxp;
|
||||
n->weight--;
|
||||
if (*rebalance_idx == nullptr && this->will_need_rebalance(*n_idxp, 0, -1)) {
|
||||
*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,
|
||||
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,
|
||||
iterate_extra_t &iterate_extra) const {
|
||||
iterate_extra_t *const iterate_extra) const {
|
||||
int r;
|
||||
for (uint32_t i = left; i < right; ++i) {
|
||||
r = f(this->d.a.values[this->d.a.start_idx + i], i, iterate_extra);
|
||||
|
@ -653,30 +665,30 @@ namespace toku {
|
|||
}
|
||||
|
||||
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,
|
||||
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) {
|
||||
omt_node &n = this->d.t.nodes[n_idx];
|
||||
const uint32_t idx_root = idx + this->nweight(n.left);
|
||||
omt_node *const n = this->d.t.nodes[n_idx];
|
||||
const uint32_t idx_root = idx + this->nweight(n->left);
|
||||
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) {
|
||||
int r = f(&n.value, idx_root, iterate_extra);
|
||||
int r = f(&n->value, idx_root, iterate_extra);
|
||||
lazy_assert_zero(r);
|
||||
}
|
||||
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,
|
||||
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,
|
||||
iterate_extra_t &iterate_extra) {
|
||||
iterate_extra_t *const iterate_extra) {
|
||||
for (uint32_t i = left; i < right; ++i) {
|
||||
int r = f(&this->d.a.values[this->d.a.start_idx + i], i, iterate_extra);
|
||||
lazy_assert_zero(r);
|
||||
|
@ -684,13 +696,13 @@ namespace toku {
|
|||
}
|
||||
|
||||
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,
|
||||
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; }
|
||||
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);
|
||||
if (left < idx_root) {
|
||||
r = this->iterate_internal<iterate_extra_t, f>(left, right, n.left, idx, iterate_extra);
|
||||
|
@ -708,51 +720,54 @@ namespace toku {
|
|||
|
||||
inline void fetch_internal_array(const uint32_t i, omtdataout_t *value) const {
|
||||
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 {
|
||||
omt_node &n = this->d.t.nodes[idx];
|
||||
const uint32_t leftweight = this->nweight(n.left);
|
||||
omt_node *const n = &this->d.t.nodes[idx];
|
||||
const uint32_t leftweight = this->nweight(n->left);
|
||||
if (i < leftweight) {
|
||||
this->fetch_internal(n.left, i, value);
|
||||
this->fetch_internal(n->left, i, value);
|
||||
} else if (i == leftweight) {
|
||||
if (value != nullptr) {
|
||||
copyout(*value, n);
|
||||
copyout(value, n);
|
||||
}
|
||||
} 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) {
|
||||
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);
|
||||
array[this->nweight(tree.left)] = tree_idx;
|
||||
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) {
|
||||
*n_idxp = NODE_NULL;
|
||||
} else {
|
||||
uint32_t halfway = numvalues/2;
|
||||
*n_idxp = idxs[halfway];
|
||||
//node_idx newidx = idxs[halfway];
|
||||
omt_node &newnode = this->d.t.nodes[*n_idxp];
|
||||
newnode.weight = numvalues;
|
||||
omt_node *const newnode = &this->d.t.nodes[*n_idxp];
|
||||
newnode->weight = numvalues;
|
||||
// value is already in there.
|
||||
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->left, &idxs[0], halfway);
|
||||
this->rebuild_subtree_from_idxs(&newnode->right, &idxs[halfway+1], numvalues-(halfway+1));
|
||||
//n_idx = newidx;
|
||||
}
|
||||
}
|
||||
|
||||
inline void rebalance(node_idx &n_idx) {
|
||||
node_idx idx = n_idx;
|
||||
__attribute__((nonnull(2)))
|
||||
inline void rebalance(node_idx *const n_idxp) {
|
||||
node_idx idx = *n_idxp;
|
||||
if (idx==this->d.t.root) {
|
||||
//Try to convert to an array.
|
||||
//If this fails, (malloc) nothing will have changed.
|
||||
|
@ -776,30 +791,35 @@ namespace toku {
|
|||
XMALLOC_N(n.weight, tmp_array);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void copyout(omtdata_t &out, omt_node &n) {
|
||||
out = n.value;
|
||||
__attribute__((nonnull(1)))
|
||||
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) {
|
||||
out = &n.value;
|
||||
__attribute__((nonnull(1,2)))
|
||||
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) {
|
||||
out = stored_value;
|
||||
__attribute__((nonnull(1)))
|
||||
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) {
|
||||
out = &stored_value;
|
||||
__attribute__((nonnull(1,2)))
|
||||
static inline void copyout(omtdata_t **const out, omtdata_t *const stored_value_ptr) {
|
||||
*out = stored_value_ptr;
|
||||
}
|
||||
|
||||
template<typename 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 limit = this->d.a.start_idx + this->d.a.num_values;
|
||||
uint32_t best_pos = NODE_NULL;
|
||||
|
@ -823,37 +843,38 @@ namespace toku {
|
|||
if (best_zero!=NODE_NULL) {
|
||||
//Found a zero
|
||||
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;
|
||||
}
|
||||
if (best_pos!=NODE_NULL) idx = best_pos - this->d.a.start_idx;
|
||||
else idx = this->d.a.num_values;
|
||||
if (best_pos!=NODE_NULL) *idxp = best_pos - this->d.a.start_idx;
|
||||
else *idxp = this->d.a.num_values;
|
||||
return DB_NOTFOUND;
|
||||
}
|
||||
|
||||
template<typename 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) {
|
||||
idx = 0;
|
||||
*idxp = 0;
|
||||
return DB_NOTFOUND;
|
||||
}
|
||||
omt_node &n = this->d.t.nodes[n_idx];
|
||||
int hv = h(n.value, extra);
|
||||
omt_node *const n = &this->d.t.nodes[n_idx];
|
||||
int hv = h(n->value, extra);
|
||||
if (hv<0) {
|
||||
int r = this->find_internal_zero<omtcmp_t, h>(n.right, extra, value, idx);
|
||||
idx += this->nweight(n.left)+1;
|
||||
int r = this->find_internal_zero<omtcmp_t, h>(n->right, extra, value, idxp);
|
||||
*idxp += this->nweight(n->left)+1;
|
||||
return r;
|
||||
} 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 {
|
||||
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) {
|
||||
idx = this->nweight(n.left);
|
||||
*idxp = this->nweight(n->left);
|
||||
if (value != nullptr) {
|
||||
copyout(*value, n);
|
||||
copyout(value, n);
|
||||
}
|
||||
r = 0;
|
||||
}
|
||||
|
@ -863,7 +884,8 @@ namespace toku {
|
|||
|
||||
template<typename 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 limit = this->d.a.start_idx + this->d.a.num_values;
|
||||
uint32_t best = NODE_NULL;
|
||||
|
@ -880,34 +902,35 @@ namespace toku {
|
|||
}
|
||||
if (best == NODE_NULL) { return DB_NOTFOUND; }
|
||||
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;
|
||||
}
|
||||
|
||||
template<typename 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) {
|
||||
return DB_NOTFOUND;
|
||||
}
|
||||
omt_node &n = this->d.t.nodes[n_idx];
|
||||
int hv = h(n.value, extra);
|
||||
omt_node *const n = &this->d.t.nodes[n_idx];
|
||||
int hv = h(n->value, extra);
|
||||
int r;
|
||||
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) {
|
||||
idx = this->nweight(n.left);
|
||||
*idxp = this->nweight(n->left);
|
||||
if (value != nullptr) {
|
||||
copyout(*value, n);
|
||||
copyout(value, n);
|
||||
}
|
||||
r = 0;
|
||||
}
|
||||
} 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) {
|
||||
idx += this->nweight(n.left) + 1;
|
||||
*idxp += this->nweight(n->left) + 1;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
@ -915,7 +938,8 @@ namespace toku {
|
|||
|
||||
template<typename 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 limit = this->d.a.start_idx + this->d.a.num_values;
|
||||
uint32_t best = NODE_NULL;
|
||||
|
@ -932,46 +956,49 @@ namespace toku {
|
|||
}
|
||||
if (best == NODE_NULL) { return DB_NOTFOUND; }
|
||||
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;
|
||||
}
|
||||
|
||||
template<typename 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) {
|
||||
return DB_NOTFOUND;
|
||||
}
|
||||
omt_node &n = this->d.t.nodes[n_idx];
|
||||
int hv = h(n.value, extra);
|
||||
omt_node *const n = &this->d.t.nodes[n_idx];
|
||||
int hv = h(n->value, extra);
|
||||
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) {
|
||||
idx += this->nweight(n.left) + 1;
|
||||
*idxp += this->nweight(n->left) + 1;
|
||||
} else if (r == DB_NOTFOUND) {
|
||||
idx = this->nweight(n.left);
|
||||
*idxp = this->nweight(n->left);
|
||||
if (value != nullptr) {
|
||||
copyout(*value, n);
|
||||
copyout(value, n);
|
||||
}
|
||||
r = 0;
|
||||
}
|
||||
return r;
|
||||
} 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");
|
||||
invariant(idx == dest.d.a.num_values);
|
||||
invariant(idx < dest.capacity);
|
||||
XMEMDUP(dest.d.a.values[dest.d.a.num_values++], value);
|
||||
invariant_nonnull(dest);
|
||||
invariant(idx == dest->d.a.num_values);
|
||||
invariant(idx < dest->capacity);
|
||||
XMEMDUP(dest->d.a.values[dest->d.a.num_values++], value);
|
||||
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");
|
||||
invariant_notnull(*value);
|
||||
toku_free(*value);
|
||||
|
|
|
@ -1243,11 +1243,11 @@ static uint32_t recover_get_num_live_txns(RECOVER_ENV renv) {
|
|||
}
|
||||
|
||||
// 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 &extra) {
|
||||
int is_txn_unprepared(const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN *const extra)
|
||||
__attribute__((nonnull(3)));
|
||||
int is_txn_unprepared(const TOKUTXN &txn, const uint32_t UU(index), TOKUTXN *const extra) {
|
||||
if (txn->state != TOKUTXN_PREPARING) {
|
||||
extra = txn;
|
||||
*extra = txn;
|
||||
return -1; // return -1 to get iterator to return
|
||||
}
|
||||
return 0;
|
||||
|
@ -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) {
|
||||
TOKUTXN txn = NULL;
|
||||
TOKUTXN txn = nullptr;
|
||||
int r = toku_txn_manager_iter_over_live_txns<TOKUTXN, is_txn_unprepared>(
|
||||
renv->logger->txn_manager,
|
||||
txn
|
||||
&txn
|
||||
);
|
||||
assert(r == 0 || r == -1);
|
||||
if (txn != NULL) {
|
||||
if (txn != nullptr) {
|
||||
*txnp = txn;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1269,10 +1269,10 @@ static int find_an_unprepared_txn (RECOVER_ENV renv, TOKUTXN *txnp) {
|
|||
}
|
||||
|
||||
// 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 &renv) {
|
||||
renv->prepared_txn_callback(renv->env, txn);
|
||||
int call_prepare_txn_callback_iter(const TOKUTXN &txn, const uint32_t UU(index), RECOVER_ENV *const renv)
|
||||
__attribute__((nonnull(3)));
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1285,7 +1285,7 @@ static void recover_abort_live_txns(RECOVER_ENV renv) {
|
|||
// abort the transaction
|
||||
r = toku_txn_abort_txn(txn, NULL, NULL);
|
||||
assert(r == 0);
|
||||
|
||||
|
||||
// close the transaction
|
||||
toku_txn_close_txn(txn);
|
||||
} else if (r==DB_NOTFOUND) {
|
||||
|
@ -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.
|
||||
int r = toku_txn_manager_iter_over_live_txns<RECOVER_ENV, call_prepare_txn_callback_iter>(
|
||||
renv->logger->txn_manager,
|
||||
renv
|
||||
&renv
|
||||
);
|
||||
assert_zero(r);
|
||||
}
|
||||
|
|
|
@ -417,22 +417,22 @@ done:
|
|||
}
|
||||
|
||||
// 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 &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)
|
||||
__attribute__((nonnull(3)));
|
||||
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;
|
||||
uint32_t idx;
|
||||
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) {
|
||||
goto done;
|
||||
}
|
||||
invariant_zero(r);
|
||||
invariant(tuple->references > 0);
|
||||
if (--tuple->references == 0) {
|
||||
r = referenced_xids.delete_at(idx);
|
||||
r = referenced_xids->delete_at(idx);
|
||||
lazy_assert_zero(r);
|
||||
}
|
||||
done:
|
||||
|
@ -443,7 +443,7 @@ done:
|
|||
static int
|
||||
referenced_xids_note_snapshot_txn_end(TXN_MANAGER mgr, const xid_omt_t &live_root_txn_list) {
|
||||
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);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -73,10 +73,10 @@ uint32_t toku_txn_manager_num_live_txns(TXN_MANAGER txn_manager);
|
|||
|
||||
|
||||
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(
|
||||
TXN_MANAGER txn_manager,
|
||||
iterate_extra_t &v
|
||||
iterate_extra_t *const v
|
||||
)
|
||||
{
|
||||
int r = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue