21
21
#include "myisamdef.h"
23
static ha_rows _mi_record_pos(MI_INFO *, const uchar *, key_part_map,
23
static ha_rows _mi_record_pos(MI_INFO *, const unsigned char *, key_part_map,
24
24
enum ha_rkey_function);
25
static double _mi_search_pos(MI_INFO *,MI_KEYDEF *,uchar *, uint,uint,my_off_t);
26
static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *,uchar *, uchar *,uint *);
25
static double _mi_search_pos(MI_INFO *,MI_KEYDEF *,unsigned char *, uint,uint,my_off_t);
26
static uint32_t _mi_keynr(MI_INFO *info,MI_KEYDEF *,unsigned char *, unsigned char *,uint32_t *);
29
29
Estimate how many records there is in a given range
42
42
HA_POS_ERROR error (or we can't estimate number of rows)
43
43
number Estimated number of rows
46
46
ha_rows mi_records_in_range(MI_INFO *info, int inx,
47
47
key_range *min_key, key_range *max_key)
49
49
ha_rows start_pos,end_pos,res;
50
DBUG_ENTER("mi_records_in_range");
52
51
if ((inx = _mi_check_index(info,inx)) < 0)
53
DBUG_RETURN(HA_POS_ERROR);
55
54
if (fast_mi_readinfo(info))
56
DBUG_RETURN(HA_POS_ERROR);
57
56
info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED);
58
57
if (info->s->concurrent_insert)
59
rw_rdlock(&info->s->key_root_lock[inx]);
58
pthread_rwlock_rdlock(&info->s->key_root_lock[inx]);
61
60
switch(info->s->keyinfo[inx].key_alg){
62
61
case HA_KEY_ALG_BTREE:
76
75
if (info->s->concurrent_insert)
77
rw_unlock(&info->s->key_root_lock[inx]);
76
pthread_rwlock_unlock(&info->s->key_root_lock[inx]);
78
77
fast_mi_writeinfo(info);
80
DBUG_PRINT("info",("records: %ld",(ulong) (res)));
85
83
/* Find relative position (in records) for key in index-tree */
87
static ha_rows _mi_record_pos(MI_INFO *info, const uchar *key,
85
static ha_rows _mi_record_pos(MI_INFO *info, const unsigned char *key,
88
86
key_part_map keypart_map,
89
87
enum ha_rkey_function search_flag)
91
uint inx=(uint) info->lastinx, nextflag, key_len;
89
uint32_t inx=(uint) info->lastinx, nextflag, key_len;
92
90
MI_KEYDEF *keyinfo=info->s->keyinfo+inx;
91
unsigned char *key_buff;
96
DBUG_ENTER("_mi_record_pos");
97
DBUG_PRINT("enter",("search_flag: %d",search_flag));
98
DBUG_ASSERT(keypart_map);
100
96
key_buff=info->lastkey+info->s->base.max_key_length;
101
key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key, keypart_map,
97
key_len=_mi_pack_key(info,inx,key_buff,(unsigned char*) key, keypart_map,
103
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
104
(uchar*) key_buff,key_len););
105
99
nextflag=myisam_read_vec[search_flag];
106
100
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
107
101
key_len=USE_WHOLE_KEY;
145
139
info->s->state.key_root[inx]);
148
DBUG_PRINT("exit",("pos: %ld",(ulong) (pos*info->state->records)));
149
DBUG_RETURN((ulong) (pos*info->state->records+0.5));
142
return((uint32_t) (pos*info->state->records+0.5));
151
DBUG_RETURN(HA_POS_ERROR);
144
return(HA_POS_ERROR);
158
151
static double _mi_search_pos(register MI_INFO *info,
159
152
register MI_KEYDEF *keyinfo,
160
uchar *key, uint key_len, uint nextflag,
153
unsigned char *key, uint32_t key_len, uint32_t nextflag,
161
154
register my_off_t pos)
164
uint nod_flag, keynr, max_keynr= 0;
157
uint32_t nod_flag, keynr, max_keynr= 0;
159
unsigned char *keypos,*buff;
168
DBUG_ENTER("_mi_search_pos");
170
162
if (pos == HA_OFFSET_ERROR)
173
165
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1)))
182
174
if (flag == MI_FOUND_WRONG_KEY)
183
DBUG_RETURN(-1); /* error */
175
return(-1); /* error */
185
177
Didn't found match. keypos points at next (bigger) key
186
178
Try to find a smaller, better matching key.
191
183
else if ((offset=_mi_search_pos(info,keyinfo,key,key_len,nextflag,
192
184
_mi_kpos(nod_flag,keypos))) < 0)
210
202
if ((offset=_mi_search_pos(info,keyinfo,key,key_len,SEARCH_FIND,
211
203
_mi_kpos(nod_flag,keypos))) < 0)
212
DBUG_RETURN(offset); /* Read error */
204
return(offset); /* Read error */
215
DBUG_PRINT("info",("keynr: %d offset: %g max_keynr: %d nod: %d flag: %d",
216
keynr,offset,max_keynr,nod_flag,flag));
217
DBUG_RETURN((keynr+offset)/(max_keynr+1));
207
return((keynr+offset)/(max_keynr+1));
219
DBUG_PRINT("exit",("Error: %d",my_errno));
224
213
/* Get keynummer of current key and max number of keys in nod */
226
static uint _mi_keynr(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
227
uchar *keypos, uint *ret_max_key)
215
static uint32_t _mi_keynr(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
216
unsigned char *keypos, uint32_t *ret_max_key)
229
uint nod_flag,keynr,max_key;
230
uchar t_buff[MI_MAX_KEY_BUFF],*end;
218
uint32_t nod_flag,keynr,max_key;
219
unsigned char t_buff[MI_MAX_KEY_BUFF],*end;
232
221
end= page+mi_getint(page);
233
222
nod_flag=mi_test_if_nod(page);