62
62
uchar *keypos,*maxpos;
63
63
uchar lastkey[MI_MAX_KEY_BUFF],*buff;
64
DBUG_ENTER("_mi_search");
65
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
66
(ulong) pos, nextflag, (ulong) info->lastpos));
67
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_len););
69
65
if (pos == HA_OFFSET_ERROR)
71
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
DBUG_RETURN(-1); /* Not found ; return error */
75
DBUG_RETURN(1); /* Search at upper levels */
70
return(-1); /* Not found ; return error */
71
return(1); /* Search at upper levels */
78
74
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
79
75
test(!(nextflag & SEARCH_SAVE_BUFF)))))
81
DBUG_DUMP("page",(uchar*) buff,mi_getint(buff));
83
78
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
84
79
&keypos,lastkey, &last_key);
85
80
if (flag == MI_FOUND_WRONG_KEY)
87
82
nod_flag=mi_test_if_nod(buff);
88
83
maxpos=buff+mi_getint(buff)-1;
92
87
if ((error=_mi_search(info,keyinfo,key,key_len,nextflag,
93
88
_mi_kpos(nod_flag,keypos))) <= 0)
98
93
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
99
94
keypos == buff+2+nod_flag)
100
DBUG_RETURN(1); /* Bigger than key */
95
return(1); /* Bigger than key */
102
97
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
103
DBUG_RETURN(1); /* Smaller than key */
98
return(1); /* Smaller than key */
111
106
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
112
107
_mi_kpos(nod_flag,keypos))) >= 0 ||
113
108
my_errno != HA_ERR_KEY_NOT_FOUND)
115
110
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
156
151
info->page_changed=0;
157
152
info->buff_used= (info->buff != buff); /* If we have to reread buff */
159
DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
163
DBUG_PRINT("exit",("Error: %d",my_errno));
164
157
info->lastpos= HA_OFFSET_ERROR;
165
158
info->page_changed=1;
167
160
} /* _mi_search */
179
172
register int start,mid,end,save_end;
181
174
uint totlength,nod_flag,not_used[2];
182
DBUG_ENTER("_mi_bin_search");
184
176
totlength=keyinfo->keylength+(nod_flag=mi_test_if_nod(page));
186
178
save_end=end=(int) ((mi_getint(page)-2-nod_flag)/totlength-1);
187
DBUG_PRINT("test",("mi_getint: %d end: %d",mi_getint(page),end));
188
179
page+=2+nod_flag;
190
181
while (start != end)
204
195
start++; /* point at next, bigger key */
205
196
*ret_pos=page+(uint) start*totlength;
206
197
*last_key= end == save_end;
207
DBUG_PRINT("exit",("flag: %d keypos: %d",flag,start));
209
199
} /* _mi_bin_search */
243
233
uint nod_flag,length=0,not_used[2];
244
234
uchar t_buff[MI_MAX_KEY_BUFF],*end;
245
DBUG_ENTER("_mi_seq_search");
247
236
end= page+mi_getint(page);
248
237
nod_flag=mi_test_if_nod(page);
257
246
mi_print_error(info->s, HA_ERR_CRASHED);
258
247
my_errno=HA_ERR_CRASHED;
260
("Found wrong key: length: %u page: 0x%lx end: 0x%lx",
261
length, (long) page, (long) end));
262
DBUG_RETURN(MI_FOUND_WRONG_KEY);
248
return(MI_FOUND_WRONG_KEY);
264
250
if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag,
268
DBUG_PRINT("loop",("page: 0x%lx key: '%s' flag: %d", (long) page, t_buff,
271
253
memcpy(buff,t_buff,length);
275
257
memcpy(buff,t_buff,length); /* Result is first key */
276
258
*last_key= page == end;
277
DBUG_PRINT("exit",("flag: %d ret_pos: 0x%lx", flag, (long) *ret_pos));
279
260
} /* _mi_seq_search */
298
279
uchar *saved_from=NULL, *saved_to=NULL, *saved_vseg=NULL;
299
280
uint saved_length=0, saved_prefix_len=0;
300
281
uint length_pack;
301
DBUG_ENTER("_mi_prefix_search");
303
283
t_buff[0]=0; /* Avoid bugs */
304
284
end= page+mi_getint(page);
312
292
key_len_left=(int) key_len- (int) key_len_skip;
313
293
/* If key_len is 0, then lenght_pack is 1, then key_len_left is -1. */
314
294
cmplen=(key_len_left>=0) ? kseg_len : key_len-length_pack;
315
DBUG_PRINT("info",("key: '%.*s'",kseg_len,kseg));
318
297
Keys are compressed the following way:
375
354
saved_prefix_len=prefix_len;
377
DBUG_PRINT("loop",("page: '%.*s%.*s'",prefix_len,t_buff+seg_len_pack,
380
357
uchar *from=vseg+suffix_len;
381
358
HA_KEYSEG *keyseg;
408
385
mi_print_error(info->s, HA_ERR_CRASHED);
409
386
my_errno=HA_ERR_CRASHED;
411
("Found wrong key: length: %u page: 0x%lx end: %lx",
412
length, (long) page, (long) end));
413
DBUG_RETURN(MI_FOUND_WRONG_KEY);
387
return(MI_FOUND_WRONG_KEY);
416
390
if (matched >= prefix_len)
804
777
key+= length; /* Same diff_key as prev */
805
778
if (length > keyseg->length)
808
("Found too long null packed key: %u of %u at 0x%lx",
809
length, keyseg->length, (long) *page_pos));
810
DBUG_DUMP("key",(uchar*) *page_pos,16);
811
780
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
812
781
my_errno=HA_ERR_CRASHED;
863
832
if (length > (uint) keyseg->length)
865
DBUG_PRINT("error",("Found too long packed key: %u of %u at 0x%lx",
866
length, keyseg->length, (long) *page_pos));
867
DBUG_DUMP("key",(uchar*) *page_pos,16);
868
834
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
869
835
my_errno=HA_ERR_CRASHED;
870
836
return 0; /* Error */
908
874
register HA_KEYSEG *keyseg;
909
875
uchar *start_key,*page,*page_end,*from,*from_end;
911
DBUG_ENTER("_mi_get_binary_pack_key");
914
879
page_end=page+MI_MAX_KEY_BUFF+1;
934
899
if (length > keyinfo->maxlength)
937
("Found too long binary packed key: %u of %u at 0x%lx",
938
length, keyinfo->maxlength, (long) *page_pos));
939
DBUG_DUMP("key",(uchar*) *page_pos,16);
940
901
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
941
902
my_errno=HA_ERR_CRASHED;
942
DBUG_RETURN(0); /* Wrong key */
903
return(0); /* Wrong key */
944
905
/* Key is packed against prev key, take prefix from prev key. */
993
954
from=page; from_end=page_end;
995
DBUG_PRINT("info",("key: 0x%lx from: 0x%lx length: %u",
996
(long) key, (long) from, length));
997
956
memmove((uchar*) key, (uchar*) from, (size_t) length);
1021
980
if (from_end != page_end)
1023
DBUG_PRINT("error",("Error when unpacking key"));
1024
982
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
1025
983
my_errno=HA_ERR_CRASHED;
1026
DBUG_RETURN(0); /* Error */
984
return(0); /* Error */
1028
986
/* Copy data pointer and, if appropriate, key block pointer. */
1029
987
memcpy((uchar*) key,(uchar*) from,(size_t) length);
1030
988
*page_pos= from+length;
1032
DBUG_RETURN((uint) (key-start_key)+keyseg->length);
990
return((uint) (key-start_key)+keyseg->length);
1040
998
uchar *key, uchar *keypos, uint *return_key_length)
1043
DBUG_ENTER("_mi_get_key");
1045
1002
nod_flag=mi_test_if_nod(page);
1046
1003
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1048
1005
bmove((uchar*) key,(uchar*) keypos,keyinfo->keylength+nod_flag);
1049
DBUG_RETURN(keypos+keyinfo->keylength+nod_flag);
1006
return(keypos+keyinfo->keylength+nod_flag);
1117
1071
uchar *lastpos;
1118
DBUG_ENTER("_mi_get_last_key");
1119
DBUG_PRINT("enter",("page: 0x%lx endpos: 0x%lx", (long) page,
1122
1073
nod_flag=mi_test_if_nod(page);
1123
1074
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
1137
1088
*return_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,lastkey);
1138
1089
if (*return_key_length == 0)
1140
DBUG_PRINT("error",("Couldn't find last key: page: 0x%lx",
1142
1091
mi_print_error(info->s, HA_ERR_CRASHED);
1143
1092
my_errno=HA_ERR_CRASHED;
1148
DBUG_PRINT("exit",("lastpos: 0x%lx length: %u", (long) lastpos,
1149
*return_key_length));
1150
DBUG_RETURN(lastpos);
1151
1098
} /* _mi_get_last_key */
1232
1179
uchar lastkey[MI_MAX_KEY_BUFF];
1233
DBUG_ENTER("_mi_search_next");
1234
DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: %lu",
1235
nextflag, (ulong) info->lastpos,
1236
(ulong) info->int_keypos));
1237
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
1239
1181
/* Force full read if we are at last key or if we are not on a leaf
1240
1182
and the key tree has changed since we used it last time
1247
1189
info->page_changed ||
1248
1190
(info->int_keytree_version != keyinfo->version &&
1249
1191
(info->int_nod_flag || info->buff_used)))
1250
DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1192
return(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1251
1193
nextflag | SEARCH_SAVE_BUFF, pos));
1253
1195
if (info->buff_used)
1255
1197
if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
1256
1198
DFLT_INIT_HITS,info->buff,0))
1258
1200
info->buff_used=0;
1269
1211
if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1270
1212
nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
1273
1215
memcpy(lastkey,key,key_length);
1274
1216
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
1275
1217
&info->int_keypos,lastkey)))
1278
1220
else /* Previous key */
1282
1224
info->int_keypos=_mi_get_last_key(info,keyinfo,info->buff,lastkey,
1283
1225
info->int_keypos, &length);
1284
1226
if (!info->int_keypos)
1286
1228
if (info->int_keypos == info->buff+2)
1287
DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1229
return(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1288
1230
nextflag | SEARCH_SAVE_BUFF, pos));
1289
1231
if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
1290
1232
nextflag | SEARCH_SAVE_BUFF,
1291
1233
_mi_kpos(nod_flag,info->int_keypos))) <= 0)
1294
1236
/* QQ: We should be able to optimize away the following call */
1295
1237
if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
1296
1238
info->int_keypos,&info->lastkey_length))
1299
1241
memcpy(info->lastkey,lastkey,info->lastkey_length);
1300
1242
info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1301
DBUG_PRINT("exit",("found key at %lu",(ulong) info->lastpos));
1303
1244
} /* _mi_search_next */
1325
1265
if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0))
1327
1267
info->lastpos= HA_OFFSET_ERROR;
1330
1270
nod_flag=mi_test_if_nod(info->buff);
1331
1271
page=info->buff+2+nod_flag;
1334
1274
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
1335
1275
info->lastkey)))
1336
DBUG_RETURN(-1); /* Crashed */
1276
return(-1); /* Crashed */
1338
1278
info->int_keypos=page; info->int_maxpos=info->buff+mi_getint(info->buff)-1;
1339
1279
info->int_nod_flag=nod_flag;
1342
1282
info->page_changed=info->buff_used=0;
1343
1283
info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1345
DBUG_PRINT("exit",("found key at %lu", (ulong) info->lastpos));
1347
1286
} /* _mi_search_first */
1370
1308
if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
1372
1310
info->lastpos= HA_OFFSET_ERROR;
1375
1313
page= buff+mi_getint(buff);
1376
1314
nod_flag=mi_test_if_nod(buff);
1379
1317
if (!_mi_get_last_key(info,keyinfo,buff,info->lastkey,page,
1380
1318
&info->lastkey_length))
1382
1320
info->lastpos=_mi_dpos(info,0,info->lastkey+info->lastkey_length);
1383
1321
info->int_keypos=info->int_maxpos=page;
1384
1322
info->int_nod_flag=nod_flag;
1572
1509
s_temp->totlength=(uint) length;
1573
1510
s_temp->prev_length=0;
1574
DBUG_PRINT("test",("tot_length: %u length: %d uniq_key_length: %u",
1575
key_length, length, s_temp->key_length));
1577
1512
/* If something after that hasn't length=0, test if we can combine */
1578
1513
if ((s_temp->next_key_pos=next_key))