Commit 72bde5e6 authored by Sergey Petrunya's avatar Sergey Petrunya

MWL#121-125 DS-MRR improvements

- Address Monty's review feedback, portion 2
parent c3009dcb
...@@ -351,7 +351,7 @@ int Mrr_ordered_index_reader::get_next(char **range_info) ...@@ -351,7 +351,7 @@ int Mrr_ordered_index_reader::get_next(char **range_info)
scanning_key_val_iter= TRUE; scanning_key_val_iter= TRUE;
} }
if ((res= kv_it.get_next())) if ((res= kv_it.get_next(range_info)))
{ {
scanning_key_val_iter= FALSE; scanning_key_val_iter= FALSE;
if ((res != HA_ERR_KEY_NOT_FOUND && res != HA_ERR_END_OF_FILE)) if ((res != HA_ERR_KEY_NOT_FOUND && res != HA_ERR_END_OF_FILE))
...@@ -359,17 +359,14 @@ int Mrr_ordered_index_reader::get_next(char **range_info) ...@@ -359,17 +359,14 @@ int Mrr_ordered_index_reader::get_next(char **range_info)
kv_it.move_to_next_key_value(); kv_it.move_to_next_key_value();
continue; continue;
} }
char *range_info; if (!skip_index_tuple(*range_info) &&
memcpy(&range_info, cur_range_info, sizeof(char*)); !skip_record(*range_info, NULL))
if (!skip_index_tuple(range_info) &&
!skip_record(range_info, NULL))
{ {
break; break;
} }
/* Go get another (record, range_id) combination */ /* Go get another (record, range_id) combination */
} /* while */ } /* while */
memcpy(range_info, cur_range_info, sizeof(void*));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -430,7 +427,7 @@ int Mrr_ordered_index_reader::refill_buffer(bool initial) ...@@ -430,7 +427,7 @@ int Mrr_ordered_index_reader::refill_buffer(bool initial)
key_buffer->reset(); key_buffer->reset();
key_buffer->setup_writing(&key_ptr, keypar.key_size_in_keybuf, key_buffer->setup_writing(&key_ptr, keypar.key_size_in_keybuf,
is_mrr_assoc? (uchar**)&range_info_ptr : NULL, is_mrr_assoc? (uchar**)&range_info_ptr : NULL,
sizeof(uchar*)); is_mrr_assoc? sizeof(uchar*):0);
while (key_buffer->can_write() && while (key_buffer->can_write() &&
!(source_exhausted= mrr_funcs.next(mrr_iter, &cur_range))) !(source_exhausted= mrr_funcs.next(mrr_iter, &cur_range)))
...@@ -603,7 +600,7 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader() ...@@ -603,7 +600,7 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
rowid_buffer->reset(); rowid_buffer->reset();
rowid_buffer->setup_writing(&index_rowid, file->ref_length, rowid_buffer->setup_writing(&index_rowid, file->ref_length,
is_mrr_assoc? (uchar**)&range_info_ptr: NULL, is_mrr_assoc? (uchar**)&range_info_ptr: NULL,
sizeof(void*)); is_mrr_assoc? sizeof(char*):0);
last_identical_rowid= NULL; last_identical_rowid= NULL;
...@@ -630,9 +627,8 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader() ...@@ -630,9 +627,8 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
/* Sort the buffer contents by rowid */ /* Sort the buffer contents by rowid */
rowid_buffer->sort((qsort2_cmp)rowid_cmp_reverse, (void*)file); rowid_buffer->sort((qsort2_cmp)rowid_cmp_reverse, (void*)file);
rowid_buffer->setup_reading(&rowid, file->ref_length, rowid_buffer->setup_reading(file->ref_length,
is_mrr_assoc? (uchar**)&rowids_range_id: NULL, is_mrr_assoc ? sizeof(char*) : 0);
sizeof(void*));
DBUG_RETURN(rowid_buffer->is_empty()? HA_ERR_END_OF_FILE : 0); DBUG_RETURN(rowid_buffer->is_empty()? HA_ERR_END_OF_FILE : 0);
} }
...@@ -662,14 +658,14 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) ...@@ -662,14 +658,14 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
*/ */
(void)rowid_buffer->read(); (void)rowid_buffer->read();
if (rowid == last_identical_rowid) if (rowid_buffer->read_ptr1 == last_identical_rowid)
last_identical_rowid= NULL; /* reached the last of identical rowids */ last_identical_rowid= NULL; /* reached the last of identical rowids */
if (!is_mrr_assoc) if (!is_mrr_assoc)
return 0; return 0;
memcpy(range_info, rowids_range_id, sizeof(uchar*)); memcpy(range_info, rowid_buffer->read_ptr2, sizeof(uchar*));
if (!index_reader->skip_record((char*)*range_info, rowid)) if (!index_reader->skip_record((char*)*range_info, rowid_buffer->read_ptr1))
return 0; return 0;
} }
...@@ -685,13 +681,13 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) ...@@ -685,13 +681,13 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
if (is_mrr_assoc) if (is_mrr_assoc)
{ {
memcpy(range_info, rowids_range_id, sizeof(uchar*)); memcpy(range_info, rowid_buffer->read_ptr2, sizeof(uchar*));
if (index_reader->skip_record(*range_info, rowid_buffer->read_ptr1))
if (index_reader->skip_record(*range_info, rowid))
continue; continue;
} }
res= file->ha_rnd_pos(file->get_table()->record[0], rowid); res= file->ha_rnd_pos(file->get_table()->record[0],
rowid_buffer->read_ptr1);
if (res == HA_ERR_RECORD_DELETED) if (res == HA_ERR_RECORD_DELETED)
{ {
...@@ -709,19 +705,17 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info) ...@@ -709,19 +705,17 @@ int Mrr_ordered_rndpos_reader::get_next(char **range_info)
Check if subsequent buffer elements have the same rowid value as this Check if subsequent buffer elements have the same rowid value as this
one. If yes, remember this fact so that we don't make any more rnd_pos() one. If yes, remember this fact so that we don't make any more rnd_pos()
calls with this value. calls with this value.
*/
uchar *cur_rowid= rowid;
/*
Note: this implies that SQL layer doesn't touch table->record[0] Note: this implies that SQL layer doesn't touch table->record[0]
between calls. between calls.
*/ */
Lifo_buffer_iterator it; Lifo_buffer_iterator it;
it.init(rowid_buffer); it.init(rowid_buffer);
while (!it.read()) // reads to (rowid, ...) while (!it.read())
{ {
if (file->cmp_ref(rowid, cur_rowid)) if (file->cmp_ref(it.read_ptr1, rowid_buffer->read_ptr1))
break; break;
last_identical_rowid= rowid; last_identical_rowid= it.read_ptr1;
} }
return 0; return 0;
} }
...@@ -1202,38 +1196,32 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg) ...@@ -1202,38 +1196,32 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
owner= owner_arg; owner= owner_arg;
identical_key_it.init(owner->key_buffer); identical_key_it.init(owner->key_buffer);
/* Get the first pair into (cur_index_tuple, cur_range_info) */ owner->key_buffer->setup_reading(owner->keypar.key_size_in_keybuf,
owner->key_buffer->setup_reading(&cur_index_tuple, owner->is_mrr_assoc ? sizeof(void*) : 0);
owner->keypar.key_size_in_keybuf,
owner->is_mrr_assoc?
(uchar**)&owner->cur_range_info: NULL,
sizeof(void*));
if (identical_key_it.read()) if (identical_key_it.read())
return HA_ERR_END_OF_FILE; return HA_ERR_END_OF_FILE;
uchar *key_in_buf= cur_index_tuple; uchar *key_in_buf= last_identical_key_ptr= identical_key_it.read_ptr1;
last_identical_key_ptr= cur_index_tuple; uchar *index_tuple= key_in_buf;
if (owner->keypar.use_key_pointers) if (owner->keypar.use_key_pointers)
memcpy(&cur_index_tuple, key_in_buf, sizeof(char*)); memcpy(&index_tuple, key_in_buf, sizeof(char*));
/* Check out how many more identical keys are following */ /* Check out how many more identical keys are following */
uchar *save_cur_index_tuple= cur_index_tuple;
while (!identical_key_it.read()) while (!identical_key_it.read())
{ {
if (owner->disallow_identical_key_handling || if (owner->disallow_identical_key_handling ||
Mrr_ordered_index_reader::compare_keys(owner, key_in_buf, Mrr_ordered_index_reader::compare_keys(owner, key_in_buf,
cur_index_tuple)) identical_key_it.read_ptr1))
break; break;
last_identical_key_ptr= cur_index_tuple; last_identical_key_ptr= identical_key_it.read_ptr1;
} }
identical_key_it.init(owner->key_buffer); identical_key_it.init(owner->key_buffer);
cur_index_tuple= save_cur_index_tuple;
res= owner->file->ha_index_read_map(owner->file->get_table()->record[0], res= owner->file->ha_index_read_map(owner->file->get_table()->record[0],
cur_index_tuple, index_tuple,
owner->keypar.key_tuple_map, owner->keypar.key_tuple_map,
HA_READ_KEY_EXACT); HA_READ_KEY_EXACT);
if (res) if (res)
{ {
...@@ -1247,7 +1235,7 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg) ...@@ -1247,7 +1235,7 @@ int Key_value_records_iterator::init(Mrr_ordered_index_reader *owner_arg)
} }
int Key_value_records_iterator::get_next() int Key_value_records_iterator::get_next(char **range_info)
{ {
int res; int res;
...@@ -1261,7 +1249,7 @@ int Key_value_records_iterator::get_next() ...@@ -1261,7 +1249,7 @@ int Key_value_records_iterator::get_next()
handler *h= owner->file; handler *h= owner->file;
if ((res= h->ha_index_next_same(h->get_table()->record[0], if ((res= h->ha_index_next_same(h->get_table()->record[0],
cur_index_tuple, identical_key_it.read_ptr1,
owner->keypar.key_tuple_length))) owner->keypar.key_tuple_length)))
{ {
/* It's either HA_ERR_END_OF_FILE or some other error */ /* It's either HA_ERR_END_OF_FILE or some other error */
...@@ -1273,7 +1261,10 @@ int Key_value_records_iterator::get_next() ...@@ -1273,7 +1261,10 @@ int Key_value_records_iterator::get_next()
} }
identical_key_it.read(); /* This gets us next range_id */ identical_key_it.read(); /* This gets us next range_id */
if (!last_identical_key_ptr || (cur_index_tuple == last_identical_key_ptr)) memcpy(range_info, identical_key_it.read_ptr2, sizeof(char*));
if (!last_identical_key_ptr ||
(identical_key_it.read_ptr1 == last_identical_key_ptr))
{ {
/* /*
We've reached the last of the identical keys that current record is a We've reached the last of the identical keys that current record is a
...@@ -1289,7 +1280,7 @@ int Key_value_records_iterator::get_next() ...@@ -1289,7 +1280,7 @@ int Key_value_records_iterator::get_next()
void Key_value_records_iterator::move_to_next_key_value() void Key_value_records_iterator::move_to_next_key_value()
{ {
while (!owner->key_buffer->read() && while (!owner->key_buffer->read() &&
(cur_index_tuple != last_identical_key_ptr)) {} (owner->key_buffer->read_ptr1 != last_identical_key_ptr)) {}
} }
......
...@@ -133,10 +133,10 @@ class Key_value_records_iterator ...@@ -133,10 +133,10 @@ class Key_value_records_iterator
*/ */
bool get_next_row; bool get_next_row;
uchar *cur_index_tuple; /* key_buffer.read() reads to here */ //uchar *cur_index_tuple; /* key_buffer.read() reads to here */
public: public:
int init(Mrr_ordered_index_reader *owner_arg); int init(Mrr_ordered_index_reader *owner_arg);
int get_next(); int get_next(char **range_info);
void move_to_next_key_value(); void move_to_next_key_value();
}; };
...@@ -281,9 +281,6 @@ class Mrr_ordered_index_reader : public Mrr_index_reader ...@@ -281,9 +281,6 @@ class Mrr_ordered_index_reader : public Mrr_index_reader
bool scanning_key_val_iter; bool scanning_key_val_iter;
/* Key_value_records_iterator::read() will place range_info here */
char *cur_range_info;
/* Buffer to store (key, range_id) pairs */ /* Buffer to store (key, range_id) pairs */
Lifo_buffer *key_buffer; Lifo_buffer *key_buffer;
...@@ -367,8 +364,8 @@ class Mrr_ordered_rndpos_reader : public Mrr_reader ...@@ -367,8 +364,8 @@ class Mrr_ordered_rndpos_reader : public Mrr_reader
Lifo_buffer *rowid_buffer; Lifo_buffer *rowid_buffer;
/* rowid_buffer.read() will set the following: */ /* rowid_buffer.read() will set the following: */
uchar *rowid; //uchar *rowid;
uchar *rowids_range_id; //uchar *rowids_range_id;
int refill_from_index_reader(); int refill_from_index_reader();
}; };
......
...@@ -39,14 +39,16 @@ class Lifo_buffer ...@@ -39,14 +39,16 @@ class Lifo_buffer
uchar **write_ptr2; uchar **write_ptr2;
size_t size2; size_t size2;
public:
/** /**
read() will do reading by storing pointer to read data into *read_ptr1 (if read() will do reading by storing pointers to read data into read_ptr1 or
the buffer stores atomic elements), or into {*read_ptr1, *read_ptr2} (if into (read_ptr1, read_ptr2), depending on whether the buffer was set to
the buffer stores pairs). store single objects or pairs.
*/ */
uchar **read_ptr1; uchar *read_ptr1;
uchar **read_ptr2; uchar *read_ptr2;
protected:
uchar *start; /**< points to start of buffer space */ uchar *start; /**< points to start of buffer space */
uchar *end; /**< points to just beyond the end of buffer space */ uchar *end; /**< points to just beyond the end of buffer space */
public: public:
...@@ -85,11 +87,9 @@ class Lifo_buffer ...@@ -85,11 +87,9 @@ class Lifo_buffer
Specify where read() should store pointers to read data, as well as read Specify where read() should store pointers to read data, as well as read
data size. The sizes must match those passed to setup_writing(). data size. The sizes must match those passed to setup_writing().
*/ */
void setup_reading(uchar **data1, size_t len1, uchar **data2, size_t len2) void setup_reading(size_t len1, size_t len2)
{ {
read_ptr1= data1;
DBUG_ASSERT(len1 == size1); DBUG_ASSERT(len1 == size1);
read_ptr2= data2;
DBUG_ASSERT(len2 == size2); DBUG_ASSERT(len2 == size2);
} }
...@@ -116,7 +116,7 @@ class Lifo_buffer ...@@ -116,7 +116,7 @@ class Lifo_buffer
/* To be used only by iterator class: */ /* To be used only by iterator class: */
virtual uchar *get_pos()= 0; virtual uchar *get_pos()= 0;
virtual bool read(uchar **position)= 0; virtual bool read(uchar **position, uchar **ptr1, uchar **ptr2)= 0;
friend class Lifo_buffer_iterator; friend class Lifo_buffer_iterator;
public: public:
virtual bool have_space_for(size_t bytes) = 0; virtual bool have_space_for(size_t bytes) = 0;
...@@ -184,14 +184,14 @@ class Forward_lifo_buffer: public Lifo_buffer ...@@ -184,14 +184,14 @@ class Forward_lifo_buffer: public Lifo_buffer
*position= (*position) - bytes; *position= (*position) - bytes;
return *position; return *position;
} }
bool read() { return read(&pos); } bool read() { return read(&pos, &read_ptr1, &read_ptr2); }
bool read(uchar **position) bool read(uchar **position, uchar **ptr1, uchar **ptr2)
{ {
if (!have_data(*position, size1 + (read_ptr2 ? size2 : 0))) if (!have_data(*position, size1 + size2))
return TRUE; return TRUE;
if (read_ptr2) if (size2)
*read_ptr2= read_bytes(position, size2); *ptr2= read_bytes(position, size2);
*read_ptr1= read_bytes(position, size1); *ptr1= read_bytes(position, size1);
return FALSE; return FALSE;
} }
void remove_unused_space(uchar **unused_start, uchar **unused_end) void remove_unused_space(uchar **unused_start, uchar **unused_end)
...@@ -268,15 +268,15 @@ class Backward_lifo_buffer: public Lifo_buffer ...@@ -268,15 +268,15 @@ class Backward_lifo_buffer: public Lifo_buffer
} }
bool read() bool read()
{ {
return read(&pos); return read(&pos, &read_ptr1, &read_ptr2);
} }
bool read(uchar **position) bool read(uchar **position, uchar **ptr1, uchar **ptr2)
{ {
if (!have_data(*position, size1 + (read_ptr2 ? size2 : 0))) if (!have_data(*position, size1 + size2))
return TRUE; return TRUE;
*read_ptr1= read_bytes(position, size1); *ptr1= read_bytes(position, size1);
if (read_ptr2) if (size2)
*read_ptr2= read_bytes(position, size2); *ptr2= read_bytes(position, size2);
return FALSE; return FALSE;
} }
bool have_data(uchar *position, size_t bytes) bool have_data(uchar *position, size_t bytes)
...@@ -312,13 +312,17 @@ class Backward_lifo_buffer: public Lifo_buffer ...@@ -312,13 +312,17 @@ class Backward_lifo_buffer: public Lifo_buffer
}; };
/** Iterator to walk over contents of the buffer without reading from it */
/** Iterator to walk over contents of the buffer without reading it. */
class Lifo_buffer_iterator class Lifo_buffer_iterator
{ {
uchar *pos; uchar *pos;
Lifo_buffer *buf; Lifo_buffer *buf;
public: public:
/* The data is read to here */
uchar *read_ptr1;
uchar *read_ptr2;
void init(Lifo_buffer *buf_arg) void init(Lifo_buffer *buf_arg)
{ {
buf= buf_arg; buf= buf_arg;
...@@ -333,7 +337,7 @@ class Lifo_buffer_iterator ...@@ -333,7 +337,7 @@ class Lifo_buffer_iterator
*/ */
bool read() bool read()
{ {
return buf->read(&pos); return buf->read(&pos, &read_ptr1, &read_ptr2);
} }
}; };
......
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