mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge {DS-DRR improvements:code cleanup} into MWL#128+DS-MRR tree
This commit is contained in:
@ -282,8 +282,20 @@ scan_it_again:
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Mrr_*_reader classes (building blocks for DS-MRR)
|
||||
***************************************************************************/
|
||||
|
||||
/***** MRR_impl classes ****************************************************/
|
||||
int Mrr_simple_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
void *seq_init_param, uint n_ranges,
|
||||
uint mode, Buffer_manager *buf_manager_arg)
|
||||
{
|
||||
HANDLER_BUFFER no_buffer = {NULL, NULL, NULL};
|
||||
h= h_arg;
|
||||
res= 0;
|
||||
return h->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
|
||||
mode, &no_buffer);
|
||||
}
|
||||
|
||||
int Mrr_simple_index_reader::get_next(char **range_info)
|
||||
{
|
||||
@ -297,44 +309,35 @@ int Mrr_simple_index_reader::get_next(char **range_info)
|
||||
return res;
|
||||
}
|
||||
|
||||
int Mrr_simple_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
void *seq_init_param, uint n_ranges,
|
||||
uint mode, Buffer_manager *buf_manager_arg)
|
||||
{
|
||||
HANDLER_BUFFER no_buffer = {NULL, NULL, NULL};
|
||||
h= h_arg;
|
||||
res= 0;
|
||||
return h->handler::multi_range_read_init(seq_funcs, seq_init_param, n_ranges,
|
||||
mode, &no_buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
DS-MRR/CPK: multi_range_read_next() function
|
||||
|
||||
@param range_info OUT identifier of range that the returned record belongs to
|
||||
@brief Get next index record
|
||||
|
||||
@param range_info OUT identifier of range that the returned record belongs to
|
||||
|
||||
@note
|
||||
This function walks over key buffer and does index reads, i.e. it produces
|
||||
{current_record, range_id} pairs.
|
||||
|
||||
The function has the same call contract like multi_range_read_next()'s.
|
||||
|
||||
We actually iterate over nested sequences:
|
||||
- a disjoint sequence of index ranges
|
||||
- each range has multiple records
|
||||
- each record goes into multiple identical ranges.
|
||||
- an ordered sequence of groups of identical keys
|
||||
- each key group has key value, which has multiple matching records
|
||||
- thus, each record matches all members of the key group
|
||||
|
||||
@retval 0 OK, next record was successfully read
|
||||
@retval HA_ERR_END_OF_FILE End of records
|
||||
@retval Other Some other error
|
||||
*/
|
||||
|
||||
int Mrr_ordered_index_reader::get_next(char **range_info_arg)
|
||||
int Mrr_ordered_index_reader::get_next(char **range_info)
|
||||
{
|
||||
DBUG_ENTER("Mrr_ordered_index_reader::get_next");
|
||||
|
||||
if (!know_key_tuple_params) /* We're in startup phase */
|
||||
if (!know_key_tuple_params)
|
||||
{
|
||||
/*
|
||||
We're at the very start, haven't filled the buffer or even know what
|
||||
will be there. Force the caller to call refill_buffer():
|
||||
*/
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -355,24 +358,8 @@ int Mrr_ordered_index_reader::get_next(char **range_info_arg)
|
||||
{
|
||||
if (key_buffer->is_empty())
|
||||
{
|
||||
/*if (auto_refill)
|
||||
{
|
||||
int res;
|
||||
if ((res= refill_buffer()))
|
||||
DBUG_RETURN(res);
|
||||
if (key_buffer->is_empty())
|
||||
{
|
||||
index_scan_eof= TRUE;
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
/* Buffer refills are managed by somebody else for us */
|
||||
index_scan_eof= TRUE;
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
}
|
||||
index_scan_eof= TRUE;
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
}
|
||||
}
|
||||
scanning_key_val_iter= TRUE;
|
||||
@ -390,24 +377,21 @@ int Mrr_ordered_index_reader::get_next(char **range_info_arg)
|
||||
/* Go get another (record, range_id) combination */
|
||||
} /* while */
|
||||
|
||||
memcpy(range_info_arg, cur_range_info, sizeof(void*));
|
||||
memcpy(range_info, cur_range_info, sizeof(void*));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
DS-MRR/CPK: Fill the buffer with (lookup_tuple, range_id) pairs and sort
|
||||
|
||||
Enumerate the input range (=key) sequence, fill the key buffer with
|
||||
(lookup_key, range_id) pairs and sort it.
|
||||
|
||||
When this function returns, either
|
||||
- key buffer is non-empty, or
|
||||
- key buffer is empty and source range sequence is exhausted
|
||||
|
||||
Fill the buffer with (lookup_tuple, range_id) pairs and sort
|
||||
|
||||
@note
|
||||
dsmrr_eof is set to indicate whether we've exhausted the list of ranges
|
||||
we're scanning.
|
||||
We don't know lookup_tuple before we get the first key from
|
||||
mrr_funcs.get_next(). Not knowing tuple length means we can't setup the
|
||||
key buffer (in particular, which part of the buffer space it should occupy
|
||||
when we have both key and rowid buffers). This problem is solved by having
|
||||
know_key_tuple_params variabe, and buf_manager, which we ask to set/reset
|
||||
buffers for us.
|
||||
*/
|
||||
|
||||
int Mrr_ordered_index_reader::refill_buffer()
|
||||
@ -427,23 +411,7 @@ int Mrr_ordered_index_reader::refill_buffer()
|
||||
is_mrr_assoc? (uchar**)&range_info_ptr : NULL,
|
||||
sizeof(uchar*));
|
||||
}
|
||||
#if 0
|
||||
|
||||
if (know_key_tuple_params)
|
||||
{
|
||||
if (do_rndpos_scan && rowid_buffer.is_empty())
|
||||
{
|
||||
/*
|
||||
We're using two buffers and both of them are empty now. Restore the
|
||||
original sizes
|
||||
*/
|
||||
rowid_buffer.set_buffer_space(full_buf, rowid_buffer_end);
|
||||
key_buffer= &backward_key_buf;
|
||||
key_buffer->set_buffer_space(rowid_buffer_end, full_buf_end);
|
||||
}
|
||||
}
|
||||
is all of the ifdef-ed stuff is handled above?
|
||||
#endif
|
||||
while ((!know_key_tuple_params || key_buffer->can_write()) &&
|
||||
!(res= mrr_funcs.next(mrr_iter, &cur_range)))
|
||||
{
|
||||
@ -478,7 +446,7 @@ int Mrr_ordered_index_reader::refill_buffer()
|
||||
key_buffer->write();
|
||||
}
|
||||
|
||||
no_more_keys= test(res);
|
||||
bool no_more_keys= test(res);
|
||||
scanning_key_val_iter= FALSE;
|
||||
index_scan_eof= FALSE;
|
||||
|
||||
@ -522,15 +490,8 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg,
|
||||
h= h_arg;
|
||||
index_reader= index_reader_arg;
|
||||
rowid_buffer= buf;
|
||||
is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
|
||||
//rowid_buff_elem_size= h->ref_length;
|
||||
//if (!(mode & HA_MRR_NO_ASSOCIATION))
|
||||
// rowid_buff_elem_size += sizeof(char*);
|
||||
|
||||
is_mrr_assoc= !test(mode & HA_MRR_NO_ASSOCIATION);
|
||||
index_reader_exhausted= FALSE;
|
||||
///int res= index_reader->refill_buffer();
|
||||
///if (res && res!=HA_ERR_END_OF_FILE)
|
||||
/// return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -553,7 +514,6 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg,
|
||||
@retval other Error
|
||||
*/
|
||||
|
||||
|
||||
int Mrr_ordered_rndpos_reader::refill_buffer()
|
||||
{
|
||||
int res;
|
||||
@ -562,7 +522,7 @@ int Mrr_ordered_rndpos_reader::refill_buffer()
|
||||
if (index_reader_exhausted)
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
||||
|
||||
while ((res= refill2() == HA_ERR_END_OF_FILE))
|
||||
while ((res= refill_from_key_buffer() == HA_ERR_END_OF_FILE))
|
||||
{
|
||||
if ((res= index_reader->refill_buffer()))
|
||||
{
|
||||
@ -575,13 +535,23 @@ int Mrr_ordered_rndpos_reader::refill_buffer()
|
||||
}
|
||||
|
||||
|
||||
/* This one refills without calling index_reader->refill_buffer(). */
|
||||
int Mrr_ordered_rndpos_reader::refill2()
|
||||
void Mrr_index_reader::position()
|
||||
{
|
||||
h->position(h->get_table()->record[0]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@brief Try to refill the rowid buffer without calling
|
||||
index_reader->refill_buffer().
|
||||
*/
|
||||
|
||||
int Mrr_ordered_rndpos_reader::refill_from_key_buffer()
|
||||
{
|
||||
char *range_info;
|
||||
uchar **range_info_ptr= (uchar**)&range_info;
|
||||
int res;
|
||||
DBUG_ENTER("Mrr_ordered_rndpos_reader::refill2");
|
||||
DBUG_ENTER("Mrr_ordered_rndpos_reader::refill_from_key_buffer");
|
||||
|
||||
DBUG_ASSERT(rowid_buffer->is_empty());
|
||||
index_rowid= index_reader->get_rowid_ptr();
|
||||
@ -600,7 +570,7 @@ int Mrr_ordered_rndpos_reader::refill2()
|
||||
break;
|
||||
|
||||
/* Put rowid, or {rowid, range_id} pair into the buffer */
|
||||
index_reader->h->position(index_reader->h->get_table()->record[0]);
|
||||
index_reader->position();
|
||||
|
||||
rowid_buffer->write();
|
||||
}
|
||||
@ -615,10 +585,12 @@ int Mrr_ordered_rndpos_reader::refill2()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
DS-MRR implementation: multi_range_read_next() function.
|
||||
/*
|
||||
Get the next record+range_id using ordered array of rowid+range_id pairds
|
||||
|
||||
Calling convention is like multi_range_read_next() has.
|
||||
@note
|
||||
Since we have sorted rowids, we try not to make multiple rnd_pos() calls
|
||||
with the same rowid value.
|
||||
*/
|
||||
|
||||
int Mrr_ordered_rndpos_reader::get_next(char **range_info)
|
||||
@ -652,31 +624,6 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
|
||||
|
||||
while (1)
|
||||
{
|
||||
#if 0
|
||||
if (rowid_buffer->is_empty()) /* We're out of rowids */
|
||||
{
|
||||
/* First, finish off the sorted keys we have */
|
||||
if (!index_reader->eof())
|
||||
{
|
||||
res= refill_buffer();
|
||||
if (res && res != HA_ERR_END_OF_FILE)
|
||||
return res;
|
||||
}
|
||||
|
||||
if (rowid_buffer->is_empty())
|
||||
{
|
||||
/*
|
||||
Ok neither index_reader nor us have any records. Refill index
|
||||
reader, then refill us.
|
||||
*/
|
||||
// TODO: if key buffer is empty, too, redistribute the buffer space.
|
||||
if ((res= index_reader->refill_buffer()) ||
|
||||
(res= refill_buffer()))
|
||||
return res;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
last_identical_rowid= NULL;
|
||||
|
||||
/* Return eof if there are no rowids in the buffer after re-fill attempt */
|
||||
@ -724,13 +671,8 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/************ MRR_impl classes end *********************************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* DS-MRR implementation
|
||||
* Top-level DS-MRR implementation functions (the ones called by storage engine)
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
@ -769,7 +711,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
if ((mode & HA_MRR_USE_DEFAULT_IMPL) || (mode & HA_MRR_SORTED))
|
||||
{
|
||||
DBUG_ASSERT(h->inited == handler::INDEX);
|
||||
Mrr_simple_index_reader *s= &strategy_factory.simple_index_reader;
|
||||
Mrr_simple_index_reader *s= &reader_factory.simple_index_reader;
|
||||
res= s->init(h, seq_funcs, seq_init_param, n_ranges, mode, this);
|
||||
strategy= s;
|
||||
DBUG_RETURN(res);
|
||||
@ -786,10 +728,10 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
if ((mode & HA_MRR_SINGLE_POINT) &&
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_MRR_SORT_KEYS))
|
||||
{
|
||||
index_strategy= ordered_idx_reader= &strategy_factory.ordered_index_reader;
|
||||
index_strategy= ordered_idx_reader= &reader_factory.ordered_index_reader;
|
||||
}
|
||||
else
|
||||
index_strategy= &strategy_factory.simple_index_reader;
|
||||
index_strategy= &reader_factory.simple_index_reader;
|
||||
|
||||
strategy= index_strategy;
|
||||
/*
|
||||
@ -807,7 +749,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
Mrr_ordered_rndpos_reader *disk_strategy= NULL;
|
||||
if (!(keyno == table->s->primary_key && h_idx->primary_key_is_clustered()))
|
||||
{
|
||||
strategy= disk_strategy= &strategy_factory.ordered_rndpos_reader;
|
||||
strategy= disk_strategy= &reader_factory.ordered_rndpos_reader;
|
||||
}
|
||||
|
||||
if (is_mrr_assoc)
|
||||
@ -818,8 +760,6 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
|
||||
if (strategy == index_strategy)
|
||||
{
|
||||
///if (ordered_idx_reader)
|
||||
// ordered_idx_reader->auto_refill= TRUE;
|
||||
/* Index strategy serves it all. We don't need two handlers, etc */
|
||||
/* Give the buffer to index strategy */
|
||||
if ((res= index_strategy->init(h, seq_funcs, seq_init_param, n_ranges,
|
||||
@ -838,9 +778,6 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
|
||||
if ((res= setup_two_handlers()))
|
||||
DBUG_RETURN(res);
|
||||
|
||||
///if (ordered_idx_reader)
|
||||
/// ordered_idx_reader->auto_refill= FALSE;
|
||||
|
||||
if ((res= index_strategy->init(h2, seq_funcs, seq_init_param, n_ranges,
|
||||
mode, this)) ||
|
||||
(res= disk_strategy->init(h, index_strategy, mode, &rowid_buffer)))
|
||||
@ -960,8 +897,8 @@ int DsMrr_impl::setup_two_handlers()
|
||||
goto error;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
||||
error:
|
||||
//close_second_handler(); -- caller does that
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
@ -1132,6 +1069,7 @@ void DsMrr_impl::reset_buffer_sizes()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Take unused space from the key buffer and give it to the rowid buffer
|
||||
*/
|
||||
@ -1144,14 +1082,9 @@ void DsMrr_impl::reallocate_buffer_space()
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
|
||||
{
|
||||
int res;
|
||||
//h= h_arg;
|
||||
//param= param_arg;
|
||||
owner= owner_arg;
|
||||
|
||||
identical_key_it.init(owner->key_buffer);
|
||||
|
Reference in New Issue
Block a user