18 #include "myisam_priv.h"
24 #include <boost/scoped_ptr.hpp>
25 #include <boost/scoped_array.hpp>
27 #include <drizzled/internal/m_string.h>
28 #include <drizzled/util/test.h>
29 #include <drizzled/charset.h>
30 #include <drizzled/memory/multi_malloc.h>
31 #include <drizzled/identifier.h>
35 using namespace drizzled;
37 static void setup_key_functions(
MI_KEYDEF *keyinfo);
38 static unsigned char *mi_keydef_read(
unsigned char *ptr,
MI_KEYDEF *keydef);
39 static unsigned char *mi_keyseg_read(
unsigned char *ptr,
HA_KEYSEG *keyseg);
40 static unsigned char *mi_recinfo_read(
unsigned char *ptr,
MI_COLUMNDEF *recinfo);
41 static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
42 static unsigned char *mi_state_info_read(
unsigned char *ptr,
MI_STATE_INFO *state);
43 static unsigned char *mi_uniquedef_read(
unsigned char *ptr,
MI_UNIQUEDEF *def);
44 static unsigned char *my_n_base_info_read(
unsigned char *ptr,
MI_BASE_INFO *base);
46 #define disk_pos_assert(pos, end_pos) \
49 errno=HA_ERR_CRASHED; \
59 MI_INFO *test_if_reopen(
char *filename)
61 list<MI_INFO *>::iterator it= myisam_open_list.begin();
62 while (it != myisam_open_list.end())
66 if (!strcmp(share->unique_file_name,filename) && share->last_version)
84 int lock_error,kfile,open_mode,save_errno,have_rtree=0;
85 uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
86 key_parts,unique_key_parts,uniques;
87 char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
90 char rp_buff[PATH_MAX];
94 unsigned char *disk_cache= NULL;
95 unsigned char *disk_pos, *end_pos;
97 boost::scoped_ptr<MYISAM_SHARE> share_buff_ap(
new MYISAM_SHARE);
100 boost::scoped_array<ulong> rec_per_key_part_ap(
new ulong[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]);
101 ulong *rec_per_key_part= rec_per_key_part_ap.get();
102 internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
103 uint64_t max_key_file_length, max_data_file_length;
108 head_length=
sizeof(share_buff.state.header);
109 memset(&info, 0,
sizeof(info));
111 (void)internal::fn_format(org_name,
112 identifier.getPath().c_str(),
117 if (!realpath(org_name,rp_buff))
118 internal::my_load_path(rp_buff,org_name, NULL);
119 rp_buff[FN_REFLEN-1]=
'\0';
120 strcpy(name_buff,rp_buff);
122 rp_buff = realpath(org_name,NULL);
127 internal::my_load_path(name_buff,org_name, NULL);
129 if (strlen(rp_buff) >= FN_REFLEN) {
130 rp_buff[FN_REFLEN-1]=
'\0';
132 strcpy(name_buff,rp_buff);
136 THR_LOCK_myisam.lock();
137 if (!(old_info=test_if_reopen(name_buff)))
140 memset(&share_buff, 0,
sizeof(share_buff));
141 share_buff.state.rec_per_key_part=rec_per_key_part;
142 share_buff.state.key_root=key_root;
143 share_buff.state.key_del=key_del;
145 if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
147 if ((errno != EROFS && errno != EACCES) ||
149 (kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
152 share->mode=open_mode;
154 if (internal::my_read(kfile, share->state.header.file_version, head_length,
157 errno= HA_ERR_NOT_A_TABLE;
160 if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
162 errno=HA_ERR_NOT_A_TABLE;
165 share->options= mi_uint2korr(share->state.header.options);
166 static const uint64_t OLD_FILE_OPTIONS= HA_OPTION_PACK_RECORD |
167 HA_OPTION_PACK_KEYS |
168 HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
169 HA_OPTION_TEMP_COMPRESS_RECORD |
171 if (share->options & ~OLD_FILE_OPTIONS)
173 errno=HA_ERR_OLD_FILE;
178 ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
179 if (sym_link_size >= 0 )
180 index_name[sym_link_size]=
'\0';
181 if (!strcmp(name_buff, org_name) || sym_link_size == -1)
182 (void) strcpy(index_name, org_name);
183 *strrchr(org_name,
'.')=
'\0';
184 (void) internal::fn_format(data_name,org_name,
"",MI_NAME_DEXT,
185 MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
187 info_length=mi_uint2korr(share->state.header.header_length);
188 base_pos=mi_uint2korr(share->state.header.base_pos);
189 if (!(disk_cache= (
unsigned char*) malloc(info_length+128)))
194 end_pos=disk_cache+info_length;
197 lseek(kfile,0,SEEK_SET);
199 if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
201 errno=HA_ERR_CRASHED;
204 len=mi_uint2korr(share->state.header.state_info_length);
205 keys= (uint) share->state.header.keys;
206 uniques= (uint) share->state.header.uniques;
207 key_parts= mi_uint2korr(share->state.header.key_parts);
208 unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
209 share->state_diff_length=len-MI_STATE_INFO_SIZE;
211 mi_state_info_read(disk_cache, &share->state);
212 len= mi_uint2korr(share->state.header.base_info_length);
213 disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
214 share->state.state_length=base_pos;
216 if (share->state.changed & STATE_CRASHED)
218 errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
219 HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
224 if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
226 errno=HA_ERR_CRASHED;
230 if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
231 key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
233 errno=HA_ERR_UNSUPPORTED;
238 max_data_file_length=
239 (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
240 (((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
241 (mi_safe_mul(share->base.pack_reclength,
242 (uint64_t) 1 << (share->base.rec_reflength*8))-1);
244 mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
245 ((uint64_t) 1 << (share->base.key_reflength*8))-1);
246 #if SIZEOF_OFF_T == 4
247 set_if_smaller(max_data_file_length, INT32_MAX);
248 set_if_smaller(max_key_file_length, INT32_MAX);
250 if (share->base.raid_type)
252 errno=HA_ERR_UNSUPPORTED;
255 share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
256 share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
258 if (share->options & HA_OPTION_COMPRESS_RECORD)
259 share->base.max_key_length+=2;
262 share->base.max_key_length+= share->base.key_reflength;
264 if (!drizzled::memory::multi_malloc(
false,
265 &share,
sizeof(*share),
266 &share->state.rec_per_key_part,
sizeof(long)*key_parts,
270 (key_parts+unique_key_parts+keys+uniques) *
sizeof(
HA_KEYSEG),
271 &share->rec, (share->base.fields+1)*
sizeof(
MI_COLUMNDEF),
272 &share->blobs,
sizeof(
MI_BLOB)*share->base.blobs,
273 &share->unique_file_name,strlen(name_buff)+1,
274 &share->index_file_name,strlen(index_name)+1,
275 &share->data_file_name,strlen(data_name)+1,
276 &share->state.key_root,keys*
sizeof(uint64_t),
277 &share->state.key_del,
278 (share->state.header.max_block_size_index*
sizeof(uint64_t)),
283 memcpy(share->state.rec_per_key_part, rec_per_key_part,
284 sizeof(
long)*key_parts);
285 memcpy(share->state.key_root, key_root,
286 sizeof(internal::my_off_t)*keys);
287 memcpy(share->state.key_del, key_del,
288 sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
289 strcpy(share->unique_file_name, name_buff);
290 share->unique_name_length= strlen(name_buff);
291 strcpy(share->index_file_name, index_name);
292 strcpy(share->data_file_name, data_name);
294 share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
297 for (i=0 ; i < keys ; i++)
299 share->keyinfo[i].share= share;
300 disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
301 disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
303 set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
304 share->keyinfo[i].seg=pos;
305 for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
307 disk_pos=mi_keyseg_read(disk_pos, pos);
308 if (pos->flag & HA_BLOB_PART &&
309 ! (share->options & (HA_OPTION_COMPRESS_RECORD |
310 HA_OPTION_PACK_RECORD)))
312 errno= HA_ERR_CRASHED;
315 if (pos->type == HA_KEYTYPE_TEXT ||
316 pos->type == HA_KEYTYPE_VARTEXT1 ||
317 pos->type == HA_KEYTYPE_VARTEXT2)
320 pos->charset=default_charset_info;
321 else if (!(pos->charset= get_charset(pos->language)))
323 errno=HA_ERR_UNKNOWN_CHARSET;
327 else if (pos->type == HA_KEYTYPE_BINARY)
328 pos->charset= &my_charset_bin;
330 setup_key_functions(share->keyinfo+i);
331 share->keyinfo[i].end=pos;
332 pos->type=HA_KEYTYPE_END;
333 pos->length=share->base.rec_reflength;
338 for (i=0 ; i < uniques ; i++)
340 disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
341 disk_pos_assert(disk_pos + share->uniqueinfo[i].keysegs *
342 HA_KEYSEG_SIZE, end_pos);
343 share->uniqueinfo[i].seg=pos;
344 for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++)
346 disk_pos=mi_keyseg_read(disk_pos, pos);
347 if (pos->type == HA_KEYTYPE_TEXT ||
348 pos->type == HA_KEYTYPE_VARTEXT1 ||
349 pos->type == HA_KEYTYPE_VARTEXT2)
352 pos->charset=default_charset_info;
353 else if (!(pos->charset= get_charset(pos->language)))
355 errno=HA_ERR_UNKNOWN_CHARSET;
360 share->uniqueinfo[i].end=pos;
361 pos->type=HA_KEYTYPE_END;
368 disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
369 for (i=j=offset=0 ; i < share->base.fields ; i++)
371 disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]);
372 share->rec[i].pack_type=0;
373 share->rec[i].huff_tree=0;
374 share->rec[i].offset=offset;
375 if (share->rec[i].type == (
int) FIELD_BLOB)
377 share->blobs[j].pack_length=
378 share->rec[i].length-portable_sizeof_char_ptr;
379 share->blobs[j].offset=offset;
382 offset+=share->rec[i].length;
384 share->rec[i].type=(int) FIELD_LAST;
385 if (offset > share->base.reclength)
387 errno= HA_ERR_CRASHED;
396 if (mi_open_datafile(&info, share, -1))
401 share->this_process=(ulong) getpid();
402 share->last_process= share->state.process;
403 share->base.key_parts=key_parts;
404 share->base.all_key_parts=key_parts+unique_key_parts;
405 if (!(share->last_version=share->state.version))
406 share->last_version=1;
407 share->rec_reflength=share->base.rec_reflength;
408 share->base.margin_key_file_length=(share->base.max_key_file_length -
409 (keys ? MI_INDEX_BLOCK_MARGIN *
410 share->blocksize * keys : 0));
411 share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
412 share->data_file_type=STATIC_RECORD;
413 if (share->options & HA_OPTION_PACK_RECORD)
414 share->data_file_type = DYNAMIC_RECORD;
417 mi_setup_functions(share);
418 share->is_log_table=
false;
419 if (myisam_concurrent_insert)
421 share->concurrent_insert=
422 ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
423 HA_OPTION_COMPRESS_RECORD |
424 HA_OPTION_TEMP_COMPRESS_RECORD)) ||
425 (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
426 if (share->concurrent_insert)
435 if (mode == O_RDWR && share->mode == O_RDONLY)
440 if (mi_open_datafile(&info, share, old_info->dfile))
443 have_rtree= old_info->rtree_recursion_state != NULL;
447 if (!drizzled::memory::multi_malloc(MY_WME,
449 &info.blobs,
sizeof(
MI_BLOB)*share->base.blobs,
450 &info.buff,(share->base.max_key_block_length*2+
451 share->base.max_key_length),
452 &info.lastkey,share->base.max_key_length*3+1,
453 &info.first_mbr_key, share->base.max_key_length,
454 &info.filename, identifier.getPath().length()+1,
455 &info.rtree_recursion_state,have_rtree ? 1024 : 0,
461 info.rtree_recursion_state= NULL;
463 strcpy(info.filename, identifier.getPath().c_str());
464 memcpy(info.blobs,share->blobs,
sizeof(
MI_BLOB)*share->base.blobs);
465 info.lastkey2=info.lastkey+share->base.max_key_length;
468 info.lastpos= HA_OFFSET_ERROR;
469 info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
470 info.opt_flag=READ_CHECK_USED;
471 info.this_unique= (ulong) info.dfile;
472 if (share->data_file_type == COMPRESSED_RECORD)
473 info.this_unique= share->state.unique;
475 info.last_unique= share->state.unique;
476 info.last_loop= share->state.update_count;
477 if (mode == O_RDONLY)
478 share->options|=HA_OPTION_READ_ONLY_DATA;
479 info.lock_type=F_UNLCK;
484 info.read_record=share->read_record;
486 share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
487 if (share->options & HA_OPTION_READ_ONLY_DATA)
489 info.lock_type=F_RDLCK;
493 if ((open_flags & HA_OPEN_TMP_TABLE) ||
494 (share->options & HA_OPTION_TMP_TABLE))
496 share->temporary=share->delay_key_write=1;
497 share->write_flag=MYF(MY_NABP);
508 info.lock_type=F_WRLCK;
511 share->delay_key_write= 1;
512 info.state= &share->state.state;
517 if (!mi_alloc_rec_buff(&info, SIZE_MAX, &info.rec_buff))
519 memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
522 myisam_open_list.push_front(m_info);
524 THR_LOCK_myisam.unlock();
529 save_errno=errno ? errno : HA_ERR_END_OF_FILE;
530 if ((save_errno == HA_ERR_CRASHED) ||
531 (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
532 (save_errno == HA_ERR_CRASHED_ON_REPAIR))
533 mi_report_error(save_errno, identifier.getPath().c_str());
536 free((
unsigned char*) m_info);
539 internal::my_close(info.dfile,MYF(0));
544 free((
unsigned char*) share);
549 internal::my_close(kfile,MYF(0));
555 THR_LOCK_myisam.unlock();
561 unsigned char *mi_alloc_rec_buff(
MI_INFO *info,
size_t length,
unsigned char **buf)
564 uint32_t old_length= 0;
566 if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
568 unsigned char *newptr = *buf;
571 if (length == SIZE_MAX)
573 if (info->s->options & HA_OPTION_COMPRESS_RECORD)
574 length= max(info->s->base.pack_reclength, info->s->max_pack_length);
576 length= info->s->base.pack_reclength;
577 length= max((uint32_t)length, info->s->base.max_key_length);
579 if (newptr && length == old_length)
583 extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
584 ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
585 MI_REC_BUFF_OFFSET : 0);
587 newptr-= MI_REC_BUFF_OFFSET;
588 void *tmpnewptr= NULL;
589 if (!(tmpnewptr= realloc(newptr, length+extra+8)))
591 newptr= (
unsigned char *)tmpnewptr;
592 *((uint32_t *) newptr)= (uint32_t) length;
593 *buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
599 static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
601 uint64_t max_val= ~ (uint64_t) 0;
603 if (!a || max_val / a < b)
612 if (share->options & HA_OPTION_PACK_RECORD)
614 share->read_record=_mi_read_dynamic_record;
615 share->read_rnd=_mi_read_rnd_dynamic_record;
616 share->delete_record=_mi_delete_dynamic_record;
617 share->compare_record=_mi_cmp_dynamic_record;
618 share->compare_unique=_mi_cmp_dynamic_unique;
619 share->calc_checksum= mi_checksum;
622 share->base.pack_reclength+= share->base.pack_bits;
623 if (share->base.blobs)
625 share->update_record=_mi_update_blob_record;
626 share->write_record=_mi_write_blob_record;
630 share->write_record=_mi_write_dynamic_record;
631 share->update_record=_mi_update_dynamic_record;
636 share->read_record=_mi_read_static_record;
637 share->read_rnd=_mi_read_rnd_static_record;
638 share->delete_record=_mi_delete_static_record;
639 share->compare_record=_mi_cmp_static_record;
640 share->update_record=_mi_update_static_record;
641 share->write_record=_mi_write_static_record;
642 share->compare_unique=_mi_cmp_static_unique;
643 share->calc_checksum= mi_static_checksum;
645 share->file_read= mi_nommap_pread;
646 share->file_write= mi_nommap_pwrite;
647 share->calc_checksum=0;
651 static void setup_key_functions(
register MI_KEYDEF *keyinfo)
654 keyinfo->ck_insert = _mi_ck_write;
655 keyinfo->ck_delete = _mi_ck_delete;
657 if (keyinfo->flag & HA_BINARY_PACK_KEY)
659 keyinfo->bin_search=_mi_seq_search;
660 keyinfo->get_key=_mi_get_binary_pack_key;
661 keyinfo->pack_key=_mi_calc_bin_pack_key_length;
662 keyinfo->store_key=_mi_store_bin_pack_key;
664 else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
666 keyinfo->get_key= _mi_get_pack_key;
667 if (keyinfo->seg[0].flag & HA_PACK_KEY)
677 if (not keyinfo->seg->charset || keyinfo->seg->charset->use_strnxfrm() ||
678 (keyinfo->seg->flag & HA_NULL_PART) ||
679 (keyinfo->seg->charset->mbminlen > 1))
680 keyinfo->bin_search=_mi_seq_search;
682 keyinfo->bin_search=_mi_prefix_search;
683 keyinfo->pack_key=_mi_calc_var_pack_key_length;
684 keyinfo->store_key=_mi_store_var_pack_key;
688 keyinfo->bin_search=_mi_seq_search;
689 keyinfo->pack_key=_mi_calc_var_key_length;
690 keyinfo->store_key=_mi_store_static_key;
695 keyinfo->bin_search=_mi_bin_search;
696 keyinfo->get_key=_mi_get_static_key;
697 keyinfo->pack_key=_mi_calc_static_key_length;
698 keyinfo->store_key=_mi_store_static_key;
708 uint32_t mi_state_info_write(
int file,
MI_STATE_INFO *state, uint32_t pWrite)
710 unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
711 unsigned char *ptr=buff;
712 uint i, keys= (uint) state->header.keys,
713 key_blocks=state->header.max_block_size_index;
715 memcpy(ptr,&state->header,
sizeof(state->header));
716 ptr+=
sizeof(state->header);
719 mi_int2store(ptr,state->open_count); ptr +=2;
720 *ptr++= (
unsigned char)state->changed; *ptr++= state->sortkey;
721 mi_rowstore(ptr,state->state.records); ptr +=8;
722 mi_rowstore(ptr,state->state.del); ptr +=8;
723 mi_rowstore(ptr,state->split); ptr +=8;
724 mi_sizestore(ptr,state->dellink); ptr +=8;
725 mi_sizestore(ptr,state->state.key_file_length); ptr +=8;
726 mi_sizestore(ptr,state->state.data_file_length); ptr +=8;
727 mi_sizestore(ptr,state->state.empty); ptr +=8;
728 mi_sizestore(ptr,state->state.key_empty); ptr +=8;
729 mi_int8store(ptr,state->auto_increment); ptr +=8;
730 mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
731 mi_int4store(ptr,state->process); ptr +=4;
732 mi_int4store(ptr,state->unique); ptr +=4;
733 mi_int4store(ptr,state->status); ptr +=4;
734 mi_int4store(ptr,state->update_count); ptr +=4;
736 ptr+=state->state_diff_length;
738 for (i=0; i < keys; i++)
740 mi_sizestore(ptr,state->key_root[i]); ptr +=8;
742 for (i=0; i < key_blocks; i++)
744 mi_sizestore(ptr,state->key_del[i]); ptr +=8;
748 uint32_t key_parts= mi_uint2korr(state->header.key_parts);
749 mi_int4store(ptr,state->sec_index_changed); ptr +=4;
750 mi_int4store(ptr,state->sec_index_used); ptr +=4;
751 mi_int4store(ptr,state->version); ptr +=4;
752 mi_int8store(ptr,state->key_map); ptr +=8;
753 mi_int8store(ptr,(uint64_t) state->create_time); ptr +=8;
754 mi_int8store(ptr,(uint64_t) state->recover_time); ptr +=8;
755 mi_int8store(ptr,(uint64_t) state->check_time); ptr +=8;
756 mi_sizestore(ptr,state->rec_per_key_rows); ptr+=8;
757 for (i=0 ; i < key_parts ; i++)
759 mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4;
764 return(my_pwrite(file, buff, (
size_t) (ptr-buff), 0L,
765 MYF(MY_NABP | MY_THREADSAFE)) != 0);
766 return(internal::my_write(file, buff, (
size_t) (ptr-buff),
771 static unsigned char *mi_state_info_read(
unsigned char *ptr,
MI_STATE_INFO *state)
773 uint32_t i,keys,key_parts,key_blocks;
774 memcpy(&state->header,ptr,
sizeof(state->header));
775 ptr +=
sizeof(state->header);
776 keys=(uint) state->header.keys;
777 key_parts=mi_uint2korr(state->header.key_parts);
778 key_blocks=state->header.max_block_size_index;
780 state->open_count = mi_uint2korr(ptr); ptr +=2;
781 state->changed= *ptr++;
782 state->sortkey = (uint) *ptr++;
783 state->state.records= mi_rowkorr(ptr); ptr +=8;
784 state->state.del = mi_rowkorr(ptr); ptr +=8;
785 state->split = mi_rowkorr(ptr); ptr +=8;
786 state->dellink= mi_sizekorr(ptr); ptr +=8;
787 state->state.key_file_length = mi_sizekorr(ptr); ptr +=8;
788 state->state.data_file_length= mi_sizekorr(ptr); ptr +=8;
789 state->state.empty = mi_sizekorr(ptr); ptr +=8;
790 state->state.key_empty= mi_sizekorr(ptr); ptr +=8;
791 state->auto_increment=mi_uint8korr(ptr); ptr +=8;
792 state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
793 state->process= mi_uint4korr(ptr); ptr +=4;
794 state->unique = mi_uint4korr(ptr); ptr +=4;
795 state->status = mi_uint4korr(ptr); ptr +=4;
796 state->update_count=mi_uint4korr(ptr); ptr +=4;
798 ptr+= state->state_diff_length;
800 for (i=0; i < keys; i++)
802 state->key_root[i]= mi_sizekorr(ptr); ptr +=8;
804 for (i=0; i < key_blocks; i++)
806 state->key_del[i] = mi_sizekorr(ptr); ptr +=8;
808 state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
809 state->sec_index_used = mi_uint4korr(ptr); ptr +=4;
810 state->version = mi_uint4korr(ptr); ptr +=4;
811 state->key_map = mi_uint8korr(ptr); ptr +=8;
812 state->create_time = (time_t) mi_sizekorr(ptr); ptr +=8;
813 state->recover_time =(time_t) mi_sizekorr(ptr); ptr +=8;
814 state->check_time = (time_t) mi_sizekorr(ptr); ptr +=8;
815 state->rec_per_key_rows=mi_sizekorr(ptr); ptr +=8;
816 for (i=0 ; i < key_parts ; i++)
818 state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
824 uint32_t mi_state_info_read_dsk(
int file,
MI_STATE_INFO *state,
bool pRead)
826 unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
830 if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
833 else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
835 mi_state_info_read(buff, state);
845 uint32_t mi_base_info_write(
int file,
MI_BASE_INFO *base)
847 unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
849 mi_sizestore(ptr,base->keystart); ptr +=8;
850 mi_sizestore(ptr,base->max_data_file_length); ptr +=8;
851 mi_sizestore(ptr,base->max_key_file_length); ptr +=8;
852 mi_rowstore(ptr,base->records); ptr +=8;
853 mi_rowstore(ptr,base->reloc); ptr +=8;
854 mi_int4store(ptr,base->mean_row_length); ptr +=4;
855 mi_int4store(ptr,base->reclength); ptr +=4;
856 mi_int4store(ptr,base->pack_reclength); ptr +=4;
857 mi_int4store(ptr,base->min_pack_length); ptr +=4;
858 mi_int4store(ptr,base->max_pack_length); ptr +=4;
859 mi_int4store(ptr,base->min_block_length); ptr +=4;
860 mi_int4store(ptr,base->fields); ptr +=4;
861 mi_int4store(ptr,base->pack_fields); ptr +=4;
862 *ptr++=base->rec_reflength;
863 *ptr++=base->key_reflength;
865 *ptr++=base->auto_key;
866 mi_int2store(ptr,base->pack_bits); ptr +=2;
867 mi_int2store(ptr,base->blobs); ptr +=2;
868 mi_int2store(ptr,base->max_key_block_length); ptr +=2;
869 mi_int2store(ptr,base->max_key_length); ptr +=2;
870 mi_int2store(ptr,base->extra_alloc_bytes); ptr +=2;
871 *ptr++= base->extra_alloc_procent;
874 mi_int2store(ptr,UINT16_C(0)); ptr +=2;
875 mi_int4store(ptr,UINT32_C(0)); ptr +=4;
877 memset(ptr, 0, 6); ptr +=6;
878 return internal::my_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
882 static unsigned char *my_n_base_info_read(
unsigned char *ptr,
MI_BASE_INFO *base)
884 base->keystart = mi_sizekorr(ptr); ptr +=8;
885 base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
886 base->max_key_file_length = mi_sizekorr(ptr); ptr +=8;
887 base->records = (ha_rows) mi_sizekorr(ptr); ptr +=8;
888 base->reloc = (ha_rows) mi_sizekorr(ptr); ptr +=8;
889 base->mean_row_length = mi_uint4korr(ptr); ptr +=4;
890 base->reclength = mi_uint4korr(ptr); ptr +=4;
891 base->pack_reclength = mi_uint4korr(ptr); ptr +=4;
892 base->min_pack_length = mi_uint4korr(ptr); ptr +=4;
893 base->max_pack_length = mi_uint4korr(ptr); ptr +=4;
894 base->min_block_length = mi_uint4korr(ptr); ptr +=4;
895 base->fields = mi_uint4korr(ptr); ptr +=4;
896 base->pack_fields = mi_uint4korr(ptr); ptr +=4;
898 base->rec_reflength = *ptr++;
899 base->key_reflength = *ptr++;
901 base->auto_key= *ptr++;
902 base->pack_bits = mi_uint2korr(ptr); ptr +=2;
903 base->blobs = mi_uint2korr(ptr); ptr +=2;
904 base->max_key_block_length= mi_uint2korr(ptr); ptr +=2;
905 base->max_key_length = mi_uint2korr(ptr); ptr +=2;
906 base->extra_alloc_bytes = mi_uint2korr(ptr); ptr +=2;
907 base->extra_alloc_procent = *ptr++;
920 uint32_t mi_keydef_write(
int file,
MI_KEYDEF *keydef)
922 unsigned char buff[MI_KEYDEF_SIZE];
923 unsigned char *ptr=buff;
925 *ptr++ = (
unsigned char) keydef->keysegs;
926 *ptr++ = keydef->key_alg;
927 mi_int2store(ptr,keydef->flag); ptr +=2;
928 mi_int2store(ptr,keydef->block_length); ptr +=2;
929 mi_int2store(ptr,keydef->keylength); ptr +=2;
930 mi_int2store(ptr,keydef->minlength); ptr +=2;
931 mi_int2store(ptr,keydef->maxlength); ptr +=2;
932 return internal::my_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
935 static unsigned char *mi_keydef_read(
unsigned char *ptr,
MI_KEYDEF *keydef)
937 keydef->keysegs = (uint) *ptr++;
938 keydef->key_alg = *ptr++;
940 keydef->flag = mi_uint2korr(ptr); ptr +=2;
941 keydef->block_length = mi_uint2korr(ptr); ptr +=2;
942 keydef->keylength = mi_uint2korr(ptr); ptr +=2;
943 keydef->minlength = mi_uint2korr(ptr); ptr +=2;
944 keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
945 keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
946 keydef->underflow_block_length=keydef->block_length/3;
955 int mi_keyseg_write(
int file,
const HA_KEYSEG *keyseg)
957 unsigned char buff[HA_KEYSEG_SIZE];
958 unsigned char *ptr=buff;
961 *ptr++= keyseg->type;
962 *ptr++= keyseg->language;
963 *ptr++= keyseg->null_bit;
964 *ptr++= keyseg->bit_start;
965 *ptr++= keyseg->bit_end;
966 *ptr++= keyseg->bit_length;
967 mi_int2store(ptr,keyseg->flag); ptr+=2;
968 mi_int2store(ptr,keyseg->length); ptr+=2;
969 mi_int4store(ptr,keyseg->start); ptr+=4;
970 pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
971 mi_int4store(ptr, pos);
974 return internal::my_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
978 static unsigned char *mi_keyseg_read(
unsigned char *ptr,
HA_KEYSEG *keyseg)
980 keyseg->type = *ptr++;
981 keyseg->language = *ptr++;
982 keyseg->null_bit = *ptr++;
983 keyseg->bit_start = *ptr++;
984 keyseg->bit_end = *ptr++;
985 keyseg->bit_length = *ptr++;
986 keyseg->flag = mi_uint2korr(ptr); ptr +=2;
987 keyseg->length = mi_uint2korr(ptr); ptr +=2;
988 keyseg->start = mi_uint4korr(ptr); ptr +=4;
989 keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
991 if (keyseg->null_bit)
992 keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
995 keyseg->bit_pos= (uint16_t)keyseg->null_pos;
1005 uint32_t mi_uniquedef_write(
int file,
MI_UNIQUEDEF *def)
1007 unsigned char buff[MI_UNIQUEDEF_SIZE];
1008 unsigned char *ptr=buff;
1010 mi_int2store(ptr,def->keysegs); ptr+=2;
1011 *ptr++= (
unsigned char) def->key;
1012 *ptr++ = (
unsigned char) def->null_are_equal;
1014 return internal::my_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1017 static unsigned char *mi_uniquedef_read(
unsigned char *ptr,
MI_UNIQUEDEF *def)
1019 def->keysegs = mi_uint2korr(ptr);
1021 def->null_are_equal=ptr[3];
1029 uint32_t mi_recinfo_write(
int file,
MI_COLUMNDEF *recinfo)
1031 unsigned char buff[MI_COLUMNDEF_SIZE];
1032 unsigned char *ptr=buff;
1034 mi_int2store(ptr,recinfo->type); ptr +=2;
1035 mi_int2store(ptr,recinfo->length); ptr +=2;
1036 *ptr++ = recinfo->null_bit;
1037 mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
1038 return internal::my_write(file, buff, (
size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1041 static unsigned char *mi_recinfo_read(
unsigned char *ptr,
MI_COLUMNDEF *recinfo)
1043 recinfo->type= mi_sint2korr(ptr); ptr +=2;
1044 recinfo->length=mi_uint2korr(ptr); ptr +=2;
1045 recinfo->null_bit= (uint8_t) *ptr++;
1046 recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1062 info->dfile=internal::my_open(share->data_file_name, share->mode,
1064 return info->dfile >= 0 ? 0 : 1;
1070 if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
1091 int mi_disable_indexes(
MI_INFO *info)
1095 mi_clear_all_keys_active(share->state.key_map);
1119 int mi_enable_indexes(
MI_INFO *info)
1124 if (share->state.state.data_file_length ||
1125 (share->state.state.key_file_length != share->base.keystart))
1127 mi_print_error(info->s, HA_ERR_CRASHED);
1128 error= HA_ERR_CRASHED;
1131 mi_set_all_keys_active(share->state.key_map, share->base.keys);
1152 int mi_indexes_are_disabled(
MI_INFO *info)
1161 if (!share->base.keys ||
1162 (mi_is_all_keys_active(share->state.key_map, share->base.keys)))
1166 if (mi_is_any_key_active(share->state.key_map))