836
827
(*key_checksum)+= mi_byte_checksum((uchar*) key,
837
828
key_length- info->s->rec_reflength);
838
829
record= _mi_dpos(info,0,key+key_length);
839
if (keyinfo->flag & HA_FULLTEXT) /* special handling for ft2 */
843
get_key_full_length_rdonly(off, key);
844
subkeys=ft_sintXkorr(key+off);
848
if (chk_index_down(param,info,&info->s->ft2_keyinfo,record,
849
temp_buff,&tmp_keys,key_checksum,1))
851
if (tmp_keys + subkeys)
853
mi_check_print_error(param,
854
"Number of words in the 2nd level tree "
855
"does not match the number in the header. "
856
"Parent word in on the page %s, offset %u",
857
llstr(page,llbuff), (uint) (old_keypos-buff));
865
830
if (record >= info->state->data_file_length)
1790
1750
if (mi_is_key_active(info->s->state.key_map, i))
1792
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
1794
if (_mi_ft_add(info, i, key, buff, filepos))
1798
else if (info->s->keyinfo[i].flag & HA_SPATIAL)
1800
uint key_length=_mi_make_key(info,i,key,buff,filepos);
1801
if (rtree_insert(info, i, key, key_length))
1804
#endif /*HAVE_SPATIAL*/
1807
1753
uint key_length=_mi_make_key(info,i,key,buff,filepos);
1808
1754
if (_mi_ck_write(info,i,key,key_length))
2383
2302
info->state->records=info->state->del=share->state.split=0;
2384
2303
info->state->empty=0;
2386
if (sort_param.keyinfo->flag & HA_FULLTEXT)
2388
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
2389
sort_param.keyinfo->seg->charset->mbmaxlen;
2390
sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
2392
fulltext indexes may have much more entries than the
2393
number of rows in the table. We estimate the number here.
2395
Note, built-in parser is always nr. 0 - see ftparser_call_initializer()
2397
if (sort_param.keyinfo->ftparser_nr == 0)
2400
for built-in parser the number of generated index entries
2401
cannot be larger than the size of the data file divided
2402
by the minimal word's length
2404
sort_info.max_records=
2405
(ha_rows) (sort_info.filelength/ft_min_word_len+1);
2410
for external plugin parser we cannot tell anything at all :(
2411
so, we'll use all the sort memory and start from ~10 buffpeks.
2412
(see _create_index_by_sort)
2414
sort_info.max_records=
2415
10*param->sort_buffer_length/sort_param.key_length;
2418
sort_param.key_read=sort_ft_key_read;
2419
sort_param.key_write=sort_ft_key_write;
2423
2306
sort_param.key_read=sort_key_read;
2424
2307
sort_param.key_write=sort_key_write;
3142
3011
DBUG_RETURN(sort_write_record(sort_param));
3143
3012
} /* sort_key_read */
3145
static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key)
3148
SORT_INFO *sort_info=sort_param->sort_info;
3149
MI_INFO *info=sort_info->info;
3151
DBUG_ENTER("sort_ft_key_read");
3153
if (!sort_param->wordlist)
3157
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
3158
if ((error=sort_get_next_record(sort_param)))
3160
if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record,
3161
&sort_param->wordroot)))
3165
error=sort_write_record(sort_param);
3167
sort_param->wordptr=sort_param->wordlist=wptr;
3172
wptr=(FT_WORD*)(sort_param->wordptr);
3175
sort_param->real_key_length=(info->s->rec_reflength+
3176
_ft_make_key(info, sort_param->key,
3177
key, wptr++, sort_param->filepos));
3179
if (sort_param->key_length > sort_param->real_key_length)
3180
bzero(key+sort_param->real_key_length,
3181
(sort_param->key_length-sort_param->real_key_length));
3185
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
3186
sort_param->wordlist=0;
3187
error=sort_write_record(sort_param);
3190
sort_param->wordptr=(void*)wptr;
3193
} /* sort_ft_key_read */
3197
3016
Read next record from file using parameters in sort_info.
3837
3656
(uchar*) a, HA_OFFSET_ERROR));
3838
3657
} /* sort_key_write */
3840
int sort_ft_buf_flush(MI_SORT_PARAM *sort_param)
3842
SORT_INFO *sort_info=sort_param->sort_info;
3843
SORT_KEY_BLOCKS *key_block=sort_info->key_block;
3844
MYISAM_SHARE *share=sort_info->info->s;
3845
uint val_off, val_len;
3847
SORT_FT_BUF *ft_buf=sort_info->ft_buf;
3850
val_len=share->ft2_keyinfo.keylength;
3851
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
3852
to=ft_buf->lastkey+val_off;
3856
/* flushing first-level tree */
3857
error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
3859
for (from=to+val_len;
3860
!error && from < ft_buf->buf;
3863
memcpy(to, from, val_len);
3864
error=sort_insert_key(sort_param,key_block,ft_buf->lastkey,
3869
/* flushing second-level tree keyblocks */
3870
error=flush_pending_blocks(sort_param);
3871
/* updating lastkey with second-level tree info */
3872
ft_intXstore(ft_buf->lastkey+val_off, -ft_buf->count);
3873
_mi_dpointer(sort_info->info, ft_buf->lastkey+val_off+HA_FT_WLEN,
3874
share->state.key_root[sort_param->key]);
3875
/* restoring first level tree data in sort_info/sort_param */
3876
sort_info->key_block=sort_info->key_block_end- sort_info->param->sort_key_blocks;
3877
sort_param->keyinfo=share->keyinfo+sort_param->key;
3878
share->state.key_root[sort_param->key]=HA_OFFSET_ERROR;
3879
/* writing lastkey in first-level tree */
3880
return error ? error :
3881
sort_insert_key(sort_param,sort_info->key_block,
3882
ft_buf->lastkey,HA_OFFSET_ERROR);
3885
static int sort_ft_key_write(MI_SORT_PARAM *sort_param, const void *a)
3887
uint a_len, val_off, val_len, error;
3889
SORT_INFO *sort_info=sort_param->sort_info;
3890
SORT_FT_BUF *ft_buf=sort_info->ft_buf;
3891
SORT_KEY_BLOCKS *key_block=sort_info->key_block;
3893
val_len=HA_FT_WLEN+sort_info->info->s->base.rec_reflength;
3894
get_key_full_length_rdonly(a_len, (uchar *)a);
3899
use two-level tree only if key_reflength fits in rec_reflength place
3900
and row format is NOT static - for _mi_dpointer not to garble offsets
3902
if ((sort_info->info->s->base.key_reflength <=
3903
sort_info->info->s->base.rec_reflength) &&
3904
(sort_info->info->s->options &
3905
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
3906
ft_buf=(SORT_FT_BUF *)my_malloc(sort_param->keyinfo->block_length +
3907
sizeof(SORT_FT_BUF), MYF(MY_WME));
3911
sort_param->key_write=sort_key_write;
3912
return sort_key_write(sort_param, a);
3914
sort_info->ft_buf=ft_buf;
3915
goto word_init_ft_buf; /* no need to duplicate the code */
3917
get_key_full_length_rdonly(val_off, ft_buf->lastkey);
3919
if (ha_compare_text(sort_param->seg->charset,
3920
((uchar *)a)+1,a_len-1,
3921
ft_buf->lastkey+1,val_off-1, 0, 0)==0)
3923
if (!ft_buf->buf) /* store in second-level tree */
3926
return sort_insert_key(sort_param,key_block,
3927
((uchar *)a)+a_len, HA_OFFSET_ERROR);
3930
/* storing the key in the buffer. */
3931
memcpy (ft_buf->buf, (char *)a+a_len, val_len);
3932
ft_buf->buf+=val_len;
3933
if (ft_buf->buf < ft_buf->end)
3936
/* converting to two-level tree */
3937
p=ft_buf->lastkey+val_off;
3939
while (key_block->inited)
3941
sort_info->key_block=key_block;
3942
sort_param->keyinfo=& sort_info->info->s->ft2_keyinfo;
3943
ft_buf->count=(ft_buf->buf - p)/val_len;
3945
/* flushing buffer to second-level tree */
3946
for (error=0; !error && p < ft_buf->buf; p+= val_len)
3947
error=sort_insert_key(sort_param,key_block,p,HA_OFFSET_ERROR);
3952
/* flushing buffer */
3953
if ((error=sort_ft_buf_flush(sort_param)))
3958
memcpy(ft_buf->lastkey, a, a_len);
3959
ft_buf->buf=ft_buf->lastkey+a_len;
3961
32 is just a safety margin here
3962
(at least max(val_len, sizeof(nod_flag)) should be there).
3963
May be better performance could be achieved if we'd put
3964
(sort_info->keyinfo->block_length-32)/XXX
3966
TODO: benchmark the best value for XXX.
3968
ft_buf->end=ft_buf->lastkey+ (sort_param->keyinfo->block_length-32);
3970
} /* sort_ft_key_write */
3973
3660
/* get pointer to record from a key */