21 #include "myisam_priv.h"
25 static ha_rows _mi_record_pos(
MI_INFO *,
const unsigned char *, key_part_map,
26 enum ha_rkey_function);
27 static double _mi_search_pos(
MI_INFO *,
MI_KEYDEF *,
unsigned char *, uint,uint,internal::my_off_t);
28 static uint32_t _mi_keynr(
MI_INFO *info,
MI_KEYDEF *,
unsigned char *,
unsigned char *,uint32_t *);
48 ha_rows mi_records_in_range(
MI_INFO *info,
int inx,
51 ha_rows start_pos,end_pos,res;
53 if ((inx = _mi_check_index(info,inx)) < 0)
56 if (fast_mi_readinfo(info))
58 info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED);
60 switch(info->s->keyinfo[inx].key_alg){
61 case HA_KEY_ALG_BTREE:
63 start_pos= (min_key ? _mi_record_pos(info, min_key->key,
64 min_key->keypart_map, min_key->flag)
66 end_pos= (max_key ? _mi_record_pos(info, max_key->key,
67 max_key->keypart_map, max_key->flag)
68 : info->state->records + (ha_rows) 1);
69 res= (end_pos < start_pos ? (ha_rows) 0 :
70 (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos));
71 if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
75 fast_mi_writeinfo(info);
83 static ha_rows _mi_record_pos(
MI_INFO *info,
const unsigned char *key,
84 key_part_map keypart_map,
85 enum ha_rkey_function search_flag)
87 uint32_t inx=(uint) info->lastinx, nextflag, key_len;
89 unsigned char *key_buff;
94 key_buff=info->lastkey+info->s->base.max_key_length;
95 key_len=_mi_pack_key(info,inx,key_buff,(
unsigned char*) key, keypart_map,
97 nextflag=myisam_read_vec[search_flag];
98 if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
99 key_len=USE_WHOLE_KEY;
135 pos=_mi_search_pos(info,keyinfo,key_buff,key_len,
136 nextflag | SEARCH_SAVE_BUFF | SEARCH_UPDATE,
137 info->s->state.key_root[inx]);
140 return((uint32_t) (pos*info->state->records+0.5));
142 return(HA_POS_ERROR);
149 static double _mi_search_pos(
register MI_INFO *info,
151 unsigned char *key, uint32_t key_len, uint32_t nextflag,
152 register internal::my_off_t pos)
155 uint32_t nod_flag, keynr, max_keynr= 0;
157 unsigned char *keypos,*buff;
160 if (pos == HA_OFFSET_ERROR)
163 if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1)))
165 flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
166 &keypos,info->lastkey, &after_key);
167 nod_flag=mi_test_if_nod(buff);
168 keynr=_mi_keynr(info,keyinfo,buff,keypos,&max_keynr);
172 if (flag == MI_FOUND_WRONG_KEY)
179 if (flag > 0 && ! nod_flag)
181 else if ((offset=_mi_search_pos(info,keyinfo,key,key_len,nextflag,
182 _mi_kpos(nod_flag,keypos))) < 0)
192 if ((nextflag & SEARCH_FIND) && nod_flag &&
193 ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
194 key_len != USE_WHOLE_KEY))
200 if ((offset=_mi_search_pos(info,keyinfo,key,key_len,SEARCH_FIND,
201 _mi_kpos(nod_flag,keypos))) < 0)
205 return((keynr+offset)/(max_keynr+1));
213 static uint32_t _mi_keynr(
MI_INFO *info,
register MI_KEYDEF *keyinfo,
unsigned char *page,
214 unsigned char *keypos, uint32_t *ret_max_key)
216 uint32_t nod_flag,keynr,max_key;
217 unsigned char t_buff[MI_MAX_KEY_BUFF],*end;
219 end= page+mi_getint(page);
220 nod_flag=mi_test_if_nod(page);
223 if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
225 *ret_max_key= (uint) (end-page)/(keyinfo->keylength+nod_flag);
226 return (uint) (keypos-page)/(keyinfo->keylength+nod_flag);
233 if (!(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff))
239 *ret_max_key=max_key;
TODO: Rename this file - func.h is stupid.