diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2010-11-03 11:03:07 +0300 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2010-11-03 11:03:07 +0300 |
commit | d6ec99d0b663465c78e3a4cf8121ed05407fe2e4 (patch) | |
tree | dd3af29f1776365784d16b771d215b7b932e175d /sql/multi_range_read.cc | |
parent | 59db1d7a3939fde90cfe743ec9c2d81e5b57dc42 (diff) | |
parent | c46450de724449466060a0934de2c4244674aa76 (diff) | |
download | mariadb-git-d6ec99d0b663465c78e3a4cf8121ed05407fe2e4.tar.gz |
Merge {DS-DRR improvements:code cleanup} into MWL#128+DS-MRR tree
Diffstat (limited to 'sql/multi_range_read.cc')
-rw-r--r-- | sql/multi_range_read.cc | 201 |
1 files changed, 67 insertions, 134 deletions
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index a6a75c1d06e..d70d3243903 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -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); |