Commit f2df37d6 authored by John Esmet's avatar John Esmet Committed by John Esmet

FT-93 Add a class for pivot bounds, remove the assumption that pivot

keys must come from a DBT stored in the ftnode by adding
ftnode_pivot_keys::fill_dbt()
parent 211027e5
...@@ -209,7 +209,7 @@ toku_pin_ftnode_for_query( ...@@ -209,7 +209,7 @@ toku_pin_ftnode_for_query(
uint32_t fullhash, uint32_t fullhash,
UNLOCKERS unlockers, UNLOCKERS unlockers,
ANCESTORS ancestors, ANCESTORS ancestors,
const PIVOT_BOUNDS bounds, const pivot_bounds &bounds,
FTNODE_FETCH_EXTRA bfe, FTNODE_FETCH_EXTRA bfe,
bool apply_ancestor_messages, // this bool is probably temporary, for #3972, once we know how range query estimates work, will revisit this bool apply_ancestor_messages, // this bool is probably temporary, for #3972, once we know how range query estimates work, will revisit this
FTNODE *node_p, FTNODE *node_p,
......
...@@ -147,7 +147,7 @@ toku_pin_ftnode_for_query( ...@@ -147,7 +147,7 @@ toku_pin_ftnode_for_query(
uint32_t fullhash, uint32_t fullhash,
UNLOCKERS unlockers, UNLOCKERS unlockers,
ANCESTORS ancestors, ANCESTORS ancestors,
const PIVOT_BOUNDS pbounds, const pivot_bounds &bounds,
FTNODE_FETCH_EXTRA bfe, FTNODE_FETCH_EXTRA bfe,
bool apply_ancestor_messages, // this bool is probably temporary, for #3972, once we know how range query estimates work, will revisit this bool apply_ancestor_messages, // this bool is probably temporary, for #3972, once we know how range query estimates work, will revisit this
FTNODE *node_p, FTNODE *node_p,
......
...@@ -468,7 +468,7 @@ ct_maybe_merge_child(struct flusher_advice *fa, ...@@ -468,7 +468,7 @@ ct_maybe_merge_child(struct flusher_advice *fa,
ctme.is_last_child = false; ctme.is_last_child = false;
pivot_to_save = childnum; pivot_to_save = childnum;
} }
toku_clone_dbt(&ctme.target_key, *parent->pivotkeys.get_pivot(pivot_to_save)); toku_clone_dbt(&ctme.target_key, parent->pivotkeys.get_pivot(pivot_to_save));
// at this point, ctme is properly setup, now we can do the merge // at this point, ctme is properly setup, now we can do the merge
struct flusher_advice new_fa; struct flusher_advice new_fa;
...@@ -580,7 +580,7 @@ handle_split_of_child( ...@@ -580,7 +580,7 @@ handle_split_of_child(
if (toku_ft_debug_mode) { if (toku_ft_debug_mode) {
printf("%s:%d Child %d splitting on %s\n", __FILE__, __LINE__, childnum, (char*)splitk->data); printf("%s:%d Child %d splitting on %s\n", __FILE__, __LINE__, childnum, (char*)splitk->data);
printf("%s:%d oldsplitkeys:", __FILE__, __LINE__); printf("%s:%d oldsplitkeys:", __FILE__, __LINE__);
for(int i = 0; i < node->n_children - 1; i++) printf(" %s", (char *) node->pivotkeys.get_pivot(i)->data); for(int i = 0; i < node->n_children - 1; i++) printf(" %s", (char *) node->pivotkeys.get_pivot(i).data);
printf("\n"); printf("\n");
} }
) )
...@@ -631,7 +631,7 @@ handle_split_of_child( ...@@ -631,7 +631,7 @@ handle_split_of_child(
WHEN_NOT_GCOV( WHEN_NOT_GCOV(
if (toku_ft_debug_mode) { if (toku_ft_debug_mode) {
printf("%s:%d splitkeys:", __FILE__, __LINE__); printf("%s:%d splitkeys:", __FILE__, __LINE__);
for (int i = 0; i < node->n_children - 2; i++) printf(" %s", (char *) node->pivotkeys.get_pivot(i)->data); for (int i = 0; i < node->n_children - 2; i++) printf(" %s", (char *) node->pivotkeys.get_pivot(i).data);
printf("\n"); printf("\n");
} }
) )
...@@ -937,7 +937,7 @@ ftleaf_split( ...@@ -937,7 +937,7 @@ ftleaf_split(
int split_idx = num_left_bns - (split_on_boundary ? 0 : 1); int split_idx = num_left_bns - (split_on_boundary ? 0 : 1);
node->pivotkeys.split_at(split_idx, &B->pivotkeys); node->pivotkeys.split_at(split_idx, &B->pivotkeys);
if (split_on_boundary && num_left_bns < node->n_children && splitk) { if (split_on_boundary && num_left_bns < node->n_children && splitk) {
toku_copyref_dbt(splitk, *node->pivotkeys.get_pivot(num_left_bns - 1)); toku_copyref_dbt(splitk, node->pivotkeys.get_pivot(num_left_bns - 1));
} else if (splitk) { } else if (splitk) {
bn_data* bd = BLB_DATA(node, num_left_bns - 1); bn_data* bd = BLB_DATA(node, num_left_bns - 1);
uint32_t keylen; uint32_t keylen;
...@@ -997,7 +997,7 @@ ft_nonleaf_split( ...@@ -997,7 +997,7 @@ ft_nonleaf_split(
// the split key for our parent is the rightmost pivot key in node // the split key for our parent is the rightmost pivot key in node
node->pivotkeys.split_at(n_children_in_a, &B->pivotkeys); node->pivotkeys.split_at(n_children_in_a, &B->pivotkeys);
toku_clone_dbt(splitk, *node->pivotkeys.get_pivot(n_children_in_a - 1)); toku_clone_dbt(splitk, node->pivotkeys.get_pivot(n_children_in_a - 1));
node->pivotkeys.delete_at(n_children_in_a - 1); node->pivotkeys.delete_at(n_children_in_a - 1);
node->n_children = n_children_in_a; node->n_children = n_children_in_a;
...@@ -1408,8 +1408,8 @@ ft_merge_child( ...@@ -1408,8 +1408,8 @@ ft_merge_child(
{ {
DBT splitk; DBT splitk;
toku_init_dbt(&splitk); toku_init_dbt(&splitk);
const DBT *old_split_key = node->pivotkeys.get_pivot(childnuma); const DBT old_split_key = node->pivotkeys.get_pivot(childnuma);
maybe_merge_pinned_nodes(node, old_split_key, childa, childb, &did_merge, &did_rebalance, &splitk, ft->h->nodesize); maybe_merge_pinned_nodes(node, &old_split_key, childa, childb, &did_merge, &did_rebalance, &splitk, ft->h->nodesize);
//toku_verify_estimates(t,childa); //toku_verify_estimates(t,childa);
// the tree did react if a merge (did_merge) or rebalance (new spkit key) occurred // the tree did react if a merge (did_merge) or rebalance (new spkit key) occurred
*did_react = (bool)(did_merge || did_rebalance); *did_react = (bool)(did_merge || did_rebalance);
......
...@@ -199,7 +199,7 @@ hot_update_flusher_keys(FTNODE parent, ...@@ -199,7 +199,7 @@ hot_update_flusher_keys(FTNODE parent,
// child node. // child node.
if (childnum < (parent->n_children - 1)) { if (childnum < (parent->n_children - 1)) {
toku_destroy_dbt(&flusher->max_current_key); toku_destroy_dbt(&flusher->max_current_key);
toku_clone_dbt(&flusher->max_current_key, *parent->pivotkeys.get_pivot(childnum)); toku_clone_dbt(&flusher->max_current_key, parent->pivotkeys.get_pivot(childnum));
} }
} }
......
...@@ -461,15 +461,26 @@ void fill_bfe_for_prefetch(struct ftnode_fetch_extra *bfe, FT ft, struct ft_curs ...@@ -461,15 +461,26 @@ void fill_bfe_for_prefetch(struct ftnode_fetch_extra *bfe, FT ft, struct ft_curs
void destroy_bfe_for_prefetch(struct ftnode_fetch_extra *bfe); void destroy_bfe_for_prefetch(struct ftnode_fetch_extra *bfe);
struct pivot_bounds { class pivot_bounds {
const DBT * const lower_bound_exclusive; public:
const DBT * const upper_bound_inclusive; // NULL to indicate negative or positive infinity (which are in practice exclusive since there are now transfinite keys in messages). pivot_bounds(const DBT &lbe_dbt, const DBT &ubi_dbt);
};
typedef struct pivot_bounds const * const PIVOT_BOUNDS; pivot_bounds next_bounds(FTNODE node, int childnum) const;
const DBT *lbe() const;
const DBT *ubi() const;
const DBT *prepivotkey (FTNODE node, int childnum, const DBT * const lower_bound_exclusive); static pivot_bounds infinite_bounds();
const DBT *postpivotkey (FTNODE node, int childnum, const DBT * const upper_bound_inclusive);
struct pivot_bounds next_pivot_keys (FTNODE node, int childnum, struct pivot_bounds const * const old_pb); private:
DBT _prepivotkey(FTNODE node, int childnum, const DBT &lbe_dbt) const;
DBT _postpivotkey(FTNODE node, int childnum, const DBT &ubi_dbt) const;
// if toku_dbt_is_empty() is true for either bound, then it represents
// negative or positive infinity (which are exclusive in practice)
const DBT _lower_bound_exclusive;
const DBT _upper_bound_inclusive;
};
bool bool
toku_bfe_wants_child_available (struct ftnode_fetch_extra* bfe, int childnum); toku_bfe_wants_child_available (struct ftnode_fetch_extra* bfe, int childnum);
......
This diff is collapsed.
...@@ -158,7 +158,8 @@ get_ith_key_dbt (BASEMENTNODE bn, int i) { ...@@ -158,7 +158,8 @@ get_ith_key_dbt (BASEMENTNODE bn, int i) {
#define VERIFY_ASSERTION(predicate, i, string) ({ \ #define VERIFY_ASSERTION(predicate, i, string) ({ \
if(!(predicate)) { \ if(!(predicate)) { \
if (verbose) { \ (void) verbose; \
if (true) { \
fprintf(stderr, "%s:%d: Looking at child %d of block %" PRId64 ": %s\n", __FILE__, __LINE__, i, blocknum.b, string); \ fprintf(stderr, "%s:%d: Looking at child %d of block %" PRId64 ": %s\n", __FILE__, __LINE__, i, blocknum.b, string); \
} \ } \
result = TOKUDB_NEEDS_REPAIR; \ result = TOKUDB_NEEDS_REPAIR; \
...@@ -398,24 +399,27 @@ toku_verify_ftnode_internal(FT_HANDLE ft_handle, ...@@ -398,24 +399,27 @@ toku_verify_ftnode_internal(FT_HANDLE ft_handle,
} }
// Verify that all the pivot keys are in order. // Verify that all the pivot keys are in order.
for (int i = 0; i < node->n_children-2; i++) { for (int i = 0; i < node->n_children-2; i++) {
int compare = compare_pairs(ft_handle, node->pivotkeys.get_pivot(i), node->pivotkeys.get_pivot(i + 1)); DBT x, y;
int compare = compare_pairs(ft_handle, node->pivotkeys.fill_pivot(i, &x), node->pivotkeys.fill_pivot(i + 1, &y));
VERIFY_ASSERTION(compare < 0, i, "Value is >= the next value"); VERIFY_ASSERTION(compare < 0, i, "Value is >= the next value");
} }
// Verify that all the pivot keys are lesser_pivot < pivot <= greatereq_pivot // Verify that all the pivot keys are lesser_pivot < pivot <= greatereq_pivot
for (int i = 0; i < node->n_children-1; i++) { for (int i = 0; i < node->n_children-1; i++) {
DBT x;
if (lesser_pivot) { if (lesser_pivot) {
int compare = compare_pairs(ft_handle, lesser_pivot, node->pivotkeys.get_pivot(i)); int compare = compare_pairs(ft_handle, lesser_pivot, node->pivotkeys.fill_pivot(i, &x));
VERIFY_ASSERTION(compare < 0, i, "Pivot is >= the lower-bound pivot"); VERIFY_ASSERTION(compare < 0, i, "Pivot is >= the lower-bound pivot");
} }
if (greatereq_pivot) { if (greatereq_pivot) {
int compare = compare_pairs(ft_handle, greatereq_pivot, node->pivotkeys.get_pivot(i)); int compare = compare_pairs(ft_handle, greatereq_pivot, node->pivotkeys.fill_pivot(i, &x));
VERIFY_ASSERTION(compare >= 0, i, "Pivot is < the upper-bound pivot"); VERIFY_ASSERTION(compare >= 0, i, "Pivot is < the upper-bound pivot");
} }
} }
for (int i = 0; i < node->n_children; i++) { for (int i = 0; i < node->n_children; i++) {
const DBT *curr_less_pivot = (i==0) ? lesser_pivot : node->pivotkeys.get_pivot(i - 1); DBT x, y;
const DBT *curr_geq_pivot = (i==node->n_children-1) ? greatereq_pivot : node->pivotkeys.get_pivot(i); const DBT *curr_less_pivot = (i==0) ? lesser_pivot : node->pivotkeys.fill_pivot(i - 1, &x);
const DBT *curr_geq_pivot = (i==node->n_children-1) ? greatereq_pivot : node->pivotkeys.fill_pivot(i, &y);
if (node->height > 0) { if (node->height > 0) {
NONLEAF_CHILDINFO bnc = BNC(node, i); NONLEAF_CHILDINFO bnc = BNC(node, i);
// Verify that messages in the buffers are in the right place. // Verify that messages in the buffers are in the right place.
...@@ -518,14 +522,15 @@ toku_verify_ftnode (FT_HANDLE ft_handle, ...@@ -518,14 +522,15 @@ toku_verify_ftnode (FT_HANDLE ft_handle,
for (int i = 0; i < node->n_children; i++) { for (int i = 0; i < node->n_children; i++) {
FTNODE child_node; FTNODE child_node;
toku_get_node_for_verify(BP_BLOCKNUM(node, i), ft_handle, &child_node); toku_get_node_for_verify(BP_BLOCKNUM(node, i), ft_handle, &child_node);
DBT x, y;
int r = toku_verify_ftnode(ft_handle, rootmsn, int r = toku_verify_ftnode(ft_handle, rootmsn,
(toku_bnc_n_entries(BNC(node, i)) > 0 (toku_bnc_n_entries(BNC(node, i)) > 0
? this_msn ? this_msn
: parentmsn_with_messages), : parentmsn_with_messages),
messages_exist_above || toku_bnc_n_entries(BNC(node, i)) > 0, messages_exist_above || toku_bnc_n_entries(BNC(node, i)) > 0,
child_node, node->height-1, child_node, node->height-1,
(i==0) ? lesser_pivot : node->pivotkeys.get_pivot(i - 1), (i==0) ? lesser_pivot : node->pivotkeys.fill_pivot(i - 1, &x),
(i==node->n_children-1) ? greatereq_pivot : node->pivotkeys.get_pivot(i), (i==node->n_children-1) ? greatereq_pivot : node->pivotkeys.fill_pivot(i, &y),
progress_callback, progress_extra, progress_callback, progress_extra,
recurse, verbose, keep_going_on_failure); recurse, verbose, keep_going_on_failure);
if (r) { if (r) {
......
This diff is collapsed.
...@@ -106,7 +106,7 @@ public: ...@@ -106,7 +106,7 @@ public:
void create_empty(); void create_empty();
// effect: create pivot keys by copying the given DBT array // effect: create pivot keys by copying the given DBT array
void create_from_dbts(const DBT *keys, int num_pivots); void create_from_dbts(const DBT *keys, int n);
// effect: create pivot keys as a clone of an existing set of pivotkeys // effect: create pivot keys as a clone of an existing set of pivotkeys
void create_from_pivot_keys(const ftnode_pivot_keys &pivotkeys); void create_from_pivot_keys(const ftnode_pivot_keys &pivotkeys);
...@@ -114,10 +114,14 @@ public: ...@@ -114,10 +114,14 @@ public:
void destroy(); void destroy();
// effect: deserialize pivot keys previously serialized by serialize_to_wbuf() // effect: deserialize pivot keys previously serialized by serialize_to_wbuf()
void deserialize_from_rbuf(struct rbuf *rb, int num_pivots); void deserialize_from_rbuf(struct rbuf *rb, int n);
// returns: unowned DBT representing the i'th pivot key // returns: unowned DBT representing the i'th pivot key
const DBT *get_pivot(int i) const; DBT get_pivot(int i) const;
// effect: fills a DBT with the i'th pivot key
// returns: the given dbt
DBT *fill_pivot(int i, DBT *dbt) const;
// effect: insert a pivot into the i'th position, shifting others to the right // effect: insert a pivot into the i'th position, shifting others to the right
void insert_at(const DBT *key, int i); void insert_at(const DBT *key, int i);
...@@ -136,21 +140,59 @@ public: ...@@ -136,21 +140,59 @@ public:
// requires: *other is empty (size == 0) // requires: *other is empty (size == 0)
void split_at(int i, ftnode_pivot_keys *other); void split_at(int i, ftnode_pivot_keys *other);
// effect: serialize pivot keys to a wbuf
// requires: wbuf has at least ftnode_pivot_keys::total_size() bytes available
void serialize_to_wbuf(struct wbuf *wb) const;
int num_pivots() const; int num_pivots() const;
// return: the sum of the keys sizes of each pivot // return: the sum of the keys sizes of each pivot
size_t total_size() const; size_t total_size() const;
// effect: serialize pivot keys to a wbuf
// requires: wbuf has at least ftnode_pivot_keys::total_size() bytes available
void serialize_to_wbuf(struct wbuf *wb) const;
private: private:
// adds/destroys keys at a certain index, maintaining _total_size, but not _num_pivots // effect: create pivot keys, in fixed key format, by copying the given key array
void _add_key(const DBT *key, int i); void _create_from_fixed_keys(const char *fixedkeys, size_t fixed_keylen, int n);
void _destroy_key(int i);
char *_fixed_key(int i) const {
return &_fixed_keys[i * _fixed_keylen];
}
bool _fixed_format() const {
return _fixed_keys != nullptr;
}
void sanity_check() const;
void _insert_at_dbt(const DBT *key, int i);
void _append_dbt(const ftnode_pivot_keys &pivotkeys);
void _replace_at_dbt(const DBT *key, int i);
void _delete_at_dbt(int i);
void _split_at_dbt(int i, ftnode_pivot_keys *other);
void _insert_at_fixed(const DBT *key, int i);
void _append_fixed(const ftnode_pivot_keys &pivotkeys);
void _replace_at_fixed(const DBT *key, int i);
void _delete_at_fixed(int i);
void _split_at_fixed(int i, ftnode_pivot_keys *other);
// adds/destroys keys at a certain index (in dbt format),
// maintaining _total_size, but not _num_pivots
void _add_key_dbt(const DBT *key, int i);
void _destroy_key_dbt(int i);
// conversions to and from packed key array format
void _convert_to_dbt_format();
void _convert_to_fixed_format();
// If every key is _fixed_keylen long, then _fixed_key is a
// packed array of keys..
char *_fixed_keys;
size_t _fixed_keylen;
// ..otherwise _fixed_keys is null and we store an array of dbts,
// each representing a key. this is simpler but less cache-efficient.
DBT *_dbt_keys;
DBT *_keys;
int _num_pivots; int _num_pivots;
size_t _total_size; size_t _total_size;
}; };
...@@ -482,12 +524,13 @@ void toku_ft_bnc_move_messages_to_stale(FT ft, NONLEAF_CHILDINFO bnc); ...@@ -482,12 +524,13 @@ void toku_ft_bnc_move_messages_to_stale(FT ft, NONLEAF_CHILDINFO bnc);
void toku_move_ftnode_messages_to_stale(FT ft, FTNODE node); void toku_move_ftnode_messages_to_stale(FT ft, FTNODE node);
// TODO: Should ft_handle just be FT? // TODO: Should ft_handle just be FT?
class pivot_bounds;
void toku_apply_ancestors_messages_to_node(FT_HANDLE t, FTNODE node, ANCESTORS ancestors, void toku_apply_ancestors_messages_to_node(FT_HANDLE t, FTNODE node, ANCESTORS ancestors,
struct pivot_bounds const *const bounds, const pivot_bounds &bounds,
bool *msgs_applied, int child_to_read); bool *msgs_applied, int child_to_read);
bool toku_ft_leaf_needs_ancestors_messages(FT ft, FTNODE node, ANCESTORS ancestors, bool toku_ft_leaf_needs_ancestors_messages(FT ft, FTNODE node, ANCESTORS ancestors,
struct pivot_bounds const *const bounds, const pivot_bounds &bounds,
MSN *const max_msn_in_path, int child_to_read); MSN *const max_msn_in_path, int child_to_read);
void toku_ft_bn_update_max_msn(FTNODE node, MSN max_msn_applied, int child_to_read); void toku_ft_bn_update_max_msn(FTNODE node, MSN max_msn_applied, int child_to_read);
......
...@@ -360,7 +360,7 @@ test_serialize_leaf_check_msn(enum ftnode_verify_type bft, bool do_clone) { ...@@ -360,7 +360,7 @@ test_serialize_leaf_check_msn(enum ftnode_verify_type bft, bool do_clone) {
assert(leafentry_memsize(curr_le) == leafentry_memsize(elts[last_i].le)); assert(leafentry_memsize(curr_le) == leafentry_memsize(elts[last_i].le));
assert(memcmp(curr_le, elts[last_i].le, leafentry_memsize(curr_le)) == 0); assert(memcmp(curr_le, elts[last_i].le, leafentry_memsize(curr_le)) == 0);
if (bn < npartitions-1) { if (bn < npartitions-1) {
assert(strcmp((char*)dn->pivotkeys.get_pivot(bn)->data, elts[last_i].keyp) <= 0); assert(strcmp((char*)dn->pivotkeys.get_pivot(bn).data, elts[last_i].keyp) <= 0);
} }
// TODO for later, get a key comparison here as well // TODO for later, get a key comparison here as well
last_i++; last_i++;
...@@ -495,7 +495,7 @@ test_serialize_leaf_with_large_pivots(enum ftnode_verify_type bft, bool do_clone ...@@ -495,7 +495,7 @@ test_serialize_leaf_with_large_pivots(enum ftnode_verify_type bft, bool do_clone
assert(leafentry_memsize(curr_le) == leafentry_memsize(les[last_i].le)); assert(leafentry_memsize(curr_le) == leafentry_memsize(les[last_i].le));
assert(memcmp(curr_le, les[last_i].le, leafentry_memsize(curr_le)) == 0); assert(memcmp(curr_le, les[last_i].le, leafentry_memsize(curr_le)) == 0);
if (bn < npartitions-1) { if (bn < npartitions-1) {
assert(strcmp((char*)dn->pivotkeys.get_pivot(bn)->data, les[last_i].keyp) <= 0); assert(strcmp((char*)dn->pivotkeys.get_pivot(bn).data, les[last_i].keyp) <= 0);
} }
// TODO for later, get a key comparison here as well // TODO for later, get a key comparison here as well
last_i++; last_i++;
...@@ -618,7 +618,7 @@ test_serialize_leaf_with_many_rows(enum ftnode_verify_type bft, bool do_clone) { ...@@ -618,7 +618,7 @@ test_serialize_leaf_with_many_rows(enum ftnode_verify_type bft, bool do_clone) {
assert(leafentry_memsize(curr_le) == leafentry_memsize(les[last_i].le)); assert(leafentry_memsize(curr_le) == leafentry_memsize(les[last_i].le));
assert(memcmp(curr_le, les[last_i].le, leafentry_memsize(curr_le)) == 0); assert(memcmp(curr_le, les[last_i].le, leafentry_memsize(curr_le)) == 0);
if (bn < npartitions-1) { if (bn < npartitions-1) {
uint32_t *CAST_FROM_VOIDP(pivot, dn->pivotkeys.get_pivot(bn)->data); uint32_t *CAST_FROM_VOIDP(pivot, dn->pivotkeys.get_pivot(bn).data);
void* tmp = les[last_i].keyp; void* tmp = les[last_i].keyp;
uint32_t *CAST_FROM_VOIDP(item, tmp); uint32_t *CAST_FROM_VOIDP(item, tmp);
assert(*pivot >= *item); assert(*pivot >= *item);
...@@ -759,7 +759,7 @@ test_serialize_leaf_with_large_rows(enum ftnode_verify_type bft, bool do_clone) ...@@ -759,7 +759,7 @@ test_serialize_leaf_with_large_rows(enum ftnode_verify_type bft, bool do_clone)
assert(leafentry_memsize(curr_le) == leafentry_memsize(les[last_i].le)); assert(leafentry_memsize(curr_le) == leafentry_memsize(les[last_i].le));
assert(memcmp(curr_le, les[last_i].le, leafentry_memsize(curr_le)) == 0); assert(memcmp(curr_le, les[last_i].le, leafentry_memsize(curr_le)) == 0);
if (bn < npartitions-1) { if (bn < npartitions-1) {
assert(strcmp((char*)dn->pivotkeys.get_pivot(bn)->data, (char*)(les[last_i].keyp)) <= 0); assert(strcmp((char*)dn->pivotkeys.get_pivot(bn).data, (char*)(les[last_i].keyp)) <= 0);
} }
// TODO for later, get a key comparison here as well // TODO for later, get a key comparison here as well
last_i++; last_i++;
...@@ -888,7 +888,7 @@ test_serialize_leaf_with_empty_basement_nodes(enum ftnode_verify_type bft, bool ...@@ -888,7 +888,7 @@ test_serialize_leaf_with_empty_basement_nodes(enum ftnode_verify_type bft, bool
assert(leafentry_memsize(curr_le) == leafentry_memsize(elts[last_i].le)); assert(leafentry_memsize(curr_le) == leafentry_memsize(elts[last_i].le));
assert(memcmp(curr_le, elts[last_i].le, leafentry_memsize(curr_le)) == 0); assert(memcmp(curr_le, elts[last_i].le, leafentry_memsize(curr_le)) == 0);
if (bn < npartitions-1) { if (bn < npartitions-1) {
assert(strcmp((char*)dn->pivotkeys.get_pivot(bn)->data, (char*)(elts[last_i].keyp)) <= 0); assert(strcmp((char*)dn->pivotkeys.get_pivot(bn).data, (char*)(elts[last_i].keyp)) <= 0);
} }
// TODO for later, get a key comparison here as well // TODO for later, get a key comparison here as well
last_i++; last_i++;
...@@ -1107,8 +1107,8 @@ test_serialize_nonleaf(enum ftnode_verify_type bft, bool do_clone) { ...@@ -1107,8 +1107,8 @@ test_serialize_nonleaf(enum ftnode_verify_type bft, bool do_clone) {
assert(dn->layout_version_read_from_disk ==FT_LAYOUT_VERSION); assert(dn->layout_version_read_from_disk ==FT_LAYOUT_VERSION);
assert(dn->height == 1); assert(dn->height == 1);
assert(dn->n_children==2); assert(dn->n_children==2);
assert(strcmp((char*)dn->pivotkeys.get_pivot(0)->data, "hello")==0); assert(strcmp((char*)dn->pivotkeys.get_pivot(0).data, "hello")==0);
assert(dn->pivotkeys.get_pivot(0)->size==6); assert(dn->pivotkeys.get_pivot(0).size==6);
assert(BP_BLOCKNUM(dn,0).b==30); assert(BP_BLOCKNUM(dn,0).b==30);
assert(BP_BLOCKNUM(dn,1).b==35); assert(BP_BLOCKNUM(dn,1).b==35);
......
...@@ -737,9 +737,8 @@ flush_to_leaf(FT_HANDLE t, bool make_leaf_up_to_date, bool use_flush) { ...@@ -737,9 +737,8 @@ flush_to_leaf(FT_HANDLE t, bool make_leaf_up_to_date, bool use_flush) {
BP_STATE(parentnode, 0) = PT_AVAIL; BP_STATE(parentnode, 0) = PT_AVAIL;
parentnode->max_msn_applied_to_node_on_disk = max_parent_msn; parentnode->max_msn_applied_to_node_on_disk = max_parent_msn;
struct ancestors ancestors = { .node = parentnode, .childnum = 0, .next = NULL }; struct ancestors ancestors = { .node = parentnode, .childnum = 0, .next = NULL };
const struct pivot_bounds infinite_bounds = { .lower_bound_exclusive = NULL, .upper_bound_inclusive = NULL };
bool msgs_applied; bool msgs_applied;
toku_apply_ancestors_messages_to_node(t, child, &ancestors, &infinite_bounds, &msgs_applied, -1); toku_apply_ancestors_messages_to_node(t, child, &ancestors, pivot_bounds::infinite_bounds(), &msgs_applied, -1);
struct checkit_fn { struct checkit_fn {
int operator()(FT_MSG UU(msg), bool is_fresh) { int operator()(FT_MSG UU(msg), bool is_fresh) {
...@@ -962,12 +961,11 @@ flush_to_leaf_with_keyrange(FT_HANDLE t, bool make_leaf_up_to_date) { ...@@ -962,12 +961,11 @@ flush_to_leaf_with_keyrange(FT_HANDLE t, bool make_leaf_up_to_date) {
parentnode->max_msn_applied_to_node_on_disk = max_parent_msn; parentnode->max_msn_applied_to_node_on_disk = max_parent_msn;
struct ancestors ancestors = { .node = parentnode, .childnum = 0, .next = NULL }; struct ancestors ancestors = { .node = parentnode, .childnum = 0, .next = NULL };
DBT lbe, ubi; DBT lbe, ubi;
const struct pivot_bounds bounds = { toku_init_dbt(&lbe);
.lower_bound_exclusive = toku_init_dbt(&lbe), toku_clone_dbt(&ubi, childkeys[7]);
.upper_bound_inclusive = toku_clone_dbt(&ubi, childkeys[7]) const pivot_bounds bounds(lbe, ubi);
};
bool msgs_applied; bool msgs_applied;
toku_apply_ancestors_messages_to_node(t, child, &ancestors, &bounds, &msgs_applied, -1); toku_apply_ancestors_messages_to_node(t, child, &ancestors, bounds, &msgs_applied, -1);
struct checkit_fn { struct checkit_fn {
DBT *childkeys; DBT *childkeys;
...@@ -1162,9 +1160,8 @@ compare_apply_and_flush(FT_HANDLE t, bool make_leaf_up_to_date) { ...@@ -1162,9 +1160,8 @@ compare_apply_and_flush(FT_HANDLE t, bool make_leaf_up_to_date) {
BP_STATE(parentnode, 0) = PT_AVAIL; BP_STATE(parentnode, 0) = PT_AVAIL;
parentnode->max_msn_applied_to_node_on_disk = max_parent_msn; parentnode->max_msn_applied_to_node_on_disk = max_parent_msn;
struct ancestors ancestors = { .node = parentnode, .childnum = 0, .next = NULL }; struct ancestors ancestors = { .node = parentnode, .childnum = 0, .next = NULL };
const struct pivot_bounds infinite_bounds = { .lower_bound_exclusive = NULL, .upper_bound_inclusive = NULL };
bool msgs_applied; bool msgs_applied;
toku_apply_ancestors_messages_to_node(t, child2, &ancestors, &infinite_bounds, &msgs_applied, -1); toku_apply_ancestors_messages_to_node(t, child2, &ancestors, pivot_bounds::infinite_bounds(), &msgs_applied, -1);
struct checkit_fn { struct checkit_fn {
int operator()(FT_MSG UU(msg), bool is_fresh) { int operator()(FT_MSG UU(msg), bool is_fresh) {
......
...@@ -260,11 +260,11 @@ static void dump_node(int fd, BLOCKNUM blocknum, FT ft) { ...@@ -260,11 +260,11 @@ static void dump_node(int fd, BLOCKNUM blocknum, FT ft) {
printf(" pivots:\n"); printf(" pivots:\n");
for (int i=0; i<n->n_children-1; i++) { for (int i=0; i<n->n_children-1; i++) {
const DBT *piv = n->pivotkeys.get_pivot(i); const DBT piv = n->pivotkeys.get_pivot(i);
printf(" pivot %2d:", i); printf(" pivot %2d:", i);
if (n->flags) if (n->flags)
printf(" flags=%x ", n->flags); printf(" flags=%x ", n->flags);
print_item(piv->data, piv->size); print_item(piv.data, piv.size);
printf("\n"); printf("\n");
} }
printf(" children:\n"); printf(" children:\n");
......
...@@ -317,6 +317,12 @@ bool toku_dbt_is_infinite(const DBT *dbt) { ...@@ -317,6 +317,12 @@ bool toku_dbt_is_infinite(const DBT *dbt) {
return dbt == toku_dbt_positive_infinity() || dbt == toku_dbt_negative_infinity(); return dbt == toku_dbt_positive_infinity() || dbt == toku_dbt_negative_infinity();
} }
bool toku_dbt_is_empty(const DBT *dbt) {
// can't have a null data field with a non-zero size
paranoid_invariant(dbt->data != nullptr || dbt->size == 0);
return dbt->data == nullptr;
}
int toku_dbt_infinite_compare(const DBT *a, const DBT *b) { int toku_dbt_infinite_compare(const DBT *a, const DBT *b) {
if (a == b) { if (a == b) {
return 0; return 0;
......
...@@ -129,6 +129,9 @@ const DBT *toku_dbt_negative_infinity(void); ...@@ -129,6 +129,9 @@ const DBT *toku_dbt_negative_infinity(void);
// returns: true if the given dbt is either positive or negative infinity // returns: true if the given dbt is either positive or negative infinity
bool toku_dbt_is_infinite(const DBT *dbt); bool toku_dbt_is_infinite(const DBT *dbt);
// returns: true if the given dbt has no data (ie: dbt->data == nullptr)
bool toku_dbt_is_empty(const DBT *dbt);
// effect: compares two potentially infinity-valued dbts // effect: compares two potentially infinity-valued dbts
// requires: at least one is infinite (assert otherwise) // requires: at least one is infinite (assert otherwise)
int toku_dbt_infinite_compare(const DBT *a, const DBT *b); int toku_dbt_infinite_compare(const DBT *a, const DBT *b);
......
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