20 #define IS_CHAR ((uint) 32768)
23 #define HEAD_LENGTH 32
27 #define MAX_QUICK_TABLE_BITS 9
30 #define MAX_QUICK_TABLE_BITS 6
33 #define get_bit(BU) ((BU)->bits ? \
34 (BU)->current_byte & ((mi_bit_type) 1 << --(BU)->bits) :\
35 (fill_buffer(BU), (BU)->bits= BITS_SAVED-1,\
36 (BU)->current_byte & ((mi_bit_type) 1 << (BITS_SAVED-1))))
37 #define skip_to_next_byte(BU) ((BU)->bits&=~7)
38 #define get_bits(BU,count) (((BU)->bits >= count) ? (((BU)->current_byte >> ((BU)->bits-=count)) & mask[count]) : fill_and_get_bits(BU,count))
40 #define decode_bytes_test_bit(bit) \
41 if (low_byte & (1 << (7-bit))) \
44 { bits-=(bit+1); break; } \
48 #define OFFSET_TABLE_SIZE 512
51 uint16 **decode_table,uchar **intervall_buff,
53 static void make_quick_table(uint16 *to_table,uint16 *decode_table,
54 uint *next_free,uint value,uint bits,
56 static void fill_quick_table(uint16 *
table,uint bits, uint max_bits,
58 static uint copy_decode_table(uint16 *to_pos,uint
offset,
59 uint16 *decode_table);
60 static uint find_longest_bitstream(uint16 *
table, uint16 *end);
66 uchar *to,uchar *end);
68 uchar *to,uchar *end);
70 uchar *to,uchar *end);
72 uchar *to, uchar *end);
74 uchar *to,uchar *end);
76 uchar *to,uchar *end);
78 uchar *to,uchar *end);
80 uchar *to, uchar *end);
82 uchar *to,uchar *end);
84 uchar *to,uchar *end);
86 uchar *to,uchar *end);
88 uchar *to,uchar *end);
90 uchar *to,uchar *end);
92 uchar *to,uchar *end);
94 uchar *to,uchar *end);
96 uchar *to, uchar *end);
98 uchar *to, uchar *end);
100 uchar *to, uchar *end);
102 uchar *to,uchar *end);
104 static void init_bit_buffer(
MI_BIT_BUFF *bit_buff,uchar *buffer,uint length);
105 static uint fill_and_get_bits(
MI_BIT_BUFF *bit_buff,uint count);
107 static uint max_bit(uint value);
114 static mi_bit_type mask[]=
117 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
118 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
119 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
120 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
122 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
123 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
124 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
125 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
132 my_bool _mi_read_pack_info(
MI_INFO *info, pbool fix_keys)
136 uint
i,trees,huff_tree_bits,rec_reflength,length;
137 uint16 *decode_table,*tmp_buff;
138 ulong elements,intervall_length;
140 uchar *intervall_buff;
141 uchar header[HEAD_LENGTH];
144 DBUG_ENTER(
"_mi_read_pack_info");
146 if (myisam_quick_table_bits < 4)
147 myisam_quick_table_bits=4;
148 else if (myisam_quick_table_bits > MAX_QUICK_TABLE_BITS)
149 myisam_quick_table_bits=MAX_QUICK_TABLE_BITS;
153 if (
mysql_file_read(file, (uchar*) header,
sizeof(header), MYF(MY_NABP)))
156 my_errno=HA_ERR_END_OF_FILE;
160 if (memcmp((uchar*) header, (uchar*) myisam_pack_file_magic, 3))
162 my_errno=HA_ERR_WRONG_IN_RECORD;
165 share->pack.version= header[3];
166 share->pack.header_length= uint4korr(header+4);
167 share->min_pack_length=(uint) uint4korr(header+8);
168 share->max_pack_length=(uint) uint4korr(header+12);
169 elements=uint4korr(header+16);
170 intervall_length=uint4korr(header+20);
171 trees=uint2korr(header+24);
172 share->pack.ref_length=header[26];
173 rec_reflength=header[27];
174 diff_length=(int) rec_reflength - (
int) share->base.rec_reflength;
176 share->rec_reflength=rec_reflength;
177 share->base.min_block_length=share->min_pack_length+1;
178 if (share->min_pack_length > 254)
179 share->base.min_block_length+=2;
180 DBUG_PRINT(
"info", (
"fixed header length: %u", HEAD_LENGTH));
181 DBUG_PRINT(
"info", (
"total header length: %lu", share->pack.header_length));
182 DBUG_PRINT(
"info", (
"pack file version: %u", share->pack.version));
183 DBUG_PRINT(
"info", (
"min pack length: %lu", share->min_pack_length));
184 DBUG_PRINT(
"info", (
"max pack length: %lu", share->max_pack_length));
185 DBUG_PRINT(
"info", (
"elements of all trees: %lu", elements));
186 DBUG_PRINT(
"info", (
"distinct values bytes: %lu", intervall_length));
187 DBUG_PRINT(
"info", (
"number of code trees: %u", trees));
188 DBUG_PRINT(
"info", (
"bytes for record lgt: %u", share->pack.ref_length));
189 DBUG_PRINT(
"info", (
"record pointer length: %u", rec_reflength));
198 intervall_length*
sizeof(uchar)),
201 intervall_buff=(uchar*) (share->decode_trees+trees);
211 length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits));
219 if (!(share->decode_tables=(uint16*)
220 my_malloc((length + OFFSET_TABLE_SIZE) *
sizeof(uint16) +
221 (uint) (share->pack.header_length -
sizeof(header) +
222 (BITS_SAVED / 8) - 1), MYF(MY_WME | MY_ZEROFILL))))
224 tmp_buff=share->decode_tables+length;
225 disk_cache= (uchar*) (tmp_buff+OFFSET_TABLE_SIZE);
228 (uint) (share->pack.header_length-
sizeof(header)),
232 huff_tree_bits=max_bit(trees ? trees-1 : 0);
233 init_bit_buffer(&bit_buff, disk_cache,
234 (uint) (share->pack.header_length-
sizeof(header)));
236 for (i=0 ; i < share->base.fields ; i++)
238 share->rec[
i].base_type=(
enum en_fieldtype) get_bits(&bit_buff,5);
239 share->rec[
i].pack_type=(uint) get_bits(&bit_buff,6);
240 share->rec[
i].space_length_bits=get_bits(&bit_buff,5);
241 share->rec[
i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
243 share->rec[
i].unpack=get_unpack_function(share->rec+i);
244 DBUG_PRINT(
"info", (
"col: %2u type: %2u pack: %u slbits: %2u",
245 i, share->rec[i].base_type, share->rec[i].pack_type,
246 share->rec[i].space_length_bits));
248 skip_to_next_byte(&bit_buff);
253 decode_table=share->decode_tables;
254 for (i=0 ; i < trees ; i++)
255 if (read_huff_table(&bit_buff,share->decode_trees+i,&decode_table,
256 &intervall_buff,tmp_buff))
259 decode_table=(uint16*)
260 my_realloc((uchar*) share->decode_tables,
261 (uint) ((uchar*) decode_table - (uchar*) share->decode_tables),
262 MYF(MY_HOLD_ON_ERROR));
265 my_ptrdiff_t diff=PTR_BYTE_DIFF(decode_table,share->decode_tables);
266 share->decode_tables=decode_table;
267 for (i=0 ; i < trees ; i++)
268 share->decode_trees[i].table=ADD_TO_PTR(share->decode_trees[i].table,
275 for (i=0 ; i < share->base.keys ; i++)
278 keyinfo->keylength+= (uint16) diff_length;
279 keyinfo->minlength+= (uint16) diff_length;
280 keyinfo->maxlength+= (uint16) diff_length;
281 keyinfo->seg[keyinfo->flag & HA_FULLTEXT ?
282 FT_SEGS : keyinfo->keysegs].length= (uint16) rec_reflength;
284 if (share->ft2_keyinfo.seg)
286 MI_KEYDEF *ft2_keyinfo= &share->ft2_keyinfo;
287 ft2_keyinfo->keylength+= (uint16) diff_length;
288 ft2_keyinfo->minlength+= (uint16) diff_length;
289 ft2_keyinfo->maxlength+= (uint16) diff_length;
293 if (bit_buff.error || bit_buff.pos < bit_buff.end)
299 my_errno=HA_ERR_WRONG_IN_RECORD;
301 my_free(share->decode_tables);
303 my_free(share->decode_trees);
328 uint16 **decode_table, uchar **intervall_buff,
331 uint min_chr,elements,char_bits,offset_bits,
size,intervall_length,table_bits,
334 DBUG_ENTER(
"read_huff_table");
336 if (!get_bits(bit_buff,1))
339 min_chr=get_bits(bit_buff,8);
340 elements=get_bits(bit_buff,9);
341 char_bits=get_bits(bit_buff,5);
342 offset_bits=get_bits(bit_buff,5);
345 DBUG_PRINT(
"info", (
"byte value compression"));
346 DBUG_PRINT(
"info", (
"minimum byte value: %u", min_chr));
347 DBUG_PRINT(
"info", (
"number of tree nodes: %u", elements));
348 DBUG_PRINT(
"info", (
"bits for values: %u", char_bits));
349 DBUG_PRINT(
"info", (
"bits for tree offsets: %u", offset_bits));
352 DBUG_PRINT(
"error", (
"ERROR: illegal number of tree elements: %u",
361 elements=get_bits(bit_buff,15);
362 intervall_length=get_bits(bit_buff,16);
363 char_bits=get_bits(bit_buff,5);
364 offset_bits=get_bits(bit_buff,5);
365 decode_tree->quick_table_bits=0;
367 DBUG_PRINT(
"info", (
"distinct column value compression"));
368 DBUG_PRINT(
"info", (
"number of tree nodes: %u", elements));
369 DBUG_PRINT(
"info", (
"value buffer length: %u", intervall_length));
370 DBUG_PRINT(
"info", (
"bits for value index: %u", char_bits));
371 DBUG_PRINT(
"info", (
"bits for tree offsets: %u", offset_bits));
374 DBUG_PRINT(
"info", (
"tree size in uint16: %u", size));
375 DBUG_PRINT(
"info", (
"tree size in bytes: %u",
376 size * (uint)
sizeof(uint16)));
378 for (end=ptr+size ; ptr < end ; ptr++)
380 if (get_bit(bit_buff))
382 *ptr= (uint16) get_bits(bit_buff,offset_bits);
383 if ((ptr + *ptr >= end) || !*ptr)
385 DBUG_PRINT(
"error", (
"ERROR: illegal pointer in decode tree"));
390 *ptr= (uint16) (IS_CHAR + (get_bits(bit_buff,char_bits) + min_chr));
392 skip_to_next_byte(bit_buff);
394 decode_tree->table= *decode_table;
395 decode_tree->intervalls= *intervall_buff;
396 if (! intervall_length)
400 table_bits= find_longest_bitstream(tmp_buff, ptr);
401 if (table_bits >= OFFSET_TABLE_SIZE)
403 if (table_bits > myisam_quick_table_bits)
404 table_bits=myisam_quick_table_bits;
405 DBUG_PRINT(
"info", (
"table bits: %u", table_bits));
407 next_free_offset= (1 << table_bits);
408 make_quick_table(*decode_table,tmp_buff,&next_free_offset,0,table_bits,
410 (*decode_table)+= next_free_offset;
411 decode_tree->quick_table_bits=table_bits;
421 bit_buff->pos-= bit_buff->bits/8;
423 memcpy(*intervall_buff,bit_buff->pos,(
size_t) intervall_length);
424 (*intervall_buff)+=intervall_length;
425 bit_buff->pos+=intervall_length;
471 static void make_quick_table(uint16 *to_table, uint16 *decode_table,
472 uint *next_free_offset, uint value, uint bits,
475 DBUG_ENTER(
"make_quick_table");
487 to_table[value]= (uint16) *next_free_offset;
492 *next_free_offset= copy_decode_table(to_table, *next_free_offset,
498 if (!(*decode_table & IS_CHAR))
501 make_quick_table(to_table, decode_table + *decode_table,
502 next_free_offset, value, bits, max_bits);
511 fill_quick_table(to_table + value, bits, max_bits, (uint) *decode_table);
517 if (!(*decode_table & IS_CHAR))
520 make_quick_table(to_table, decode_table + *decode_table,
521 next_free_offset, value, bits, max_bits);
530 fill_quick_table(to_table + value, bits, max_bits, (uint) *decode_table);
561 static void fill_quick_table(uint16 *
table, uint bits, uint max_bits,
565 DBUG_ENTER(
"fill_quick_table");
572 value|= (max_bits - bits) << 8 | IS_CHAR;
574 for (end= table + ((my_ptrdiff_t) 1 << bits); table < end; table++)
576 *table= (uint16) value;
598 static uint copy_decode_table(uint16 *to_pos, uint
offset,
599 uint16 *decode_table)
602 DBUG_ENTER(
"copy_decode_table");
605 if (!(*decode_table & IS_CHAR))
610 offset=copy_decode_table(to_pos,offset+2,decode_table+ *decode_table);
615 to_pos[
offset]= *decode_table;
622 if (!(*decode_table & IS_CHAR))
625 to_pos[prev_offset+1]=(uint16) (offset-prev_offset-1);
627 offset=copy_decode_table(to_pos,offset,decode_table+ *decode_table);
632 to_pos[prev_offset+1]= *decode_table;
662 static uint find_longest_bitstream(uint16 *table, uint16 *end)
667 if (!(*table & IS_CHAR))
669 uint16 *next= table + *
table;
670 if (next > end || next == table)
672 DBUG_PRINT(
"error", (
"ERROR: illegal pointer in decode tree"));
673 return OFFSET_TABLE_SIZE;
675 length= find_longest_bitstream(next, end) + 1;
678 if (!(*table & IS_CHAR))
680 uint16 *next= table + *
table;
681 if (next > end || next == table)
683 DBUG_PRINT(
"error", (
"ERROR: illegal pointer in decode tree"));
684 return OFFSET_TABLE_SIZE;
686 length2= find_longest_bitstream(next, end) + 1;
687 length= MY_MAX(length, length2);
707 int _mi_read_pack_record(
MI_INFO *info, my_off_t filepos, uchar *
buf)
711 DBUG_ENTER(
"mi_read_pack_record");
713 if (filepos == HA_OFFSET_ERROR)
717 if (_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
718 &info->rec_buff, file, filepos))
721 block_info.rec_len - block_info.offset, MYF(MY_NABP)))
723 info->update|= HA_STATE_AKTIV;
724 DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
725 info->rec_buff, block_info.rec_len));
727 my_errno=HA_ERR_WRONG_IN_RECORD;
735 register uchar *to, uchar *from, ulong reclength)
741 DBUG_ENTER(
"_mi_pack_rec_unpack");
743 init_bit_buffer(bit_buff, (uchar*) from, reclength);
745 for (current_field=share->rec, end=current_field+share->base.fields ;
746 current_field < end ;
747 current_field++,to=end_field)
749 end_field=to+current_field->length;
750 (*current_field->unpack)(current_field, bit_buff, (uchar*)
to,
753 if (!bit_buff->error &&
754 bit_buff->pos - bit_buff->bits / 8 == bit_buff->end)
756 info->update&= ~HA_STATE_AKTIV;
757 DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD);
766 switch (
rec->base_type) {
767 case FIELD_SKIP_ZERO:
768 if (
rec->pack_type & PACK_TYPE_ZERO_FILL)
769 return &uf_zerofill_skip_zero;
770 return &uf_skip_zero;
772 if (
rec->pack_type & PACK_TYPE_SPACE_FIELDS)
773 return &uf_space_normal;
774 if (
rec->pack_type & PACK_TYPE_ZERO_FILL)
775 return &uf_zerofill_normal;
776 return &decode_bytes;
777 case FIELD_SKIP_ENDSPACE:
778 if (
rec->pack_type & PACK_TYPE_SPACE_FIELDS)
780 if (
rec->pack_type & PACK_TYPE_SELECTED)
781 return &uf_space_endspace_selected;
782 return &uf_space_endspace;
784 if (
rec->pack_type & PACK_TYPE_SELECTED)
785 return &uf_endspace_selected;
787 case FIELD_SKIP_PRESPACE:
788 if (
rec->pack_type & PACK_TYPE_SPACE_FIELDS)
790 if (
rec->pack_type & PACK_TYPE_SELECTED)
791 return &uf_space_prespace_selected;
792 return &uf_space_prespace;
794 if (
rec->pack_type & PACK_TYPE_SELECTED)
795 return &uf_prespace_selected;
799 case FIELD_INTERVALL:
800 return &uf_intervall;
807 if (
rec->length <= 256)
818 static void uf_zerofill_skip_zero(
MI_COLUMNDEF *
rec, MI_BIT_BUFF *bit_buff,
819 uchar *to, uchar *end)
821 if (get_bit(bit_buff))
822 memset(to, 0, (end-to));
825 end-=rec->space_length_bits;
826 decode_bytes(rec,bit_buff,to,end);
827 memset(end, 0, rec->space_length_bits);
831 static void uf_skip_zero(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
834 if (get_bit(bit_buff))
835 memset(to, 0, (end-to));
837 decode_bytes(rec,bit_buff,to,end);
840 static void uf_space_normal(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
843 if (get_bit(bit_buff))
844 memset(to,
' ', end - to);
846 decode_bytes(rec,bit_buff,to,end);
849 static void uf_space_endspace_selected(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
850 uchar *to, uchar *end)
853 if (get_bit(bit_buff))
854 memset(to,
' ', end-to);
857 if (get_bit(bit_buff))
859 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
864 if (to+spaces != end)
865 decode_bytes(rec,bit_buff,to,end-spaces);
866 memset(end-spaces,
' ', spaces);
869 decode_bytes(rec,bit_buff,to,end);
873 static void uf_endspace_selected(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
874 uchar *to, uchar *end)
877 if (get_bit(bit_buff))
879 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
884 if (to+spaces != end)
885 decode_bytes(rec,bit_buff,to,end-spaces);
886 memset(end - spaces,
' ', spaces);
889 decode_bytes(rec,bit_buff,to,end);
892 static void uf_space_endspace(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
896 if (get_bit(bit_buff))
897 memset(to,
' ', end - to);
900 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
905 if (to+spaces != end)
906 decode_bytes(rec,bit_buff,to,end-spaces);
907 memset(end - spaces,
' ', spaces);
911 static void uf_endspace(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
915 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
920 if (to+spaces != end)
921 decode_bytes(rec,bit_buff,to,end-spaces);
922 memset(end - spaces,
' ', spaces);
925 static void uf_space_prespace_selected(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
926 uchar *to, uchar *end)
929 if (get_bit(bit_buff))
930 memset(to,
' ', end - to);
933 if (get_bit(bit_buff))
935 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
940 memset(to,
' ', spaces);
941 if (to+spaces != end)
942 decode_bytes(rec,bit_buff,to+spaces,end);
945 decode_bytes(rec,bit_buff,to,end);
950 static void uf_prespace_selected(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
951 uchar *to, uchar *end)
954 if (get_bit(bit_buff))
956 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
961 memset(to,
' ', spaces);
962 if (to+spaces != end)
963 decode_bytes(rec,bit_buff,to+spaces,end);
966 decode_bytes(rec,bit_buff,to,end);
970 static void uf_space_prespace(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
974 if (get_bit(bit_buff))
975 memset(to,
' ', end-to);
978 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
983 memset(to,
' ', spaces);
984 if (to+spaces != end)
985 decode_bytes(rec,bit_buff,to+spaces,end);
989 static void uf_prespace(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
993 if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
998 memset(to,
' ', spaces);
999 if (to+spaces != end)
1000 decode_bytes(rec,bit_buff,to+spaces,end);
1003 static void uf_zerofill_normal(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
1006 end-=rec->space_length_bits;
1007 decode_bytes(rec,bit_buff,(uchar*) to,end);
1008 memset(end, 0, rec->space_length_bits);
1012 MI_BIT_BUFF *bit_buff __attribute__((unused)),
1016 memcpy(to,rec->huff_tree->intervalls,(
size_t) (end-to));
1019 static void uf_intervall(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
1022 reg1 uint field_length=(uint) (end-to);
1023 memcpy(to,rec->huff_tree->intervalls+field_length*decode_pos(bit_buff,
1025 (
size_t) field_length);
1030 static void uf_zero(
MI_COLUMNDEF *rec __attribute__((unused)),
1031 MI_BIT_BUFF *bit_buff __attribute__((unused)),
1032 uchar *to, uchar *end)
1034 memset(to, 0, (end-to));
1037 static void uf_blob(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
1038 uchar *to, uchar *end)
1040 if (get_bit(bit_buff))
1041 memset(to, 0, (end-to));
1044 ulong length=get_bits(bit_buff,rec->space_length_bits);
1045 uint pack_length=(uint) (end-to)-portable_sizeof_char_ptr;
1046 if (bit_buff->blob_pos+length > bit_buff->blob_end)
1049 memset(to, 0, (end-to));
1052 decode_bytes(rec,bit_buff,bit_buff->blob_pos,bit_buff->blob_pos+length);
1053 _mi_store_blob_length((uchar*) to,pack_length,length);
1054 memcpy(to+pack_length, &bit_buff->blob_pos,
sizeof(
char*));
1055 bit_buff->blob_pos+=length;
1060 static void uf_varchar1(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
1061 uchar *to, uchar *end __attribute__((unused)))
1063 if (get_bit(bit_buff))
1067 ulong length=get_bits(bit_buff,rec->space_length_bits);
1068 *to= (uchar) length;
1069 decode_bytes(rec,bit_buff,to+1,to+1+length);
1074 static void uf_varchar2(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
1075 uchar *to, uchar *end __attribute__((unused)))
1077 if (get_bit(bit_buff))
1081 ulong length=get_bits(bit_buff,rec->space_length_bits);
1082 int2store(to,length);
1083 decode_bytes(rec,bit_buff,to+2,to+2+length);
1089 #if BITS_SAVED == 64
1091 static void decode_bytes(
MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,
1094 reg1 uint bits,low_byte;
1096 reg4 uint table_bits,table_and;
1099 decode_tree=rec->decode_tree;
1100 bits=bit_buff->bits;
1101 table_bits=decode_tree->quick_table_bits;
1102 table_and= (1 << table_bits)-1;
1108 if (bit_buff->pos > bit_buff->end+4)
1113 bit_buff->current_byte= (bit_buff->current_byte << 32) +
1114 ((((uint) bit_buff->pos[3])) +
1115 (((uint) bit_buff->pos[2]) << 8) +
1116 (((uint) bit_buff->pos[1]) << 16) +
1117 (((uint) bit_buff->pos[0]) << 24));
1144 low_byte=(uint) (bit_buff->current_byte >> (bits - table_bits)) & table_and;
1145 low_byte=decode_tree->table[low_byte];
1146 if (low_byte & IS_CHAR)
1152 *to++ = (low_byte & 255);
1153 bits-= ((low_byte >> 8) & 31);
1158 pos=decode_tree->table+low_byte;
1163 low_byte=(uint) (bit_buff->current_byte >> (bits-8));
1164 decode_bytes_test_bit(0);
1165 decode_bytes_test_bit(1);
1166 decode_bytes_test_bit(2);
1167 decode_bytes_test_bit(3);
1168 decode_bytes_test_bit(4);
1169 decode_bytes_test_bit(5);
1170 decode_bytes_test_bit(6);
1171 decode_bytes_test_bit(7);
1176 }
while (to != end);
1178 bit_buff->bits=bits;
1184 static void decode_bytes(
MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
1187 reg1 uint bits,low_byte;
1189 reg4 uint table_bits,table_and;
1192 decode_tree=rec->huff_tree;
1193 bits=bit_buff->bits;
1194 table_bits=decode_tree->quick_table_bits;
1195 table_and= (1 << table_bits)-1;
1199 if (bits < table_bits)
1201 if (bit_buff->pos > bit_buff->end+1)
1206 #if BITS_SAVED == 32
1207 bit_buff->current_byte= (bit_buff->current_byte << 24) +
1208 (((uint) ((uchar) bit_buff->pos[2]))) +
1209 (((uint) ((uchar) bit_buff->pos[1])) << 8) +
1210 (((uint) ((uchar) bit_buff->pos[0])) << 16);
1216 bit_buff->current_byte= (bit_buff->current_byte << 8) +
1217 (uint) ((uchar) bit_buff->pos[0]);
1223 bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) +
1224 ((uint) ((uchar) bit_buff->pos[1]));
1231 low_byte=(bit_buff->current_byte >> (bits - table_bits)) & table_and;
1232 low_byte=decode_tree->table[low_byte];
1233 if (low_byte & IS_CHAR)
1235 *to++ = (low_byte & 255);
1236 bits-= ((low_byte >> 8) & 31);
1240 pos=decode_tree->table+low_byte;
1246 #if BITS_SAVED == 32
1247 bit_buff->current_byte= (bit_buff->current_byte << 24) +
1248 (((uint) ((uchar) bit_buff->pos[2]))) +
1249 (((uint) ((uchar) bit_buff->pos[1])) << 8) +
1250 (((uint) ((uchar) bit_buff->pos[0])) << 16);
1254 bit_buff->current_byte= (bit_buff->current_byte << 8) +
1255 (uint) ((uchar) bit_buff->pos[0]);
1260 low_byte=(uint) (bit_buff->current_byte >> (bits-8));
1261 decode_bytes_test_bit(0);
1262 decode_bytes_test_bit(1);
1263 decode_bytes_test_bit(2);
1264 decode_bytes_test_bit(3);
1265 decode_bytes_test_bit(4);
1266 decode_bytes_test_bit(5);
1267 decode_bytes_test_bit(6);
1268 decode_bytes_test_bit(7);
1271 *to++ = (uchar) *pos;
1273 }
while (to != end);
1275 bit_buff->bits=bits;
1281 static uint decode_pos(MI_BIT_BUFF *bit_buff,
MI_DECODE_TREE *decode_tree)
1283 uint16 *pos=decode_tree->table;
1286 if (get_bit(bit_buff))
1289 return (uint) (*pos & ~IS_CHAR);
1295 int _mi_read_rnd_pack_record(
MI_INFO *info, uchar *buf,
1296 register my_off_t filepos,
1297 my_bool skip_deleted_blocks)
1302 DBUG_ENTER(
"_mi_read_rnd_pack_record");
1304 if (filepos >= info->state->data_file_length)
1306 my_errno= HA_ERR_END_OF_FILE;
1310 if (info->opt_flag & READ_CACHE_USED)
1312 if (_mi_read_cache(&info->rec_cache, (uchar*) block_info.header,
1313 filepos, share->pack.ref_length,
1314 skip_deleted_blocks ? READING_NEXT : 0))
1316 b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
1317 &info->rec_buff, -1, filepos);
1320 b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
1321 &info->rec_buff, info->dfile, filepos);
1325 if (block_info.rec_len > share->max_pack_length)
1327 my_errno=HA_ERR_WRONG_IN_RECORD;
1332 if (info->opt_flag & READ_CACHE_USED)
1334 if (_mi_read_cache(&info->rec_cache, (uchar*) info->rec_buff,
1335 block_info.filepos, block_info.rec_len,
1336 skip_deleted_blocks ? READING_NEXT : 0))
1342 (uchar*) info->rec_buff + block_info.offset,
1343 block_info.rec_len-block_info.offset, MYF(MY_NABP)))
1346 info->packed_length=block_info.rec_len;
1347 info->lastpos=filepos;
1348 info->nextpos=block_info.filepos+block_info.rec_len;
1349 info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
1351 DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
1352 info->rec_buff, block_info.rec_len));
1354 DBUG_RETURN(my_errno);
1360 uint _mi_pack_get_block_info(
MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
1362 File file, my_off_t filepos)
1364 uchar *header=info->header;
1365 uint head_length, UNINIT_VAR(ref_length);
1366 LINT_INIT(ref_length);
1370 ref_length=myisam->s->pack.ref_length;
1377 return BLOCK_FATAL_ERROR;
1378 DBUG_DUMP(
"header",(uchar*) header,ref_length);
1380 head_length= read_pack_length((uint) myisam->s->pack.version, header,
1382 if (myisam->s->base.blobs)
1384 head_length+= read_pack_length((uint) myisam->s->pack.version,
1385 header + head_length, &info->blob_len);
1391 if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
1393 return BLOCK_FATAL_ERROR;
1394 bit_buff->blob_pos= (uchar*) *rec_buff_p + info->rec_len;
1395 bit_buff->blob_end= bit_buff->blob_pos + info->blob_len;
1396 myisam->blob_length=info->blob_len;
1398 info->filepos=filepos+head_length;
1401 info->offset= MY_MIN(info->rec_len, ref_length - head_length);
1402 memcpy(*rec_buff_p, header + head_length, info->offset);
1411 static void init_bit_buffer(MI_BIT_BUFF *bit_buff, uchar *buffer, uint length)
1413 bit_buff->pos=buffer;
1414 bit_buff->end=buffer+length;
1415 bit_buff->bits=bit_buff->error=0;
1416 bit_buff->current_byte=0;
1419 static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff, uint count)
1422 count-=bit_buff->bits;
1423 tmp=(bit_buff->current_byte & mask[bit_buff->bits]) << count;
1424 fill_buffer(bit_buff);
1425 bit_buff->bits=BITS_SAVED - count;
1426 return tmp+(bit_buff->current_byte >> (BITS_SAVED - count));
1432 static void fill_buffer(MI_BIT_BUFF *bit_buff)
1434 if (bit_buff->pos >= bit_buff->end)
1437 bit_buff->current_byte=0;
1441 #if BITS_SAVED == 64
1442 bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) +
1443 (((uint) ((uchar) bit_buff->pos[6])) << 8) +
1444 (((uint) ((uchar) bit_buff->pos[5])) << 16) +
1445 (((uint) ((uchar) bit_buff->pos[4])) << 24) +
1447 ((((uint) ((uchar) bit_buff->pos[3]))) +
1448 (((uint) ((uchar) bit_buff->pos[2])) << 8) +
1449 (((uint) ((uchar) bit_buff->pos[1])) << 16) +
1450 (((uint) ((uchar) bit_buff->pos[0])) << 24)) << 32));
1453 #if BITS_SAVED == 32
1454 bit_buff->current_byte= (((uint) ((uchar) bit_buff->pos[3])) +
1455 (((uint) ((uchar) bit_buff->pos[2])) << 8) +
1456 (((uint) ((uchar) bit_buff->pos[1])) << 16) +
1457 (((uint) ((uchar) bit_buff->pos[0])) << 24));
1460 bit_buff->current_byte= (uint) (((uint) ((uchar) bit_buff->pos[1]))+
1461 (((uint) ((uchar) bit_buff->pos[0])) << 8));
1469 static uint max_bit(
register uint value)
1482 #ifdef HAVE_SYS_MMAN_H
1483 #include <sys/mman.h>
1488 static int _mi_read_mempack_record(
MI_INFO *info,my_off_t filepos,uchar *buf);
1489 static int _mi_read_rnd_mempack_record(
MI_INFO*, uchar *,my_off_t, my_bool);
1491 my_bool _mi_memmap_file(
MI_INFO *info)
1496 DBUG_ENTER(
"mi_memmap_file");
1498 if (!info->s->file_map)
1500 my_off_t data_file_length= share->state.state.data_file_length;
1502 if (myisam_mmap_size != SIZE_T_MAX)
1505 eom= data_file_length > myisam_mmap_size - myisam_mmap_used - MEMMAP_EXTRA_MARGIN;
1507 myisam_mmap_used+= data_file_length + MEMMAP_EXTRA_MARGIN;
1511 eom= data_file_length > myisam_mmap_size - MEMMAP_EXTRA_MARGIN;
1515 DBUG_PRINT(
"warning", (
"File is too large for mmap"));
1519 share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
1521 DBUG_PRINT(
"warning",(
"File isn't extended for memmap"));
1522 if (myisam_mmap_size != SIZE_T_MAX)
1525 myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN;
1530 if (mi_dynmap_file(info,
1531 share->state.state.data_file_length +
1532 MEMMAP_EXTRA_MARGIN))
1534 if (myisam_mmap_size != SIZE_T_MAX)
1537 myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN;
1543 info->opt_flag|= MEMMAP_USED;
1544 info->read_record= share->read_record= _mi_read_mempack_record;
1545 share->read_rnd= _mi_read_rnd_mempack_record;
1550 void _mi_unmap_file(
MI_INFO *info)
1552 DBUG_ASSERT(info->s->options & HA_OPTION_COMPRESS_RECORD);
1554 (void) my_munmap((
char*) info->s->file_map, (size_t) info->s->mmaped_length);
1556 if (myisam_mmap_size != SIZE_T_MAX)
1559 myisam_mmap_used-= info->s->mmaped_length;
1565 static uchar *_mi_mempack_get_block_info(
MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
1569 header+= read_pack_length((uint) myisam->s->pack.version, header,
1571 if (myisam->s->base.blobs)
1573 header+= read_pack_length((uint) myisam->s->pack.version, header,
1576 if (!(mi_alloc_rec_buff(myisam, info->blob_len,
1579 bit_buff->blob_pos= (uchar*) *rec_buff_p;
1580 bit_buff->blob_end= (uchar*) *rec_buff_p + info->blob_len;
1586 static int _mi_read_mempack_record(
MI_INFO *info, my_off_t filepos, uchar *buf)
1591 DBUG_ENTER(
"mi_read_mempack_record");
1593 if (filepos == HA_OFFSET_ERROR)
1596 if (!(pos= (uchar*) _mi_mempack_get_block_info(info, &info->bit_buff,
1597 &block_info, &info->rec_buff,
1598 (uchar*) share->file_map+
1601 DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
1602 pos, block_info.rec_len));
1607 static int _mi_read_rnd_mempack_record(
MI_INFO *info, uchar *buf,
1608 register my_off_t filepos,
1609 my_bool skip_deleted_blocks
1610 __attribute__((unused)))
1615 DBUG_ENTER(
"_mi_read_rnd_mempack_record");
1617 if (filepos >= share->state.state.data_file_length)
1619 my_errno=HA_ERR_END_OF_FILE;
1622 if (!(pos= (uchar*) _mi_mempack_get_block_info(info, &info->bit_buff,
1623 &block_info, &info->rec_buff,
1625 (start=share->file_map+
1629 if (block_info.rec_len > info->s->max_pack_length)
1631 my_errno=HA_ERR_WRONG_IN_RECORD;
1635 info->packed_length=block_info.rec_len;
1636 info->lastpos=filepos;
1637 info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len;
1638 info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
1640 DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
1641 pos, block_info.rec_len));
1643 DBUG_RETURN(my_errno);
1650 uint save_pack_length(uint version, uchar *block_buff, ulong length)
1654 *(uchar*) block_buff= (uchar) length;
1657 if (length <= 65535)
1659 *(uchar*) block_buff=254;
1660 int2store(block_buff+1,(uint) length);
1663 *(uchar*) block_buff=255;
1666 DBUG_ASSERT(length <= 0xFFFFFF);
1667 int3store(block_buff + 1, (ulong) length);
1672 int4store(block_buff + 1, (ulong) length);
1678 uint read_pack_length(uint version,
const uchar *buf, ulong *length)
1685 else if (buf[0] == 254)
1687 *length= uint2korr(buf + 1);
1692 *length= uint3korr(buf + 1);
1697 *length= uint4korr(buf + 1);
1703 uint calc_pack_length(uint version, ulong length)
1705 return (length < 254) ? 1 : (length < 65536) ? 3 : (version == 1) ? 4 : 5;