Commit e25db795 authored by Sergey Petrunya's avatar Sergey Petrunya

DS-MRR, key-ordered retrievals: commit for buildbot

parent 7391175d
This diff is collapsed.
...@@ -37,6 +37,96 @@ ...@@ -37,6 +37,96 @@
*/ */
/*
A simple memory buffer for reading and writing.
when writing, there is no user-visible "current" position, although
internally 'pos' points to just after the end of used area (or at the
start of it for reverse buffer).
When reading, there is current position pointing at start (for reverse
buffer, end) of the element that will be read next.
^^ why end for reverse? it's more logical to point at start
One can peek at what's behind that element by using advance_ptr function.
TODO: will the reverse buffer store {tuple; rowid} or {rowid; tuple} pairs?
(why does it matter??? Read and write in the same order and then it
shouldn't matter.)
*/
class SimpleBuffer
{
uchar *start;
uchar *end;
uchar *read_pos;
uchar *write_pos;
/*
1 <=> buffer grows/is filled/is read from start to end
-1 <=> everthing is done from end to start instead.
*/
int direction;
public:
/* Write-mode functions */
void reset_for_writing();
void write(const uchar *data, size_t bytes);
bool have_space_for(size_t bytes);
uchar *used_area() { return (direction == 1)? read_pos : write_pos; }
size_t used_size();
/* Read-mode functions */
void reset_for_reading();
uchar *read(size_t bytes);
bool have_data(size_t bytes);
uchar *end_of_space();
/* Control functions */
void set_buffer_space(uchar *start_arg, uchar *end_arg, int direction_arg)
{
start= start_arg;
end= end_arg;
direction= direction_arg;
reset_for_writing();
}
friend class PeekIterator;
class PeekIterator
{
// if direction==1 : pointer to what to return next
// if direction==-1: pointer to the end of what is to be returned next
uchar *pos;
SimpleBuffer *sb;
public:
void init(SimpleBuffer *sb_arg)
{
sb= sb_arg;
pos= sb->read_pos;
}
/* Return pointer to next chunk of nbytes bytes and avance over it */
uchar *get_next(size_t nbytes)
{
if (sb->direction == 1)
{
if (pos + nbytes > sb->write_pos)
return NULL;
uchar *res= pos;
pos += nbytes;
return res;
}
else
{
if (pos - nbytes <= sb->write_pos)
return NULL;
pos -= nbytes;
return pos;
}
}
};
};
/* /*
DS-MRR implementation for one table. Create/use one object of this class for DS-MRR implementation for one table. Create/use one object of this class for
each ha_{myisam/innobase/etc} object. That object will be further referred to each ha_{myisam/innobase/etc} object. That object will be further referred to
...@@ -73,6 +163,8 @@ ...@@ -73,6 +163,8 @@
scanning. scanning.
*/ */
class DsMrr_impl class DsMrr_impl
{ {
public: public:
...@@ -108,14 +200,27 @@ class DsMrr_impl ...@@ -108,14 +200,27 @@ class DsMrr_impl
/* Secondary handler object. It is used for scanning the index */ /* Secondary handler object. It is used for scanning the index */
handler *h2; handler *h2;
uchar *full_buf;
uchar *full_buf_end;
/* Buffer to store rowids, or (rowid, range_id) pairs */ /* Buffer to store rowids, or (rowid, range_id) pairs */
uchar *mrr_buf; SimpleBuffer rowid_buffer;
uchar *mrr_buf_cur; /* Current position when reading/writing */
uchar *mrr_buf_last; /* When reading: end of used buffer space */
uchar *mrr_buf_end; /* End of the buffer */
uchar *mrr_buf_next_identical; uchar *identical_rowid_ptr;
/* Identical keys */
bool in_identical_keys_range;
uchar *last_identical_key_ptr;
SimpleBuffer::PeekIterator identical_key_it;
SimpleBuffer key_buffer;
uint keyno;
/* Execution control */
bool do_sort_keys;
bool use_key_pointers; bool use_key_pointers;
bool do_rowid_fetch;
bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */ bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */
...@@ -129,18 +234,33 @@ class DsMrr_impl ...@@ -129,18 +234,33 @@ class DsMrr_impl
/** DS-MRR/CPK variables start */ /** DS-MRR/CPK variables start */
/* Length of lookup tuple being used, in bytes */ /* Length of lookup tuple being used, in bytes */
uint cpk_tuple_length; uint key_tuple_length;
key_part_map key_tuple_map;
/*
This is
= key_tuple_length if we copy keys to buffer
= sizeof(void*) if we're using pointers to materialized keys.
*/
uint key_size_in_keybuf;
/* = key_size_in_keybuf [ + sizeof(range_assoc_info) ] */
uint key_buff_elem_size;
/* = h->ref_length [ + sizeof(range_assoc_info) ] */
uint rowid_buff_elem_size;
uint key_buf_element_size;
/* /*
TRUE <=> We're scanning on a full primary key (and not on prefix), and so TRUE <=> We're scanning on a full primary key (and not on prefix), and so
can get max. one match for each key can get max. one match for each key
*/ */
bool cpk_is_unique_scan; bool index_ranges_unique;
/* TRUE<=> we're in a middle of enumerating records from a range */ /* TRUE<=> we're in a middle of enumerating records from a range */
bool cpk_have_range; bool in_index_range;
/* Valid if cpk_have_range==TRUE: range_id of the range we're enumerating */ uchar *cur_index_tuple;
char *cpk_saved_range_info; /* if in_index_range==TRUE: range_id of the range we're enumerating */
char *cur_range_info;
char *first_identical_range_info;
bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz, bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz,
COST_VECT *cost); COST_VECT *cost);
...@@ -150,6 +270,11 @@ class DsMrr_impl ...@@ -150,6 +270,11 @@ class DsMrr_impl
static int key_tuple_cmp(void* arg, uchar* key1, uchar* key2); static int key_tuple_cmp(void* arg, uchar* key1, uchar* key2);
int dsmrr_fill_rowid_buffer(); int dsmrr_fill_rowid_buffer();
void dsmrr_fill_key_buffer(); void dsmrr_fill_key_buffer();
int dsmrr_next_cpk(char **range_info); int dsmrr_next_from_index(char **range_info);
void setup_buffer_sizes(key_range *sample_key);
static range_seq_t key_buf_seq_init(void *init_param, uint n_ranges, uint flags);
static uint key_buf_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
}; };
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