20
20
Functions for easy reading of records, possible through a cache
22
22
#include "config.h"
24
#include "drizzled/drizzled.h"
25
23
#include "drizzled/error.h"
24
#include "drizzled/table.h"
25
#include "drizzled/session.h"
26
#include "drizzled/records.h"
27
#include "drizzled/optimizer/range.h"
28
#include "drizzled/internal/my_sys.h"
26
29
#include "drizzled/internal/iocache.h"
27
#include "drizzled/internal/my_sys.h"
28
#include "drizzled/optimizer/range.h"
29
#include "drizzled/plugin/storage_engine.h"
30
#include "drizzled/records.h"
31
#include "drizzled/session.h"
32
#include "drizzled/table.h"
37
static int rr_sequential(ReadRecord *info);
38
static int rr_quick(ReadRecord *info);
39
static int rr_from_tempfile(ReadRecord *info);
40
static int rr_unpack_from_tempfile(ReadRecord *info);
41
static int rr_unpack_from_buffer(ReadRecord *info);
42
static int rr_from_pointers(ReadRecord *info);
43
static int rr_from_cache(ReadRecord *info);
34
int rr_sequential(READ_RECORD *info);
35
static int rr_quick(READ_RECORD *info);
36
static int rr_from_tempfile(READ_RECORD *info);
37
static int rr_unpack_from_tempfile(READ_RECORD *info);
38
static int rr_unpack_from_buffer(READ_RECORD *info);
39
static int rr_from_pointers(READ_RECORD *info);
40
static int rr_from_cache(READ_RECORD *info);
41
static int init_rr_cache(Session *session, READ_RECORD *info);
44
42
static int rr_cmp(unsigned char *a,unsigned char *b);
45
static int rr_index_first(ReadRecord *info);
46
static int rr_index(ReadRecord *info);
48
void ReadRecord::init_reard_record_sequential()
50
read_record= rr_sequential;
53
int ReadRecord::init_read_record_idx(Session *,
58
table_arg->emptyRecord();
60
cursor= table->cursor;
61
record= table->getInsertRecord();
62
print_error= print_error_arg;
43
static int rr_index_first(READ_RECORD *info);
44
static int rr_index(READ_RECORD *info);
46
void init_read_record_idx(READ_RECORD *info,
53
memset(info, 0, sizeof(*info));
55
info->cursor= table->cursor;
56
info->record= table->record[0];
57
info->print_error= print_error;
64
59
table->status=0; /* And it's always found */
65
if (not table->cursor->inited)
67
int error= table->cursor->startIndexScan(idx, 1);
60
if (!table->cursor->inited)
61
table->cursor->ha_index_init(idx, 1);
71
62
/* read_record will be changed to rr_index in rr_index_first */
72
read_record= rr_index_first;
63
info->read_record= rr_index_first;
78
int ReadRecord::init_read_record(Session *session_arg,
80
optimizer::SqlSelect *select_arg,
67
void init_read_record(READ_RECORD *info,
70
optimizer::SqlSelect *select,
84
74
internal::IO_CACHE *tempfile;
89
cursor= table->cursor;
90
forms= &table; /* Only one table */
76
memset(info, 0, sizeof(*info));
77
info->session=session;
79
info->cursor= table->cursor;
80
info->forms= &info->table; /* Only one table */
92
82
if (table->sort.addon_field)
94
rec_buf= table->sort.addon_buf;
95
ref_length= table->sort.addon_length;
84
info->rec_buf= table->sort.addon_buf;
85
info->ref_length= table->sort.addon_length;
99
89
table->emptyRecord();
100
record= table->getInsertRecord();
101
ref_length= table->cursor->ref_length;
90
info->record= table->record[0];
91
info->ref_length= table->cursor->ref_length;
104
print_error= print_error_arg;
105
ignore_not_found_rows= 0;
94
info->print_error= print_error;
95
info->ignore_not_found_rows= 0;
106
96
table->status=0; /* And it's always found */
108
98
if (select && my_b_inited(select->file))
110
99
tempfile= select->file;
114
101
tempfile= table->sort.io_cache;
117
102
if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
119
read_record= (table->sort.addon_field ?
120
rr_unpack_from_tempfile : rr_from_tempfile);
123
io_cache->reinit_io_cache(internal::READ_CACHE,0L,0,0);
124
ref_pos=table->cursor->ref;
104
info->read_record= (table->sort.addon_field ?
105
rr_unpack_from_tempfile : rr_from_tempfile);
106
info->io_cache=tempfile;
107
reinit_io_cache(info->io_cache,internal::READ_CACHE,0L,0,0);
108
info->ref_pos=table->cursor->ref;
125
109
if (!table->cursor->inited)
127
error= table->cursor->startTableScan(0);
110
table->cursor->ha_rnd_init(0);
133
113
table->sort.addon_field is checked because if we use addon fields,
139
119
!(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) &&
140
120
(table->db_stat & HA_READ_ONLY ||
141
121
table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
142
(uint64_t) table->getShare()->getRecordLength() * (table->cursor->stats.records+
122
(uint64_t) table->s->reclength* (table->cursor->stats.records+
143
123
table->cursor->stats.deleted) >
144
124
(uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
145
io_cache->end_of_file/ref_length * table->getShare()->getRecordLength() >
125
info->io_cache->end_of_file/info->ref_length * table->s->reclength >
146
126
(internal::my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
147
!table->getShare()->blob_fields &&
148
ref_length <= MAX_REFLENGTH)
127
!table->s->blob_fields &&
128
info->ref_length <= MAX_REFLENGTH)
130
if (! init_rr_cache(session, info))
152
read_record= rr_from_cache;
132
info->read_record=rr_from_cache;
156
136
else if (select && select->quick)
158
read_record= rr_quick;
138
info->read_record=rr_quick;
160
140
else if (table->sort.record_pointers)
162
error= table->cursor->startTableScan(0);
166
cache_pos=table->sort.record_pointers;
167
cache_end= cache_pos+ table->sort.found_records * ref_length;
168
read_record= (table->sort.addon_field ? rr_unpack_from_buffer : rr_from_pointers);
142
table->cursor->ha_rnd_init(0);
143
info->cache_pos=table->sort.record_pointers;
144
info->cache_end=info->cache_pos+
145
table->sort.found_records*info->ref_length;
146
info->read_record= (table->sort.addon_field ?
147
rr_unpack_from_buffer : rr_from_pointers);
172
read_record= rr_sequential;
173
error= table->cursor->startTableScan(1);
151
info->read_record= rr_sequential;
152
table->cursor->ha_rnd_init(1);
177
153
/* We can use record cache if we don't update dynamic length tables */
178
154
if (!table->no_cache &&
179
155
(use_record_cache > 0 ||
180
156
(int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS ||
181
!(table->getShare()->db_options_in_use & HA_OPTION_PACK_RECORD)))
157
!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD)))
183
158
table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
188
162
} /* init_read_record */
191
void ReadRecord::end_read_record()
165
void end_read_record(READ_RECORD *info)
192
166
{ /* free cache if used */
195
global_read_rnd_buffer.sub(session->variables.read_rnd_buff_size);
169
free((char*) info->cache);
201
table->filesort_free_buffers();
202
(void) cursor->extra(HA_EXTRA_NO_CACHE);
203
if (read_record != rr_quick) // otherwise quick_range does it
204
(void) cursor->ha_index_or_rnd_end();
174
info->table->filesort_free_buffers();
175
(void) info->cursor->extra(HA_EXTRA_NO_CACHE);
176
if (info->read_record != rr_quick) // otherwise quick_range does it
177
(void) info->cursor->ha_index_or_rnd_end();
210
static int rr_handle_error(ReadRecord *info, int error)
182
static int rr_handle_error(READ_RECORD *info, int error)
212
184
if (error == HA_ERR_END_OF_FILE)
410
381
/* cacheing of records from a database */
411
bool ReadRecord::init_rr_cache()
382
static int init_rr_cache(Session *session, READ_RECORD *info)
413
uint32_t local_rec_cache_size;
415
struct_length= 3 + MAX_REFLENGTH;
416
reclength= ALIGN_SIZE(table->getShare()->getRecordLength() + 1);
417
if (reclength < struct_length)
418
reclength= ALIGN_SIZE(struct_length);
420
error_offset= table->getShare()->getRecordLength();
421
cache_records= (session->variables.read_rnd_buff_size /
422
(reclength + struct_length));
423
local_rec_cache_size= cache_records * reclength;
424
rec_cache_size= cache_records * ref_length;
426
if (not global_read_rnd_buffer.add(session->variables.read_rnd_buff_size))
428
my_error(ER_OUT_OF_GLOBAL_READRNDMEMORY, MYF(ME_ERROR+ME_WAITTANG));
384
uint32_t rec_cache_size;
386
info->struct_length= 3+MAX_REFLENGTH;
387
info->reclength= ALIGN_SIZE(info->table->s->reclength+1);
388
if (info->reclength < info->struct_length)
389
info->reclength= ALIGN_SIZE(info->struct_length);
391
info->error_offset= info->table->s->reclength;
392
info->cache_records= (session->variables.read_rnd_buff_size /
393
(info->reclength+info->struct_length));
394
rec_cache_size= info->cache_records*info->reclength;
395
info->rec_cache_size= info->cache_records*info->ref_length;
432
397
// We have to allocate one more byte to use uint3korr (see comments for it)
433
if (cache_records <= 2 ||
434
!(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
398
if (info->cache_records <= 2 ||
399
!(info->cache=(unsigned char*) malloc(rec_cache_size+info->cache_records*
400
info->struct_length+1)))
439
403
// Avoid warnings in qsort
440
memset(cache, 0, local_rec_cache_size + cache_records * struct_length + 1);
404
memset(info->cache, 0,
405
rec_cache_size+info->cache_records* info->struct_length+1);
442
read_positions= cache + local_rec_cache_size;
443
cache_pos= cache_end= cache;
407
info->read_positions=info->cache+rec_cache_size;
408
info->cache_pos=info->cache_end=info->cache;
446
410
} /* init_rr_cache */
448
static int rr_from_cache(ReadRecord *info)
412
static int rr_from_cache(READ_RECORD *info)
451
416
internal::my_off_t rest_of_file;
469
memcpy(info->record,info->cache_pos, (size_t) info->table->getShare()->getRecordLength());
434
memcpy(info->record,info->cache_pos, (size_t) info->table->s->reclength);
471
info->cache_pos+= info->reclength;
436
info->cache_pos+=info->reclength;
472
437
return ((int) error);
474
439
length=info->rec_cache_size;
475
rest_of_file= info->io_cache->end_of_file - my_b_tell(info->io_cache);
440
rest_of_file=info->io_cache->end_of_file - my_b_tell(info->io_cache);
476
441
if ((internal::my_off_t) length > rest_of_file)
478
442
length= (uint32_t) rest_of_file;
481
if (!length || my_b_read(info->io_cache, info->getCache(), length))
443
if (!length || my_b_read(info->io_cache,info->cache,length))
483
445
return -1; /* End of cursor */
486
448
length/=info->ref_length;
487
position=info->getCache();
449
position=info->cache;
488
450
ref_position=info->read_positions;
489
for (uint32_t i= 0 ; i < length ; i++,position+=info->ref_length)
451
for (i=0 ; i < length ; i++,position+=info->ref_length)
491
453
memcpy(ref_position,position,(size_t) info->ref_length);
492
454
ref_position+=MAX_REFLENGTH;