22 uchar *key, uchar *keypos,
23 uint *return_key_length);
27 int _mi_check_index(
MI_INFO *info,
int inx)
33 my_errno= HA_ERR_WRONG_INDEX;
36 if (!mi_is_key_active(info->s->state.key_map, inx))
38 my_errno= info->s->state.state.records ? HA_ERR_WRONG_INDEX :
42 if (info->lastinx != inx)
46 info->update= ((info->update & (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED)) |
47 HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND);
49 if (info->opt_flag & WRITE_CACHE_USED && flush_io_cache(&info->rec_cache))
63 uchar *key, uint key_len, uint nextflag,
register my_off_t pos)
68 uchar *keypos,*maxpos;
69 uchar lastkey[MI_MAX_KEY_BUFF],*buff;
70 DBUG_ENTER(
"_mi_search");
71 DBUG_PRINT(
"enter",(
"pos: %lu nextflag: %u lastpos: %lu",
72 (ulong) pos, nextflag, (ulong) info->lastpos));
73 DBUG_EXECUTE(
"key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
75 if (pos == HA_OFFSET_ERROR)
77 my_errno=HA_ERR_KEY_NOT_FOUND;
78 info->lastpos= HA_OFFSET_ERROR;
79 if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
84 if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
85 test(!(nextflag & SEARCH_SAVE_BUFF)))))
87 DBUG_DUMP(
"page", buff, mi_getint(buff));
89 flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
90 &keypos,lastkey, &last_key);
91 if (flag == MI_FOUND_WRONG_KEY)
93 nod_flag=mi_test_if_nod(buff);
94 maxpos=buff+mi_getint(buff)-1;
98 if ((error=_mi_search(info,keyinfo,key,key_len,nextflag,
99 _mi_kpos(nod_flag,keypos))) <= 0)
104 if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
105 keypos == buff+2+nod_flag)
108 else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
113 if ((nextflag & SEARCH_FIND) && nod_flag &&
114 ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
115 key_len != USE_WHOLE_KEY))
117 if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
118 _mi_kpos(nod_flag,keypos))) >= 0 ||
119 my_errno != HA_ERR_KEY_NOT_FOUND)
121 info->last_keypage= HA_OFFSET_ERROR;
124 if (pos != info->last_keypage)
126 uchar *old_buff=buff;
127 if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
128 test(!(nextflag & SEARCH_SAVE_BUFF)))))
130 keypos=buff+(keypos-old_buff);
131 maxpos=buff+(maxpos-old_buff);
134 if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
137 if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos,
138 &info->lastkey_length))
140 if (!(nextflag & SEARCH_SMALLER) &&
141 ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
144 my_errno=HA_ERR_KEY_NOT_FOUND;
150 info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,lastkey);
151 if (!info->lastkey_length)
153 memcpy(info->lastkey,lastkey,info->lastkey_length);
155 info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
157 info->int_keypos=info->buff+ (keypos-buff);
158 info->int_maxpos=info->buff+ (maxpos-buff);
159 info->int_nod_flag=nod_flag;
160 info->int_keytree_version=keyinfo->version;
161 info->last_search_keypage=info->last_keypage;
162 info->page_changed=0;
163 info->buff_used= (info->buff != buff);
165 DBUG_PRINT(
"exit",(
"found key at %lu",(ulong) info->lastpos));
169 DBUG_PRINT(
"exit",(
"Error: %d",my_errno));
170 info->lastpos= HA_OFFSET_ERROR;
171 info->page_changed=1;
182 uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
183 uchar *buff __attribute__((unused)), my_bool *last_key)
185 reg4
int start,mid,end,save_end;
187 uint totlength,nod_flag,not_used[2];
188 DBUG_ENTER(
"_mi_bin_search");
191 totlength=keyinfo->keylength+(nod_flag=mi_test_if_nod(page));
193 save_end=end=(int) ((mi_getint(page)-2-nod_flag)/totlength-1);
194 DBUG_PRINT(
"test",(
"mi_getint: %d end: %d",mi_getint(page),end));
200 if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len,
201 comp_flag, not_used))
208 flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len,
209 comp_flag, not_used);
212 *ret_pos=page+(uint) start*totlength;
213 *last_key= end == save_end;
214 DBUG_PRINT(
"exit",(
"flag: %d keypos: %d",flag,start));
246 uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
247 uchar *buff, my_bool *last_key)
249 int UNINIT_VAR(flag);
250 uint nod_flag,UNINIT_VAR(length),not_used[2];
251 uchar t_buff[MI_MAX_KEY_BUFF],*end;
252 DBUG_ENTER(
"_mi_seq_search");
254 end= page+mi_getint(page);
255 nod_flag=mi_test_if_nod(page);
261 length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,t_buff);
262 if (length == 0 || page > end)
264 mi_print_error(info->s, HA_ERR_CRASHED);
265 my_errno=HA_ERR_CRASHED;
267 (
"Found wrong key: length: %u page: 0x%lx end: 0x%lx",
268 length, (
long) page, (
long) end));
269 DBUG_RETURN(MI_FOUND_WRONG_KEY);
271 if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
275 DBUG_PRINT(
"loop",(
"page: 0x%lx key: '%s' flag: %d", (
long) page, t_buff,
278 memcpy(buff,t_buff,length);
282 memcpy(buff,t_buff,length);
283 *last_key= page == end;
284 DBUG_PRINT(
"exit",(
"flag: %d ret_pos: 0x%lx", flag, (
long) *ret_pos));
289 int _mi_prefix_search(
MI_INFO *info,
register MI_KEYDEF *keyinfo, uchar *page,
290 uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
291 uchar *buff, my_bool *last_key)
298 int flag=0, my_flag=-1;
299 uint nod_flag, UNINIT_VAR(length), len, matched, cmplen, kseg_len;
300 uint UNINIT_VAR(prefix_len), suffix_len;
301 int key_len_skip, UNINIT_VAR(seg_len_pack), key_len_left;
302 uchar *end, *kseg, *vseg;
303 uchar *sort_order=keyinfo->seg->charset->sort_order;
304 uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
305 uchar *UNINIT_VAR(saved_from), *UNINIT_VAR(saved_to);
306 uchar *UNINIT_VAR(saved_vseg);
307 uint saved_length=0, saved_prefix_len=0;
309 DBUG_ENTER(
"_mi_prefix_search");
312 end= page+mi_getint(page);
313 nod_flag=mi_test_if_nod(page);
318 get_key_pack_length(kseg_len,length_pack,kseg);
319 key_len_skip=length_pack+kseg_len;
320 key_len_left=(int) key_len- (
int) key_len_skip;
322 cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack;
323 DBUG_PRINT(
"info",(
"key: '%.*s'",kseg_len,kseg));
343 uint packed= *page & 128;
346 if (keyinfo->seg->length >= 127)
348 suffix_len=mi_uint2korr(vseg) & 32767;
352 suffix_len= *vseg++ & 127;
364 prefix_len=suffix_len;
365 get_key_length(suffix_len,vseg);
374 len=prefix_len+suffix_len;
375 seg_len_pack=get_pack_length(len);
376 t_buff=tt_buff+3-seg_len_pack;
377 store_key_length(t_buff,len);
379 if (prefix_len > saved_prefix_len)
380 memcpy(t_buff+seg_len_pack+saved_prefix_len,saved_vseg,
381 prefix_len-saved_prefix_len);
383 saved_prefix_len=prefix_len;
385 DBUG_PRINT(
"loop",(
"page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,
388 uchar *from=vseg+suffix_len;
392 for (keyseg=keyinfo->seg+1 ; keyseg->type ; keyseg++ )
395 if (keyseg->flag & HA_NULL_PART)
400 if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
402 get_key_length(l,from);
409 from+=keyseg->length;
411 length= (uint) (from - vseg);
416 mi_print_error(info->s, HA_ERR_CRASHED);
417 my_errno=HA_ERR_CRASHED;
419 (
"Found wrong key: length: %u page: 0x%lx end: %lx",
420 length, (
long) page, (
long) end));
421 DBUG_RETURN(MI_FOUND_WRONG_KEY);
424 if (matched >= prefix_len)
428 uchar *k=kseg+prefix_len;
434 left= ((len <= cmplen) ? suffix_len :
435 ((prefix_len < cmplen) ? cmplen - prefix_len : 0));
437 matched=prefix_len+left;
441 for (my_flag=0;left;left--)
442 if ((my_flag= (
int) sort_order[*vseg++] - (int) sort_order[*k++]))
447 for (my_flag=0;left;left--)
448 if ((my_flag= (
int) *vseg++ - (int) *k++))
467 if ((keyinfo->seg->type != HA_KEYTYPE_TEXT &&
468 keyinfo->seg->type != HA_KEYTYPE_VARTEXT1 &&
469 keyinfo->seg->type != HA_KEYTYPE_VARTEXT2))
474 uchar *k_end= k+ (cmplen - len);
475 for ( ; k < k_end && *k ==
' '; k++) ;
478 if (*k < (uchar)
' ')
486 else if (len > cmplen)
489 if ((nextflag & SEARCH_PREFIX) && key_len_left == 0)
493 for (vseg_end= vseg + (len-cmplen) ;
494 vseg < vseg_end && *vseg == (uchar)
' ';
496 DBUG_ASSERT(vseg < vseg_end);
498 if (*vseg > (uchar)
' ')
511 if ((flag = ha_key_cmp(keyinfo->seg+1,vseg,
512 k, key_len_left, nextflag, not_used)) >= 0)
522 DBUG_ASSERT(flag <= 0);
523 if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST))
524 flag=(nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
534 memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
535 saved_to=buff+saved_length;
536 saved_from=saved_vseg;
541 flag=(keyinfo->seg->flag & HA_REVERSE_SORT) ? -my_flag : my_flag;
544 memcpy(buff,t_buff,saved_length=seg_len_pack+prefix_len);
545 saved_to=buff+saved_length;
546 saved_from=saved_vseg;
550 memcpy(saved_to,saved_from,saved_length);
552 *last_key= page == end;
554 DBUG_PRINT(
"exit",(
"flag: %d ret_pos: 0x%lx", flag, (
long) *ret_pos));
561 my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
567 return mi_uint7korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
569 return mi_uint6korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
571 return mi_uint5korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
581 return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
583 return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
585 return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
587 return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH;
590 return(HA_OFFSET_ERROR);
597 void _mi_kpointer(
register MI_INFO *info,
register uchar *buff, my_off_t pos)
599 pos/=MI_MIN_KEY_BLOCK_LENGTH;
600 switch (info->s->base.key_reflength) {
602 case 7: mi_int7store(buff,pos);
break;
603 case 6: mi_int6store(buff,pos);
break;
604 case 5: mi_int5store(buff,pos);
break;
613 case 4: mi_int4store(buff,pos);
break;
614 case 3: mi_int3store(buff,pos);
break;
615 case 2: mi_int2store(buff,(uint) pos);
break;
616 case 1: buff[0]= (uchar) pos;
break;
625 my_off_t _mi_dpos(
MI_INFO *info, uint nod_flag, uchar *after_key)
628 after_key-=(nod_flag + info->s->rec_reflength);
629 switch (info->s->rec_reflength) {
631 case 8: pos= (my_off_t) mi_uint8korr(after_key);
break;
632 case 7: pos= (my_off_t) mi_uint7korr(after_key);
break;
633 case 6: pos= (my_off_t) mi_uint6korr(after_key);
break;
634 case 5: pos= (my_off_t) mi_uint5korr(after_key);
break;
636 case 8: pos= (my_off_t) mi_uint4korr(after_key+4);
break;
637 case 7: pos= (my_off_t) mi_uint4korr(after_key+3);
break;
638 case 6: pos= (my_off_t) mi_uint4korr(after_key+2);
break;
639 case 5: pos= (my_off_t) mi_uint4korr(after_key+1);
break;
641 case 4: pos= (my_off_t) mi_uint4korr(after_key);
break;
642 case 3: pos= (my_off_t) mi_uint3korr(after_key);
break;
643 case 2: pos= (my_off_t) mi_uint2korr(after_key);
break;
647 return (info->s->options &
648 (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
649 pos*info->s->base.pack_reclength;
658 switch (s->rec_reflength) {
661 pos= (my_off_t) mi_uint8korr(ptr);
662 if (pos == HA_OFFSET_ERROR)
663 return HA_OFFSET_ERROR;
666 pos= (my_off_t) mi_uint7korr(ptr);
667 if (pos == (((my_off_t) 1) << 56) -1)
668 return HA_OFFSET_ERROR;
671 pos= (my_off_t) mi_uint6korr(ptr);
672 if (pos == (((my_off_t) 1) << 48) -1)
673 return HA_OFFSET_ERROR;
676 pos= (my_off_t) mi_uint5korr(ptr);
677 if (pos == (((my_off_t) 1) << 40) -1)
678 return HA_OFFSET_ERROR;
685 ptr+= (s->rec_reflength-4);
689 pos= (my_off_t) mi_uint4korr(ptr);
690 if (pos == (my_off_t) (uint32) ~0L)
691 return HA_OFFSET_ERROR;
694 pos= (my_off_t) mi_uint3korr(ptr);
695 if (pos == (my_off_t) (1 << 24) -1)
696 return HA_OFFSET_ERROR;
699 pos= (my_off_t) mi_uint2korr(ptr);
700 if (pos == (my_off_t) (1 << 16) -1)
701 return HA_OFFSET_ERROR;
705 return ((s->options &
706 (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? pos :
707 pos*s->base.pack_reclength);
713 void _mi_dpointer(
MI_INFO *info, uchar *buff, my_off_t pos)
715 if (!(info->s->options &
716 (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
717 pos != HA_OFFSET_ERROR)
718 pos/=info->s->base.pack_reclength;
720 switch (info->s->rec_reflength) {
722 case 8: mi_int8store(buff,pos);
break;
723 case 7: mi_int7store(buff,pos);
break;
724 case 6: mi_int6store(buff,pos);
break;
725 case 5: mi_int5store(buff,pos);
break;
736 case 4: mi_int4store(buff,pos);
break;
737 case 3: mi_int3store(buff,pos);
break;
738 case 2: mi_int2store(buff,(uint) pos);
break;
752 uint _mi_get_static_key(
register MI_KEYDEF *keyinfo, uint nod_flag,
753 register uchar **page,
register uchar *key)
755 memcpy((uchar*) key,(uchar*) *page,
756 (
size_t) (keyinfo->keylength+nod_flag));
757 *page+=keyinfo->keylength+nod_flag;
758 return(keyinfo->keylength);
776 uint _mi_get_pack_key(
register MI_KEYDEF *keyinfo, uint nod_flag,
777 register uchar **page_pos,
register uchar *key)
780 uchar *start_key,*page=*page_pos;
784 for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
786 if (keyseg->flag & HA_PACK_KEY)
790 uint packed= *page & 128,tot_length,rest_length;
791 if (keyseg->length >= 127)
793 length=mi_uint2korr(page) & 32767;
797 length= *page++ & 127;
801 if (length > (uint) keyseg->length)
803 mi_print_error(keyinfo->share, HA_ERR_CRASHED);
804 my_errno=HA_ERR_CRASHED;
809 if (keyseg->flag & HA_NULL_PART)
811 get_key_length(length,key);
813 if (length > keyseg->length)
816 (
"Found too long null packed key: %u of %u at 0x%lx",
817 length, keyseg->length, (
long) *page_pos));
818 DBUG_DUMP(
"key", *page_pos, 16);
819 mi_print_error(keyinfo->share, HA_ERR_CRASHED);
820 my_errno=HA_ERR_CRASHED;
825 if (keyseg->flag & HA_NULL_PART)
831 get_key_length(rest_length,page);
832 tot_length=rest_length+length;
835 if (tot_length >= 255 && *start != 255)
838 bmove_upp(key+length+3, key+length+1, length);
840 mi_int2store(key+1,tot_length);
843 else if (tot_length < 255 && *start == 255)
845 bmove(key+1,key+3,length);
851 store_key_length_inc(key,tot_length);
854 memcpy(key,page,rest_length);
861 if (keyseg->flag & HA_NULL_PART)
871 if (length > (uint) keyseg->length)
873 DBUG_PRINT(
"error",(
"Found too long packed key: %u of %u at 0x%lx",
874 length, keyseg->length, (
long) *page_pos));
875 DBUG_DUMP(
"key", *page_pos, 16);
876 mi_print_error(keyinfo->share, HA_ERR_CRASHED);
877 my_errno=HA_ERR_CRASHED;
880 store_key_length_inc(key,length);
884 if (keyseg->flag & HA_NULL_PART)
886 if (!(*key++ = *page++))
890 (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
893 get_key_length(length,tmp);
894 length+=(uint) (tmp-page);
897 length=keyseg->length;
899 memcpy((uchar*) key,(uchar*) page,(
size_t) length);
903 length=keyseg->length+nod_flag;
904 bmove((uchar*) key,(uchar*) page,length);
905 *page_pos= page+length;
906 return ((uint) (key-start_key)+keyseg->length);
913 uint _mi_get_binary_pack_key(
register MI_KEYDEF *keyinfo, uint nod_flag,
914 register uchar **page_pos,
register uchar *key)
917 uchar *start_key,*
page,*page_end,*from,*from_end;
919 DBUG_ENTER(
"_mi_get_binary_pack_key");
922 page_end=page+MI_MAX_KEY_BUFF+1;
939 get_key_length(length,page);
942 if (length > keyinfo->maxlength)
945 (
"Found too long binary packed key: %u of %u at 0x%lx",
946 length, keyinfo->maxlength, (
long) *page_pos));
947 DBUG_DUMP(
"key", *page_pos, 16);
952 from_end= key + length;
968 for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
970 if (keyseg->flag & HA_NULL_PART)
973 if (from == from_end) { from=
page; from_end=page_end; }
974 if (!(*key++ = *from++))
977 if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
980 if (from == from_end) { from=
page; from_end=page_end; }
982 if ((length= (*key++ = *from++)) == 255)
985 if (from == from_end) { from=
page; from_end=page_end; }
986 length= (uint) ((*key++ = *from++)) << 8;
988 if (from == from_end) { from=
page; from_end=page_end; }
989 length+= (uint) ((*key++ = *from++));
991 if (length > keyseg->length)
995 length=keyseg->length;
997 if ((tmp=(uint) (from_end-from)) <= length)
1001 from=
page; from_end=page_end;
1003 DBUG_PRINT(
"info",(
"key: 0x%lx from: 0x%lx length: %u",
1004 (
long) key, (
long) from, length));
1005 memmove((uchar*) key, (uchar*) from, (
size_t) length);
1014 length=keyseg->length+nod_flag;
1015 if ((tmp=(uint) (from_end-from)) <= length)
1018 memcpy(key+tmp,page,length-tmp);
1019 *page_pos= page+length-tmp;
1029 if (from_end != page_end)
1031 DBUG_PRINT(
"error",(
"Error when unpacking key"));
1035 memcpy((uchar*) key,(uchar*) from,(
size_t) length);
1036 *page_pos= from+length;
1038 DBUG_RETURN((uint) (key-start_key)+keyseg->length);
1041 mi_print_error(keyinfo->share, HA_ERR_CRASHED);
1042 my_errno= HA_ERR_CRASHED;
1051 uchar *key, uchar *keypos, uint *return_key_length)
1054 DBUG_ENTER(
"_mi_get_key");
1056 nod_flag=mi_test_if_nod(page);
1057 if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1059 bmove((uchar*) key,(uchar*) keypos,keyinfo->keylength+nod_flag);
1060 DBUG_RETURN(keypos+keyinfo->keylength+nod_flag);
1066 while (page <= keypos)
1068 *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
1069 if (*return_key_length == 0)
1071 mi_print_error(info->s, HA_ERR_CRASHED);
1072 my_errno=HA_ERR_CRASHED;
1077 DBUG_PRINT(
"exit",(
"page: 0x%lx length: %u", (
long) page,
1078 *return_key_length));
1086 static my_bool _mi_get_prev_key(
MI_INFO *info,
MI_KEYDEF *keyinfo, uchar *page,
1087 uchar *key, uchar *keypos,
1088 uint *return_key_length)
1091 DBUG_ENTER(
"_mi_get_prev_key");
1093 nod_flag=mi_test_if_nod(page);
1094 if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1096 *return_key_length=keyinfo->keylength;
1097 bmove((uchar*) key,(uchar*) keypos- *return_key_length-nod_flag,
1098 *return_key_length);
1105 while (page < keypos)
1107 *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,key);
1108 if (*return_key_length == 0)
1110 mi_print_error(info->s, HA_ERR_CRASHED);
1111 my_errno=HA_ERR_CRASHED;
1125 uchar *lastkey, uchar *endpos, uint *return_key_length)
1129 DBUG_ENTER(
"_mi_get_last_key");
1130 DBUG_PRINT(
"enter",(
"page: 0x%lx endpos: 0x%lx", (
long) page,
1133 nod_flag=mi_test_if_nod(page);
1134 if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1136 lastpos=endpos-keyinfo->keylength-nod_flag;
1137 *return_key_length=keyinfo->keylength;
1139 bmove((uchar*) lastkey,(uchar*) lastpos,keyinfo->keylength+nod_flag);
1143 lastpos=(page+=2+nod_flag);
1145 while (page < endpos)
1148 *return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey);
1149 if (*return_key_length == 0)
1151 DBUG_PRINT(
"error",(
"Couldn't find last key: page: 0x%lx",
1153 mi_print_error(info->s, HA_ERR_CRASHED);
1154 my_errno=HA_ERR_CRASHED;
1159 DBUG_PRINT(
"exit",(
"lastpos: 0x%lx length: %u", (
long) lastpos,
1160 *return_key_length));
1161 DBUG_RETURN(lastpos);
1167 uint _mi_keylength(
MI_KEYDEF *keyinfo,
register uchar *key)
1172 if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1173 return (keyinfo->keylength);
1176 for (keyseg=keyinfo->seg ; keyseg->type ; keyseg++)
1178 if (keyseg->flag & HA_NULL_PART)
1181 if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART))
1184 get_key_length(length,key);
1188 key+= keyseg->length;
1190 return((uint) (key-start)+keyseg->length);
1202 uint _mi_keylength_part(
MI_KEYDEF *keyinfo,
register uchar *key,
1208 for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++)
1210 if (keyseg->flag & HA_NULL_PART)
1213 if (keyseg->flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART))
1216 get_key_length(length,key);
1220 key+= keyseg->length;
1222 return (uint) (key-start);
1227 uchar *_mi_move_key(
MI_KEYDEF *keyinfo, uchar *
to, uchar *from)
1230 memcpy((uchar*) to, (uchar*) from,
1231 (
size_t) (length=_mi_keylength(keyinfo,from)));
1239 uchar *key, uint key_length, uint nextflag, my_off_t pos)
1243 uchar lastkey[MI_MAX_KEY_BUFF];
1244 DBUG_ENTER(
"_mi_search_next");
1245 DBUG_PRINT(
"enter",(
"nextflag: %u lastpos: %lu int_keypos: %lu",
1246 nextflag, (ulong) info->lastpos,
1247 (ulong) info->int_keypos));
1248 DBUG_EXECUTE(
"key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
1257 if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
1258 info->page_changed ||
1259 (info->int_keytree_version != keyinfo->version &&
1260 (info->int_nod_flag || info->buff_used)))
1261 DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1262 nextflag | SEARCH_SAVE_BUFF, pos));
1264 if (info->buff_used)
1266 if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
1267 DFLT_INIT_HITS,info->buff,0))
1273 nod_flag=mi_test_if_nod(info->buff);
1275 if (nextflag & SEARCH_BIGGER)
1277 my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
1278 if (tmp_pos != HA_OFFSET_ERROR)
1280 if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1281 nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
1284 memcpy(lastkey,key,key_length);
1285 if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
1286 &info->int_keypos,lastkey)))
1293 info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
1294 info->int_keypos, &length);
1295 if (!info->int_keypos)
1297 if (info->int_keypos == info->buff+2)
1298 DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1299 nextflag | SEARCH_SAVE_BUFF, pos));
1300 if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1301 nextflag | SEARCH_SAVE_BUFF,
1302 _mi_kpos(nod_flag,info->int_keypos))) <= 0)
1306 if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
1307 info->int_keypos,&info->lastkey_length))
1310 memcpy(info->lastkey,lastkey,info->lastkey_length);
1311 info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1312 DBUG_PRINT(
"exit",(
"found key at %lu",(ulong) info->lastpos));
1321 register my_off_t pos)
1325 DBUG_ENTER(
"_mi_search_first");
1327 if (pos == HA_OFFSET_ERROR)
1329 my_errno=HA_ERR_KEY_NOT_FOUND;
1330 info->lastpos= HA_OFFSET_ERROR;
1336 if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0))
1338 info->lastpos= HA_OFFSET_ERROR;
1341 nod_flag=mi_test_if_nod(info->buff);
1342 page=info->buff+2+nod_flag;
1343 }
while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
1345 if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
1349 info->int_keypos=
page; info->int_maxpos=info->buff+mi_getint(info->buff)-1;
1350 info->int_nod_flag=nod_flag;
1351 info->int_keytree_version=keyinfo->version;
1352 info->last_search_keypage=info->last_keypage;
1353 info->page_changed=info->buff_used=0;
1354 info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1356 DBUG_PRINT(
"exit",(
"found key at %lu", (ulong) info->lastpos));
1365 register my_off_t pos)
1369 DBUG_ENTER(
"_mi_search_last");
1371 if (pos == HA_OFFSET_ERROR)
1373 my_errno=HA_ERR_KEY_NOT_FOUND;
1374 info->lastpos= HA_OFFSET_ERROR;
1381 if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
1383 info->lastpos= HA_OFFSET_ERROR;
1386 page= buff+mi_getint(buff);
1387 nod_flag=mi_test_if_nod(buff);
1388 }
while ((pos=_mi_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
1390 if (!_mi_get_last_key(info,keyinfo,buff,info->lastkey,page,
1391 &info->lastkey_length))
1393 info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1394 info->int_keypos=info->int_maxpos=
page;
1395 info->int_nod_flag=nod_flag;
1396 info->int_keytree_version=keyinfo->version;
1397 info->last_search_keypage=info->last_keypage;
1398 info->page_changed=info->buff_used=0;
1400 DBUG_PRINT(
"exit",(
"found key at %lu",(ulong) info->lastpos));
1422 _mi_calc_static_key_length(
MI_KEYDEF *keyinfo,uint nod_flag,
1423 uchar *next_pos __attribute__((unused)),
1424 uchar *org_key __attribute__((unused)),
1425 uchar *prev_key __attribute__((unused)),
1429 return (
int) (s_temp->totlength=keyinfo->keylength+nod_flag);
1435 _mi_calc_var_key_length(
MI_KEYDEF *keyinfo,uint nod_flag,
1436 uchar *next_pos __attribute__((unused)),
1437 uchar *org_key __attribute__((unused)),
1438 uchar *prev_key __attribute__((unused)),
1442 return (
int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag);
1465 _mi_calc_var_pack_key_length(
MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
1466 uchar *org_key, uchar *prev_key, uchar *key,
1471 uint key_length,ref_length,org_key_length=0,
1472 length_pack,new_key_length,diff_flag,pack_marker;
1473 uchar *start,*end,*key_end,*sort_order;
1474 my_bool same_length;
1476 length_pack=s_temp->ref_length=s_temp->n_ref_length=s_temp->n_length=0;
1477 same_length=0; keyseg=keyinfo->seg;
1478 key_length=_mi_keylength(keyinfo,key)+nod_flag;
1481 if ((keyinfo->flag & HA_FULLTEXT) &&
1482 ((keyseg->type == HA_KEYTYPE_TEXT) ||
1483 (keyseg->type == HA_KEYTYPE_VARTEXT1) ||
1484 (keyseg->type == HA_KEYTYPE_VARTEXT2)) &&
1485 !use_strnxfrm(keyseg->charset))
1486 sort_order=keyseg->charset->sort_order;
1489 if (keyseg->length >= 127)
1499 s_temp->pack_marker=pack_marker;
1502 if (keyseg->flag & HA_NULL_PART)
1507 s_temp->key_length= 0;
1508 s_temp->totlength=key_length-1+diff_flag;
1509 s_temp->next_key_pos=0;
1510 return (s_temp->totlength);
1512 s_temp->store_not_null=1;
1514 if (prev_key && !*prev_key++)
1520 s_temp->store_not_null=0;
1521 s_temp->prev_key=org_key;
1525 get_key_pack_length(new_key_length,length_pack,key);
1526 end=key_end= key+ new_key_length;
1532 get_key_length(org_key_length,prev_key);
1533 s_temp->prev_key=prev_key;
1535 if (new_key_length && new_key_length == org_key_length)
1537 else if (new_key_length > org_key_length)
1538 end=key + org_key_length;
1542 while (key < end && sort_order[*key] == sort_order[*prev_key])
1549 while (key < end && *key == *prev_key)
1557 s_temp->key_length= (uint) (key_end-key);
1559 if (same_length && key == key_end)
1562 s_temp->ref_length= pack_marker;
1563 length=(int) key_length-(
int) (key_end-start)-length_pack;
1567 s_temp->n_length= *next_key;
1575 ref_length= (uint) (key-start);
1576 s_temp->ref_length= ref_length + pack_marker;
1577 length= (int) (key_length - ref_length);
1579 length-= length_pack;
1581 length+= ((new_key_length-ref_length) >= 255) ? 3 : 1;
1585 s_temp->key_length+=s_temp->store_not_null;
1586 length= key_length - length_pack+ diff_flag;
1589 s_temp->totlength=(uint) length;
1590 s_temp->prev_length=0;
1591 DBUG_PRINT(
"test",(
"tot_length: %u length: %d uniq_key_length: %u",
1592 key_length, length, s_temp->key_length));
1595 if ((s_temp->next_key_pos=next_key))
1597 uint packed,n_length;
1599 packed = *next_key & 128;
1602 n_length= mi_uint2korr(next_key) & 32767;
1606 n_length= *next_key++ & 127;
1608 n_length-= s_temp->store_not_null;
1610 if (n_length || packed)
1612 uint next_length_pack, new_ref_length=s_temp->ref_length;
1617 if (!prev_key && org_key)
1619 get_key_length(org_key_length,org_key);
1623 while (key < end && sort_order[*key] == sort_order[*org_key])
1630 while (key < end && *key == *org_key)
1635 if ((new_ref_length= (uint) (key - start)))
1636 new_ref_length+=pack_marker;
1647 s_temp->part_of_prev_key= new_ref_length;
1648 s_temp->prev_length= org_key_length -
1649 (new_ref_length-pack_marker);
1650 s_temp->n_ref_length= s_temp->part_of_prev_key;
1651 s_temp->n_length= s_temp->prev_length;
1652 n_length= get_pack_length(s_temp->prev_length);
1653 s_temp->prev_key+= (new_ref_length - pack_marker);
1654 length+= s_temp->prev_length + n_length;
1658 s_temp->part_of_prev_key=0;
1659 s_temp->prev_length= org_key_length;
1660 s_temp->n_ref_length=s_temp->n_length= org_key_length;
1661 length+= org_key_length;
1663 return (
int) length;
1666 ref_length=n_length;
1668 get_key_pack_length(n_length,next_length_pack,next_key);
1671 if (!new_ref_length)
1673 s_temp->part_of_prev_key= 0;
1674 s_temp->prev_length= ref_length;
1675 s_temp->n_ref_length= s_temp->n_length= n_length+ref_length;
1676 return (
int) length+ref_length-next_length_pack;
1678 if (ref_length+pack_marker > new_ref_length)
1680 uint new_pack_length=new_ref_length-pack_marker;
1682 s_temp->part_of_prev_key= new_ref_length;
1683 s_temp->prev_length= ref_length - new_pack_length;
1684 s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length;
1685 s_temp->prev_key+= new_pack_length;
1686 length-= (next_length_pack - get_pack_length(s_temp->n_length));
1687 return (
int) length + s_temp->prev_length;
1696 DBUG_PRINT(
"test",(
"length: %d next_key: 0x%lx", length,
1701 key=(start+=ref_length);
1702 if (key+n_length < key_end)
1703 key_end=key+n_length;
1706 while (key < key_end && sort_order[*key] ==
1707 sort_order[*next_key])
1714 while (key < key_end && *key == *next_key)
1719 if (!(tmp_length=(uint) (key-start)))
1721 s_temp->next_key_pos=0;
1724 ref_length+=tmp_length;
1725 n_length-=tmp_length;
1726 length-=tmp_length+next_length_pack;
1728 if (n_length == 0 && ref_length == new_key_length)
1730 s_temp->n_ref_length=pack_marker;
1734 s_temp->n_ref_length=ref_length | pack_marker;
1735 length+= get_pack_length(n_length);
1736 s_temp->n_length=n_length;
1747 _mi_calc_bin_pack_key_length(
MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
1748 uchar *org_key, uchar *prev_key, uchar *key,
1751 uint length,key_length,ref_length;
1753 s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
1755 s_temp->n_length= s_temp->n_ref_length=0;
1758 s_temp->prev_key=org_key;
1768 for ( ; *key == *prev_key && key < end; key++,prev_key++) ;
1769 s_temp->ref_length= ref_length=(uint) (key-s_temp->key);
1770 length=key_length - ref_length + get_pack_length(ref_length);
1775 s_temp->ref_length=ref_length=0;
1776 length=key_length+1;
1778 if ((s_temp->next_key_pos=next_key))
1781 uint next_length,next_length_pack;
1782 get_key_pack_length(next_length,next_length_pack,next_key);
1785 if (!prev_key && org_key && next_length)
1788 for (key= s_temp->key, end=key+next_length ;
1789 *key == *org_key && key < end;
1791 ref_length= (uint) (key - s_temp->key);
1794 if (next_length > ref_length)
1799 s_temp->n_ref_length= ref_length;
1800 s_temp->prev_length= next_length-ref_length;
1801 s_temp->prev_key+= ref_length;
1802 return (
int) (length+ s_temp->prev_length - next_length_pack +
1803 get_pack_length(ref_length));
1806 key= s_temp->key+next_length;
1807 while (*key++ == *next_key++) ;
1808 if ((ref_length= (uint) (key - s_temp->key)-1) == next_length)
1810 s_temp->next_key_pos=0;
1813 s_temp->prev_length=0;
1814 s_temp->n_ref_length=ref_length;
1815 return (
int) (length-(ref_length - next_length) - next_length_pack +
1816 get_pack_length(ref_length));
1818 return (
int) length;
1828 void _mi_store_static_key(
MI_KEYDEF *keyinfo __attribute__((unused)),
1829 register uchar *key_pos,
1832 memcpy((uchar*) key_pos,(uchar*) s_temp->key,(
size_t) s_temp->totlength);
1838 #define store_pack_length(test,pos,length) { \
1839 if (test) { *((pos)++) = (uchar) (length); } else \
1840 { *((pos)++) = (uchar) ((length) >> 8); *((pos)++) = (uchar) (length); } }
1843 void _mi_store_var_pack_key(
MI_KEYDEF *keyinfo __attribute__((unused)),
1844 register uchar *key_pos,
1852 if (s_temp->ref_length)
1855 store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->ref_length);
1857 if (s_temp->ref_length != s_temp->pack_marker)
1858 store_key_length_inc(key_pos,s_temp->key_length);
1863 store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length);
1865 bmove((uchar*) key_pos,(uchar*) s_temp->key,
1866 (length=s_temp->totlength-(uint) (key_pos-start)));
1868 if (!s_temp->next_key_pos)
1872 if (s_temp->prev_length)
1875 if (s_temp->part_of_prev_key)
1877 store_pack_length(s_temp->pack_marker == 128,key_pos,
1878 s_temp->part_of_prev_key);
1879 store_key_length_inc(key_pos,s_temp->n_length);
1883 s_temp->n_length+= s_temp->store_not_null;
1884 store_pack_length(s_temp->pack_marker == 128,key_pos,
1887 memcpy(key_pos, s_temp->prev_key, s_temp->prev_length);
1889 else if (s_temp->n_ref_length)
1891 store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_ref_length);
1892 if (s_temp->n_ref_length == s_temp->pack_marker)
1894 store_key_length(key_pos,s_temp->n_length);
1898 s_temp->n_length+= s_temp->store_not_null;
1899 store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->n_length);
1906 void _mi_store_bin_pack_key(
MI_KEYDEF *keyinfo __attribute__((unused)),
1907 register uchar *key_pos,
1910 store_key_length_inc(key_pos,s_temp->ref_length);
1911 memcpy((
char*) key_pos,(
char*) s_temp->key+s_temp->ref_length,
1912 (
size_t) s_temp->totlength-s_temp->ref_length);
1914 if (s_temp->next_key_pos)
1916 key_pos+=(uint) (s_temp->totlength-s_temp->ref_length);
1917 store_key_length_inc(key_pos,s_temp->n_ref_length);
1918 if (s_temp->prev_length)
1920 memcpy(key_pos,s_temp->prev_key,s_temp->prev_length);