00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "myisam_priv.h"
00019
00020 using namespace drizzled;
00021
00022
00023
00024 unsigned char *_mi_fetch_keypage(MI_INFO *info, MI_KEYDEF *keyinfo,
00025 internal::my_off_t page, int, unsigned char *buff, int)
00026 {
00027 if (not pread(info->s->kfile, buff, keyinfo->block_length, page))
00028 {
00029 info->last_keypage=HA_OFFSET_ERROR;
00030 mi_print_error(info->s, HA_ERR_CRASHED);
00031 errno=HA_ERR_CRASHED;
00032 return(0);
00033 }
00034 unsigned char* tmp= buff;
00035 if (tmp == info->buff)
00036 info->buff_used=1;
00037 info->last_keypage=page;
00038 uint32_t page_size=mi_getint(tmp);
00039 if (page_size < 4 || page_size > keyinfo->block_length)
00040 {
00041 info->last_keypage = HA_OFFSET_ERROR;
00042 mi_print_error(info->s, HA_ERR_CRASHED);
00043 errno = HA_ERR_CRASHED;
00044 tmp = 0;
00045 }
00046 return(tmp);
00047 }
00048
00049
00050
00051
00052 int _mi_write_keypage(MI_INFO *info, MI_KEYDEF *keyinfo,
00053 internal::my_off_t page, int, unsigned char *buff)
00054 {
00055 uint32_t length;
00056
00057 #ifndef FAST
00058 if (page < info->s->base.keystart ||
00059 page+keyinfo->block_length > info->state->key_file_length ||
00060 (page & (MI_MIN_KEY_BLOCK_LENGTH-1)))
00061 {
00062 errno=EINVAL;
00063 return((-1));
00064 }
00065 #endif
00066
00067 if ((length=keyinfo->block_length) > IO_SIZE*2 &&
00068 info->state->key_file_length != page+length)
00069 length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1));
00070 #ifdef HAVE_VALGRIND
00071 {
00072 length=mi_getint(buff);
00073 memset(buff+length, 0, keyinfo->block_length-length);
00074 length=keyinfo->block_length;
00075 }
00076 #endif
00077 return not pwrite(info->s->kfile, buff, length, page);
00078 }
00079
00080
00081
00082
00083 int _mi_dispose(MI_INFO *info, MI_KEYDEF *keyinfo, internal::my_off_t pos, int)
00084 {
00085 internal::my_off_t old_link;
00086 unsigned char buff[8];
00087
00088 old_link= info->s->state.key_del[keyinfo->block_size_index];
00089 info->s->state.key_del[keyinfo->block_size_index]= pos;
00090 mi_sizestore(buff,old_link);
00091 info->s->state.changed|= STATE_NOT_SORTED_PAGES;
00092 return not pwrite(info->s->kfile, buff, sizeof(buff), pos);
00093 }
00094
00095
00096
00097
00098 internal::my_off_t _mi_new(MI_INFO *info, MI_KEYDEF *keyinfo, int)
00099 {
00100 internal::my_off_t pos;
00101 unsigned char buff[8];
00102
00103 if ((pos= info->s->state.key_del[keyinfo->block_size_index]) ==
00104 HA_OFFSET_ERROR)
00105 {
00106 if (info->state->key_file_length >=
00107 info->s->base.max_key_file_length - keyinfo->block_length)
00108 {
00109 errno=HA_ERR_INDEX_FILE_FULL;
00110 return(HA_OFFSET_ERROR);
00111 }
00112 pos=info->state->key_file_length;
00113 info->state->key_file_length+= keyinfo->block_length;
00114 }
00115 else if (pread(info->s->kfile, buff, sizeof(buff), pos))
00116 info->s->state.key_del[keyinfo->block_size_index]= mi_sizekorr(buff);
00117 else
00118 pos= HA_OFFSET_ERROR;
00119 info->s->state.changed|= STATE_NOT_SORTED_PAGES;
00120 return(pos);
00121 }