12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
/* key handling functions */
18
#include "myisam_priv.h"
19
#include <drizzled/charset_info.h>
20
#include <drizzled/internal/m_string.h>
21
#include <drizzled/util/test.h>
23
using namespace drizzled;
25
static bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
26
unsigned char *key, unsigned char *keypos,
27
uint32_t *return_key_length);
18
#include "myisamdef.h"
21
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
22
uchar *key, uchar *keypos,
23
uint *return_key_length);
35
31
if (inx < 0 || ! mi_is_key_active(info->s->state.key_map, inx))
37
errno=HA_ERR_WRONG_INDEX;
33
my_errno=HA_ERR_WRONG_INDEX;
40
36
if (info->lastinx != inx) /* Index changed */
60
56
int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
61
unsigned char *key, uint32_t key_len, uint32_t nextflag, register internal::my_off_t pos)
57
uchar *key, uint key_len, uint nextflag, register my_off_t pos)
66
unsigned char *keypos,*maxpos;
67
unsigned char lastkey[MI_MAX_KEY_BUFF],*buff;
62
uchar *keypos,*maxpos;
63
uchar lastkey[MI_MAX_KEY_BUFF],*buff;
69
65
if (pos == HA_OFFSET_ERROR)
71
errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
67
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
72
68
info->lastpos= HA_OFFSET_ERROR;
73
69
if (!(nextflag & (SEARCH_SMALLER | SEARCH_BIGGER | SEARCH_LAST)))
74
70
return(-1); /* Not found ; return error */
110
106
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
111
107
_mi_kpos(nod_flag,keypos))) >= 0 ||
112
errno != HA_ERR_KEY_NOT_FOUND)
108
my_errno != HA_ERR_KEY_NOT_FOUND)
114
110
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
117
113
if (pos != info->last_keypage)
119
unsigned char *old_buff=buff;
115
uchar *old_buff=buff;
120
116
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
121
117
test(!(nextflag & SEARCH_SAVE_BUFF)))))
127
123
if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
129
uint32_t not_used[2];
130
126
if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos,
131
127
&info->lastkey_length))
134
130
ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND,
137
errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
133
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
169
165
/* ret_pos point to where find or bigger key starts */
172
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
173
unsigned char *key, uint32_t key_len, uint32_t comp_flag, unsigned char **ret_pos,
174
unsigned char *buff, bool *last_key)
168
int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
169
uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
170
uchar *buff __attribute__((unused)), my_bool *last_key)
177
172
register int start,mid,end,save_end;
179
uint32_t totlength,nod_flag,not_used[2];
174
uint totlength,nod_flag,not_used[2];
181
176
totlength=keyinfo->keylength+(nod_flag=mi_test_if_nod(page));
233
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
234
unsigned char *key, uint32_t key_len, uint32_t comp_flag, unsigned char **ret_pos,
235
unsigned char *buff, bool *last_key)
228
int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
229
uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
230
uchar *buff, my_bool *last_key)
238
uint32_t nod_flag,length=0,not_used[2];
239
unsigned char t_buff[MI_MAX_KEY_BUFF],*end;
233
uint nod_flag,length=0,not_used[2];
234
uchar t_buff[MI_MAX_KEY_BUFF],*end;
241
236
end= page+mi_getint(page);
242
237
nod_flag=mi_test_if_nod(page);
249
244
if (length == 0 || page > end)
251
246
mi_print_error(info->s, HA_ERR_CRASHED);
252
errno=HA_ERR_CRASHED;
247
my_errno=HA_ERR_CRASHED;
253
248
return(MI_FOUND_WRONG_KEY);
255
250
if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
265
260
} /* _mi_seq_search */
268
int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, unsigned char *page,
269
unsigned char *key, uint32_t key_len, uint32_t nextflag, unsigned char **ret_pos,
270
unsigned char *buff, bool *last_key)
263
int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
264
uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
265
uchar *buff, my_bool *last_key)
273
268
my_flag is raw comparison result to be changed according to
275
270
flag is the value returned by ha_key_cmp and as treated as final
277
272
int flag=0, my_flag=-1;
278
uint32_t nod_flag, length=0, len, matched, cmplen, kseg_len;
279
uint32_t prefix_len=0,suffix_len;
273
uint nod_flag, length=0, len, matched, cmplen, kseg_len;
274
uint prefix_len=0,suffix_len;
280
275
int key_len_skip, seg_len_pack=0, key_len_left;
281
unsigned char *end, *kseg, *vseg;
282
unsigned char *sort_order=keyinfo->seg->charset->sort_order;
283
unsigned char tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
284
unsigned char *saved_from=NULL, *saved_to=NULL, *saved_vseg=NULL;
285
uint32_t saved_length=0, saved_prefix_len=0;
286
uint32_t length_pack;
276
uchar *end, *kseg, *vseg;
277
uchar *sort_order=keyinfo->seg->charset->sort_order;
278
uchar tt_buff[MI_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
279
uchar *saved_from=NULL, *saved_to=NULL, *saved_vseg=NULL;
280
uint saved_length=0, saved_prefix_len=0;
289
284
t_buff[0]=0; /* Avoid bugs */
391
386
mi_print_error(info->s, HA_ERR_CRASHED);
392
errno=HA_ERR_CRASHED;
387
my_errno=HA_ERR_CRASHED;
393
388
return(MI_FOUND_WRONG_KEY);
396
391
if (matched >= prefix_len)
398
393
/* We have to compare. But we can still skip part of the key */
400
unsigned char *k=kseg+prefix_len;
395
uchar *k=kseg+prefix_len;
403
398
If prefix_len > cmplen then we are in the end-space comparison
445
440
/* We have to compare k and vseg as if they were space extended */
446
unsigned char *k_end= k+ (cmplen - len);
441
uchar *k_end= k+ (cmplen - len);
447
442
for ( ; k < k_end && *k == ' '; k++) ;
449
444
goto cmp_rest; /* should never happen */
450
if (*k < (unsigned char) ' ')
445
if (*k < (uchar) ' ')
452
447
my_flag= 1; /* Compared string is smaller */
458
453
else if (len > cmplen)
460
unsigned char *vseg_end;
461
456
if ((nextflag & SEARCH_PREFIX) && key_len_left == 0)
464
459
/* We have to compare k and vseg as if they were space extended */
465
460
for (vseg_end= vseg + (len-cmplen) ;
466
vseg < vseg_end && *vseg == (unsigned char) ' ';
461
vseg < vseg_end && *vseg == (uchar) ' ';
467
462
vseg++, matched++) ;
468
463
assert(vseg < vseg_end);
470
if (*vseg > (unsigned char) ' ')
465
if (*vseg > (uchar) ' ')
472
467
my_flag= 1; /* Compared string is smaller */
552
return ((internal::my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
547
return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
554
return ((internal::my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
549
return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
556
return (internal::my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
551
return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
558
553
return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH;
559
554
case 0: /* At leaf page */
566
561
/* Save pos to a key_block */
568
void _mi_kpointer(register MI_INFO *info, register unsigned char *buff, internal::my_off_t pos)
563
void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
570
565
pos/=MI_MIN_KEY_BLOCK_LENGTH;
571
566
switch (info->s->base.key_reflength) {
584
579
case 4: mi_int4store(buff,pos); break;
585
580
case 3: mi_int3store(buff,pos); break;
586
581
case 2: mi_int2store(buff,(uint) pos); break;
587
case 1: buff[0]= (unsigned char) pos; break;
582
case 1: buff[0]= (uchar) pos; break;
588
583
default: abort(); /* impossible */
590
585
} /* _mi_kpointer */
593
588
/* Calc pos to a data-record from a key */
596
internal::my_off_t _mi_dpos(MI_INFO *info, uint32_t nod_flag, unsigned char *after_key)
591
my_off_t _mi_dpos(MI_INFO *info, uint nod_flag, uchar *after_key)
598
internal::my_off_t pos;
599
594
after_key-=(nod_flag + info->s->rec_reflength);
600
595
switch (info->s->rec_reflength) {
601
596
#if SIZEOF_OFF_T > 4
602
case 8: pos= (internal::my_off_t) mi_uint8korr(after_key); break;
603
case 7: pos= (internal::my_off_t) mi_uint7korr(after_key); break;
604
case 6: pos= (internal::my_off_t) mi_uint6korr(after_key); break;
605
case 5: pos= (internal::my_off_t) mi_uint5korr(after_key); break;
597
case 8: pos= (my_off_t) mi_uint8korr(after_key); break;
598
case 7: pos= (my_off_t) mi_uint7korr(after_key); break;
599
case 6: pos= (my_off_t) mi_uint6korr(after_key); break;
600
case 5: pos= (my_off_t) mi_uint5korr(after_key); break;
607
case 8: pos= (internal::my_off_t) mi_uint4korr(after_key+4); break;
608
case 7: pos= (internal::my_off_t) mi_uint4korr(after_key+3); break;
609
case 6: pos= (internal::my_off_t) mi_uint4korr(after_key+2); break;
610
case 5: pos= (internal::my_off_t) mi_uint4korr(after_key+1); break;
602
case 8: pos= (my_off_t) mi_uint4korr(after_key+4); break;
603
case 7: pos= (my_off_t) mi_uint4korr(after_key+3); break;
604
case 6: pos= (my_off_t) mi_uint4korr(after_key+2); break;
605
case 5: pos= (my_off_t) mi_uint4korr(after_key+1); break;
612
case 4: pos= (internal::my_off_t) mi_uint4korr(after_key); break;
613
case 3: pos= (internal::my_off_t) mi_uint3korr(after_key); break;
614
case 2: pos= (internal::my_off_t) mi_uint2korr(after_key); break;
607
case 4: pos= (my_off_t) mi_uint4korr(after_key); break;
608
case 3: pos= (my_off_t) mi_uint3korr(after_key); break;
609
case 2: pos= (my_off_t) mi_uint2korr(after_key); break;
616
611
pos=0L; /* Shut compiler up */
624
619
/* Calc position from a record pointer ( in delete link chain ) */
626
internal::my_off_t _mi_rec_pos(MYISAM_SHARE *s, unsigned char *ptr)
621
my_off_t _mi_rec_pos(MYISAM_SHARE *s, uchar *ptr)
628
internal::my_off_t pos;
629
624
switch (s->rec_reflength) {
630
625
#if SIZEOF_OFF_T > 4
632
pos= (internal::my_off_t) mi_uint8korr(ptr);
627
pos= (my_off_t) mi_uint8korr(ptr);
633
628
if (pos == HA_OFFSET_ERROR)
634
629
return HA_OFFSET_ERROR; /* end of list */
637
pos= (internal::my_off_t) mi_uint7korr(ptr);
638
if (pos == (((internal::my_off_t) 1) << 56) -1)
632
pos= (my_off_t) mi_uint7korr(ptr);
633
if (pos == (((my_off_t) 1) << 56) -1)
639
634
return HA_OFFSET_ERROR; /* end of list */
642
pos= (internal::my_off_t) mi_uint6korr(ptr);
643
if (pos == (((internal::my_off_t) 1) << 48) -1)
637
pos= (my_off_t) mi_uint6korr(ptr);
638
if (pos == (((my_off_t) 1) << 48) -1)
644
639
return HA_OFFSET_ERROR; /* end of list */
647
pos= (internal::my_off_t) mi_uint5korr(ptr);
648
if (pos == (((internal::my_off_t) 1) << 40) -1)
642
pos= (my_off_t) mi_uint5korr(ptr);
643
if (pos == (((my_off_t) 1) << 40) -1)
649
644
return HA_OFFSET_ERROR; /* end of list */
657
652
/* fall through */
660
pos= (internal::my_off_t) mi_uint4korr(ptr);
661
if (pos == (internal::my_off_t) UINT32_MAX)
655
pos= (my_off_t) mi_uint4korr(ptr);
656
if (pos == (my_off_t) (uint32) ~0L)
662
657
return HA_OFFSET_ERROR;
665
pos= (internal::my_off_t) mi_uint3korr(ptr);
666
if (pos == (internal::my_off_t) (1 << 24) -1)
660
pos= (my_off_t) mi_uint3korr(ptr);
661
if (pos == (my_off_t) (1 << 24) -1)
667
662
return HA_OFFSET_ERROR;
670
pos= (internal::my_off_t) mi_uint2korr(ptr);
671
if (pos == (internal::my_off_t) (1 << 16) -1)
665
pos= (my_off_t) mi_uint2korr(ptr);
666
if (pos == (my_off_t) (1 << 16) -1)
672
667
return HA_OFFSET_ERROR;
674
669
default: abort(); /* Impossible */
682
677
/* save position to record */
684
void _mi_dpointer(MI_INFO *info, unsigned char *buff, internal::my_off_t pos)
679
void _mi_dpointer(MI_INFO *info, uchar *buff, my_off_t pos)
686
681
if (!(info->s->options &
687
682
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) &&
721
716
/* same as _mi_get_key but used with fixed length keys */
723
uint32_t _mi_get_static_key(register MI_KEYDEF *keyinfo, uint32_t nod_flag,
724
register unsigned char **page, register unsigned char *key)
718
uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag,
719
register uchar **page, register uchar *key)
726
memcpy(key, *page, keyinfo->keylength+nod_flag);
721
memcpy((uchar*) key,(uchar*) *page,
722
(size_t) (keyinfo->keylength+nod_flag));
727
723
*page+=keyinfo->keylength+nod_flag;
728
724
return(keyinfo->keylength);
729
725
} /* _mi_get_static_key */
743
739
key_length + length of data pointer
746
uint32_t _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint32_t nod_flag,
747
register unsigned char **page_pos, register unsigned char *key)
742
uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
743
register uchar **page_pos, register uchar *key)
749
745
register HA_KEYSEG *keyseg;
750
unsigned char *start_key,*page=*page_pos;
746
uchar *start_key,*page=*page_pos;
754
750
for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
756
752
if (keyseg->flag & HA_PACK_KEY)
758
754
/* key with length, packed to previous key */
759
unsigned char *start=key;
760
uint32_t packed= *page & 128,tot_length,rest_length;
756
uint packed= *page & 128,tot_length,rest_length;
761
757
if (keyseg->length >= 127)
763
759
length=mi_uint2korr(page) & 32767;
801
797
if (tot_length >= 255 && *start != 255)
803
799
/* length prefix changed from a length of one to a length of 3 */
804
internal::bmove_upp(key+length+3, key+length+1, length);
800
bmove_upp(key+length+3, key+length+1, length);
806
802
mi_int2store(key+1,tot_length);
809
805
else if (tot_length < 255 && *start == 255)
811
memmove(key+1,key+3,length);
807
bmove(key+1,key+3,length);
852
848
if (keyseg->flag &
853
849
(HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
855
unsigned char *tmp=page;
856
852
get_key_length(length,tmp);
857
853
length+=(uint) (tmp-page);
860
856
length=keyseg->length;
862
memcpy(key, page, length);
858
memcpy((uchar*) key,(uchar*) page,(size_t) length);
866
862
length=keyseg->length+nod_flag;
867
memmove(key,page,length);
863
bmove((uchar*) key,(uchar*) page,length);
868
864
*page_pos= page+length;
869
865
return ((uint) (key-start_key)+keyseg->length);
870
866
} /* _mi_get_pack_key */
874
870
/* key that is packed relatively to previous */
876
uint32_t _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint32_t nod_flag,
877
register unsigned char **page_pos, register unsigned char *key)
872
uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
873
register uchar **page_pos, register uchar *key)
879
875
register HA_KEYSEG *keyseg;
880
unsigned char *start_key,*page,*page_end,*from,*from_end;
876
uchar *start_key,*page,*page_end,*from,*from_end;
884
880
page_end=page+MI_MAX_KEY_BUFF+1;
904
900
if (length > keyinfo->maxlength)
906
902
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
907
errno=HA_ERR_CRASHED;
903
my_errno=HA_ERR_CRASHED;
908
904
return(0); /* Wrong key */
910
906
/* Key is packed against prev key, take prefix from prev key. */
959
955
from=page; from_end=page_end;
961
memmove(key, from, length);
957
memmove((uchar*) key, (uchar*) from, (size_t) length);
985
981
if (from_end != page_end)
987
983
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
988
errno=HA_ERR_CRASHED;
984
my_errno=HA_ERR_CRASHED;
989
985
return(0); /* Error */
991
987
/* Copy data pointer and, if appropriate, key block pointer. */
992
memcpy(key, from, length);
988
memcpy((uchar*) key,(uchar*) from,(size_t) length);
993
989
*page_pos= from+length;
995
991
return((uint) (key-start_key)+keyseg->length);
999
995
/* Get key at position without knowledge of previous key */
1000
996
/* Returns pointer to next key */
1002
unsigned char *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
1003
unsigned char *key, unsigned char *keypos, uint32_t *return_key_length)
998
uchar *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
999
uchar *key, uchar *keypos, uint *return_key_length)
1007
1003
nod_flag=mi_test_if_nod(page);
1008
1004
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1010
memmove(key,keypos,keyinfo->keylength+nod_flag);
1006
bmove((uchar*) key,(uchar*) keypos,keyinfo->keylength+nod_flag);
1011
1007
return(keypos+keyinfo->keylength+nod_flag);
1032
1028
/* Get key at position without knowledge of previous key */
1033
1029
/* Returns 0 if ok */
1035
static bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
1036
unsigned char *key, unsigned char *keypos,
1037
uint32_t *return_key_length)
1031
static my_bool _mi_get_prev_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
1032
uchar *key, uchar *keypos,
1033
uint *return_key_length)
1041
1037
nod_flag=mi_test_if_nod(page);
1042
1038
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1044
1040
*return_key_length=keyinfo->keylength;
1045
memmove(key, keypos - *return_key_length-nod_flag, *return_key_length);
1041
bmove((uchar*) key,(uchar*) keypos- *return_key_length-nod_flag,
1042
*return_key_length);
1068
1065
/* Get last key from key-page */
1069
1066
/* Return pointer to where key starts */
1071
unsigned char *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
1072
unsigned char *lastkey, unsigned char *endpos, uint32_t *return_key_length)
1068
uchar *_mi_get_last_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page,
1069
uchar *lastkey, uchar *endpos, uint *return_key_length)
1075
unsigned char *lastpos;
1077
1074
nod_flag=mi_test_if_nod(page);
1078
1075
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1080
1077
lastpos=endpos-keyinfo->keylength-nod_flag;
1081
1078
*return_key_length=keyinfo->keylength;
1082
1079
if (lastpos > page)
1083
memmove(lastkey,lastpos,keyinfo->keylength+nod_flag);
1080
bmove((uchar*) lastkey,(uchar*) lastpos,keyinfo->keylength+nod_flag);
1105
1102
/* Calculate length of key */
1107
uint32_t _mi_keylength(MI_KEYDEF *keyinfo, register unsigned char *key)
1104
uint _mi_keylength(MI_KEYDEF *keyinfo, register uchar *key)
1109
1106
register HA_KEYSEG *keyseg;
1110
unsigned char *start;
1112
1109
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1113
1110
return (keyinfo->keylength);
1139
1136
after '0xDF' but find 'ss'
1142
uint32_t _mi_keylength_part(MI_KEYDEF *keyinfo, register unsigned char *key,
1139
uint _mi_keylength_part(MI_KEYDEF *keyinfo, register uchar *key,
1143
1140
HA_KEYSEG *end)
1145
1142
register HA_KEYSEG *keyseg;
1146
unsigned char *start= key;
1148
1145
for (keyseg=keyinfo->seg ; keyseg != end ; keyseg++)
1165
1162
/* Move a key */
1167
unsigned char *_mi_move_key(MI_KEYDEF *keyinfo, unsigned char *to, unsigned char *from)
1164
uchar *_mi_move_key(MI_KEYDEF *keyinfo, uchar *to, uchar *from)
1169
register uint32_t length;
1170
length= _mi_keylength(keyinfo, from);
1171
memcpy(to, from, length);
1166
register uint length;
1167
memcpy((uchar*) to, (uchar*) from,
1168
(size_t) (length=_mi_keylength(keyinfo,from)));
1172
1169
return to+length;
1176
1173
/* This can't be used when database is touched after last read */
1178
1175
int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1179
unsigned char *key, uint32_t key_length, uint32_t nextflag, internal::my_off_t pos)
1176
uchar *key, uint key_length, uint nextflag, my_off_t pos)
1183
unsigned char lastkey[MI_MAX_KEY_BUFF];
1180
uchar lastkey[MI_MAX_KEY_BUFF];
1185
1182
/* Force full read if we are at last key or if we are not on a leaf
1186
1183
and the key tree has changed since we used it last time
1210
1207
if (nextflag & SEARCH_BIGGER) /* Next key */
1212
internal::my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
1209
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
1213
1210
if (tmp_pos != HA_OFFSET_ERROR)
1215
1212
if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1224
1221
else /* Previous key */
1227
1224
/* Find start of previous key */
1228
1225
info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
1229
1226
info->int_keypos, &length);
1252
1249
/* This is stored in info->lastpos */
1254
1251
int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1255
register internal::my_off_t pos)
1252
register my_off_t pos)
1258
unsigned char *page;
1260
1257
if (pos == HA_OFFSET_ERROR)
1262
errno=HA_ERR_KEY_NOT_FOUND;
1259
my_errno=HA_ERR_KEY_NOT_FOUND;
1263
1260
info->lastpos= HA_OFFSET_ERROR;
1294
1291
/* This is stored in info->lastpos */
1296
1293
int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
1297
register internal::my_off_t pos)
1294
register my_off_t pos)
1300
unsigned char *buff,*page;
1302
1299
if (pos == HA_OFFSET_ERROR)
1304
errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
1301
my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */
1305
1302
info->lastpos= HA_OFFSET_ERROR;
1349
1346
/* Static length key */
1352
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1353
unsigned char *next_pos,
1354
unsigned char *org_key,
1355
unsigned char *prev_key,
1356
unsigned char *key, MI_KEY_PARAM *s_temp)
1349
_mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
1350
uchar *next_pos __attribute__((unused)),
1351
uchar *org_key __attribute__((unused)),
1352
uchar *prev_key __attribute__((unused)),
1353
uchar *key, MI_KEY_PARAM *s_temp)
1361
1355
s_temp->key=key;
1362
1356
return (int) (s_temp->totlength=keyinfo->keylength+nod_flag);
1365
1359
/* Variable length key */
1368
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1369
unsigned char *next_pos,
1370
unsigned char *org_key,
1371
unsigned char *prev_key,
1372
unsigned char *key, MI_KEY_PARAM *s_temp)
1362
_mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint nod_flag,
1363
uchar *next_pos __attribute__((unused)),
1364
uchar *org_key __attribute__((unused)),
1365
uchar *prev_key __attribute__((unused)),
1366
uchar *key, MI_KEY_PARAM *s_temp)
1377
1368
s_temp->key=key;
1378
1369
return (int) (s_temp->totlength=_mi_keylength(keyinfo,key)+nod_flag);
1401
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
1402
unsigned char *next_key,
1403
unsigned char *org_key,
1404
unsigned char *prev_key,
1392
_mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
1393
uchar *org_key, uchar *prev_key, uchar *key,
1406
1394
MI_KEY_PARAM *s_temp)
1408
1396
register HA_KEYSEG *keyseg;
1410
uint32_t key_length,ref_length,org_key_length=0,
1398
uint key_length,ref_length,org_key_length=0,
1411
1399
length_pack,new_key_length,diff_flag,pack_marker;
1412
unsigned char *start,*end,*key_end,*sort_order;
1400
uchar *start,*end,*key_end,*sort_order;
1401
my_bool same_length;
1415
1403
length_pack=s_temp->ref_length=s_temp->n_ref_length=s_temp->n_length=0;
1416
1404
same_length=0; keyseg=keyinfo->seg;
1525
1513
/* If something after that hasn't length=0, test if we can combine */
1526
1514
if ((s_temp->next_key_pos=next_key))
1528
uint32_t packed,n_length;
1516
uint packed,n_length;
1530
1518
packed = *next_key & 128;
1531
1519
if (diff_flag == 2)
1609
1597
if (ref_length+pack_marker > new_ref_length)
1611
uint32_t new_pack_length=new_ref_length-pack_marker;
1599
uint new_pack_length=new_ref_length-pack_marker;
1612
1600
/* We must copy characters from the original key to the next key */
1613
1601
s_temp->part_of_prev_key= new_ref_length;
1614
1602
s_temp->prev_length= ref_length - new_pack_length;
1673
1661
/* Length of key which is prefix compressed */
1676
_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char *next_key,
1677
unsigned char *org_key, unsigned char *prev_key, unsigned char *key,
1664
_mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key,
1665
uchar *org_key, uchar *prev_key, uchar *key,
1678
1666
MI_KEY_PARAM *s_temp)
1680
uint32_t length,key_length,ref_length;
1668
uint length,key_length,ref_length;
1682
1670
s_temp->totlength=key_length=_mi_keylength(keyinfo,key)+nod_flag;
1683
#ifdef HAVE_VALGRIND
1684
1672
s_temp->n_length= s_temp->n_ref_length=0; /* For valgrind */
1686
1674
s_temp->key=key;
1692
1680
As keys may be identical when running a sort in myisamchk, we
1693
1681
have to guard against the case where keys may be identical
1696
1684
end=key+key_length;
1697
1685
for ( ; *key == *prev_key && key < end; key++,prev_key++) ;
1698
1686
s_temp->ref_length= ref_length=(uint) (key-s_temp->key);
1707
1695
if ((s_temp->next_key_pos=next_key)) /* If another key after */
1709
1697
/* pack key against next key */
1710
uint32_t next_length,next_length_pack;
1698
uint next_length,next_length_pack;
1711
1699
get_key_pack_length(next_length,next_length_pack,next_key);
1713
1701
/* If first key and next key is packed (only on delete) */
1714
1702
if (!prev_key && org_key && next_length)
1717
1705
for (key= s_temp->key, end=key+next_length ;
1718
1706
*key == *org_key && key < end;
1719
1707
key++,org_key++) ;
1755
1743
/* store key without compression */
1757
void _mi_store_static_key(MI_KEYDEF *keyinfo,
1758
register unsigned char *key_pos,
1745
void _mi_store_static_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1746
register uchar *key_pos,
1759
1747
register MI_KEY_PARAM *s_temp)
1762
memcpy(key_pos, s_temp->key, s_temp->totlength);
1749
memcpy((uchar*) key_pos,(uchar*) s_temp->key,(size_t) s_temp->totlength);
1766
1753
/* store variable length key with prefix compression */
1768
1755
#define store_pack_length(test,pos,length) { \
1769
if (test) { *((pos)++) = (unsigned char) (length); } else \
1770
{ *((pos)++) = (unsigned char) ((length) >> 8); *((pos)++) = (unsigned char) (length); } }
1773
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo,
1774
register unsigned char *key_pos,
1756
if (test) { *((pos)++) = (uchar) (length); } else \
1757
{ *((pos)++) = (uchar) ((length) >> 8); *((pos)++) = (uchar) (length); } }
1760
void _mi_store_var_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1761
register uchar *key_pos,
1775
1762
register MI_KEY_PARAM *s_temp)
1779
unsigned char *start;
1793
1779
/* Not packed against previous key */
1794
1780
store_pack_length(s_temp->pack_marker == 128,key_pos,s_temp->key_length);
1796
assert(key_pos >= start);
1797
length= s_temp->totlength - (key_pos - start);
1798
memmove(key_pos, s_temp->key, length);
1782
bmove((uchar*) key_pos,(uchar*) s_temp->key,
1783
(length=s_temp->totlength-(uint) (key_pos-start)));
1800
1785
if (!s_temp->next_key_pos) /* No following key */
1836
1821
/* variable length key with prefix compression */
1838
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo,
1839
register unsigned char *key_pos,
1823
void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo __attribute__((unused)),
1824
register uchar *key_pos,
1840
1825
register MI_KEY_PARAM *s_temp)
1843
assert(s_temp->totlength >= s_temp->ref_length);
1844
1827
store_key_length_inc(key_pos,s_temp->ref_length);
1845
memcpy(key_pos,s_temp->key+s_temp->ref_length,
1846
s_temp->totlength - s_temp->ref_length);
1828
memcpy((char*) key_pos,(char*) s_temp->key+s_temp->ref_length,
1829
(size_t) s_temp->totlength-s_temp->ref_length);
1848
1831
if (s_temp->next_key_pos)