home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / isam / _packrec.c < prev    next >
C/C++ Source or Header  |  2000-08-31  |  33KB  |  1,185 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.     /* Functions to compressed records */
  18.  
  19. #include "isamdef.h"
  20.  
  21. #define IS_CHAR ((uint) 32768)        /* Bit if char (not offset) in tree */
  22.  
  23. #if INT_MAX > 65536L
  24. #define BITS_SAVED 32
  25. #define MAX_QUICK_TABLE_BITS 9        /* Because we may shift in 24 bits */
  26. #else
  27. #define BITS_SAVED 16
  28. #define MAX_QUICK_TABLE_BITS 6
  29. #endif
  30.  
  31. #define get_bit(BU) ((BU)->bits ? \
  32.              (BU)->current_byte & ((bit_type) 1 << --(BU)->bits) :\
  33.              (fill_buffer(BU), (BU)->bits= BITS_SAVED-1,\
  34.               (BU)->current_byte & ((bit_type) 1 << (BITS_SAVED-1))))
  35. #define skipp_to_next_byte(BU) ((BU)->bits&=~7)
  36. #define get_bits(BU,count) (((BU)->bits >= count) ? (((BU)->current_byte >> ((BU)->bits-=count)) & mask[count]) : fill_and_get_bits(BU,count))
  37.  
  38. #define decode_bytes_test_bit(bit) \
  39.   if (low_byte & (1 << (7-bit))) \
  40.     pos++; \
  41.   if (*pos & IS_CHAR) \
  42.   { bits-=(bit+1); break; } \
  43.   pos+= *pos
  44.  
  45.  
  46.   static void read_huff_table(BIT_BUFF *bit_buff,DECODE_TREE *decode_tree,
  47.                   uint16 **decode_table,byte **intervall_buff,
  48.                   uint16 *tmp_buff);
  49. static void make_quick_table(uint16 *to_table,uint16 *decode_table,
  50.                  uint *next_free,uint value,uint bits,
  51.                  uint max_bits);
  52. static void fill_quick_table(uint16 *table,uint bits, uint max_bits,
  53.                  uint value);
  54. static uint copy_decode_table(uint16 *to_pos,uint offset,
  55.                   uint16 *decode_table);
  56. static uint find_longest_bitstream(uint16 *table);
  57. static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *field,
  58.                            BIT_BUFF *buff,
  59.                            uchar *to,
  60.                            uchar *end);
  61. static void uf_zerofill_skipp_zero(N_RECINFO *rec,BIT_BUFF *bit_buff,
  62.                    uchar *to,uchar *end);
  63. static void uf_skipp_zero(N_RECINFO *rec,BIT_BUFF *bit_buff,
  64.               uchar *to,uchar *end);
  65. static void uf_space_normal(N_RECINFO *rec,BIT_BUFF *bit_buff,
  66.                 uchar *to,uchar *end);
  67. static void uf_space_endspace_selected(N_RECINFO *rec,BIT_BUFF *bit_buff,
  68.                        uchar *to, uchar *end);
  69. static void uf_endspace_selected(N_RECINFO *rec,BIT_BUFF *bit_buff,
  70.                  uchar *to,uchar *end);
  71. static void uf_space_endspace(N_RECINFO *rec,BIT_BUFF *bit_buff,
  72.                   uchar *to,uchar *end);
  73. static void uf_endspace(N_RECINFO *rec,BIT_BUFF *bit_buff,
  74.             uchar *to,uchar *end);
  75. static void uf_space_prespace_selected(N_RECINFO *rec,BIT_BUFF *bit_buff,
  76.                        uchar *to, uchar *end);
  77. static void uf_prespace_selected(N_RECINFO *rec,BIT_BUFF *bit_buff,
  78.                  uchar *to,uchar *end);
  79. static void uf_space_prespace(N_RECINFO *rec,BIT_BUFF *bit_buff,
  80.                   uchar *to,uchar *end);
  81. static void uf_prespace(N_RECINFO *rec,BIT_BUFF *bit_buff,
  82.             uchar *to,uchar *end);
  83. static void uf_zerofill_normal(N_RECINFO *rec,BIT_BUFF *bit_buff,
  84.                    uchar *to,uchar *end);
  85. static void uf_constant(N_RECINFO *rec,BIT_BUFF *bit_buff,
  86.             uchar *to,uchar *end);
  87. static void uf_intervall(N_RECINFO *rec,BIT_BUFF *bit_buff,
  88.              uchar *to,uchar *end);
  89. static void uf_zero(N_RECINFO *rec,BIT_BUFF *bit_buff,
  90.             uchar *to,uchar *end);
  91. static void decode_bytes(N_RECINFO *rec,BIT_BUFF *bit_buff,
  92.              uchar *to,uchar *end);
  93. static uint decode_pos(BIT_BUFF *bit_buff,DECODE_TREE *decode_tree);
  94. static void init_bit_buffer(BIT_BUFF *bit_buff,char *buffer,uint length);
  95. static uint fill_and_get_bits(BIT_BUFF *bit_buff,uint count);
  96. static void fill_buffer(BIT_BUFF *bit_buff);
  97. static uint max_bit(uint value);
  98. #ifdef HAVE_MMAP
  99. static void _nisam_mempack_get_block_info(BLOCK_INFO *info,uint ref_length,
  100.                        uchar *header);
  101. #endif
  102.  
  103. static uint mask[]=
  104. {
  105.    0x00000000,
  106.    0x00000001, 0x00000003, 0x00000007, 0x0000000f,
  107.    0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
  108.    0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
  109.    0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
  110. #if BITS_SAVED > 16
  111.    0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
  112.    0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
  113.    0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
  114.    0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
  115. #endif
  116.  };
  117.  
  118.  
  119.     /* Read all packed info, allocate memory and fix field structs */
  120.  
  121. my_bool _nisam_read_pack_info(N_INFO *info, pbool fix_keys)
  122. {
  123.   File file;
  124.   int diff_length;
  125.   uint i,trees,huff_tree_bits,rec_reflength,length;
  126.   uint16 *decode_table,*tmp_buff;
  127.   ulong elements,intervall_length;
  128.   char *disk_cache,*intervall_buff;
  129.   uchar header[32];
  130.   ISAM_SHARE *share=info->s;
  131.   BIT_BUFF bit_buff;
  132.   DBUG_ENTER("_nisam_read_pack_info");
  133.  
  134.   if (nisam_quick_table_bits < 4)
  135.     nisam_quick_table_bits=4;
  136.   else if (nisam_quick_table_bits > MAX_QUICK_TABLE_BITS)
  137.     nisam_quick_table_bits=MAX_QUICK_TABLE_BITS;
  138.  
  139.   file=info->dfile;
  140.   my_errno=0;
  141.   if (my_read(file,(byte*) header,sizeof(header),MYF(MY_NABP)))
  142.   {
  143.     if (!my_errno)
  144.       my_errno=HA_ERR_END_OF_FILE;
  145.     DBUG_RETURN(1);
  146.   }
  147.   if (memcmp((byte*) header,(byte*) nisam_pack_file_magic,4))
  148.   {
  149.     my_errno=HA_ERR_WRONG_IN_RECORD;
  150.     DBUG_RETURN(1);
  151.   }
  152.   share->pack.header_length=uint4korr(header+4);
  153.   share->min_pack_length=(uint) uint4korr(header+8);
  154.   share->max_pack_length=(uint) uint4korr(header+12);
  155.   set_if_bigger(share->base.pack_reclength,share->max_pack_length);
  156.   elements=uint4korr(header+16);
  157.   intervall_length=uint4korr(header+20);
  158.   trees=uint2korr(header+24);
  159.   share->pack.ref_length=header[26];
  160.   rec_reflength=header[27];
  161.   diff_length=(int) rec_reflength - (int) share->base.rec_reflength;
  162.   if (fix_keys)
  163.     share->rec_reflength=rec_reflength;
  164.   share->base.min_block_length=share->min_pack_length+share->pack.ref_length;
  165.  
  166.   if (!(share->decode_trees=(DECODE_TREE*)
  167.     my_malloc((uint) (trees*sizeof(DECODE_TREE)+
  168.               intervall_length*sizeof(byte)),
  169.           MYF(MY_WME))))
  170.     DBUG_RETURN(1);
  171.   intervall_buff=(byte*) (share->decode_trees+trees);
  172.  
  173.   length=(uint) (elements*2+trees*(1 << nisam_quick_table_bits));
  174.   if (!(share->decode_tables=(uint16*)
  175.     my_malloc((length+512)*sizeof(uint16)+
  176.           (uint) (share->pack.header_length+7),
  177.           MYF(MY_WME | MY_ZEROFILL))))
  178.   {
  179.     my_free((gptr) share->decode_trees,MYF(0));
  180.     DBUG_RETURN(1);
  181.   }
  182.   tmp_buff=share->decode_tables+length;
  183.   disk_cache=(byte*) (tmp_buff+512);
  184.  
  185.   if (my_read(file,disk_cache,
  186.           (uint) (share->pack.header_length-sizeof(header)),
  187.           MYF(MY_NABP)))
  188.   {
  189.     my_free((gptr) share->decode_trees,MYF(0));
  190.     my_free((gptr) share->decode_tables,MYF(0));
  191.     DBUG_RETURN(1);
  192.   }
  193.  
  194.   huff_tree_bits=max_bit(trees ? trees-1 : 0);
  195.   init_bit_buffer(&bit_buff,disk_cache,
  196.           (uint) (share->pack.header_length-sizeof(header)));
  197.     /* Read new info for each field */
  198.   for (i=0 ; i < share->base.fields ; i++)
  199.   {
  200.     share->rec[i].base_type=(enum en_fieldtype) get_bits(&bit_buff,4);
  201.     share->rec[i].pack_type=(uint) get_bits(&bit_buff,4);
  202.     share->rec[i].space_length_bits=get_bits(&bit_buff,4);
  203.     share->rec[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
  204.                                 huff_tree_bits);
  205.     share->rec[i].unpack=get_unpack_function(share->rec+i);
  206.   }
  207.   skipp_to_next_byte(&bit_buff);
  208.   decode_table=share->decode_tables;
  209.   for (i=0 ; i < trees ; i++)
  210.     read_huff_table(&bit_buff,share->decode_trees+i,&decode_table,
  211.             &intervall_buff,tmp_buff);
  212.   decode_table=(uint16*)
  213.     my_realloc((gptr) share->decode_tables,
  214.            (uint) ((byte*) decode_table - (byte*) share->decode_tables),
  215.            MYF(MY_HOLD_ON_ERROR));
  216.   {
  217.     my_ptrdiff_t diff=PTR_BYTE_DIFF(decode_table,share->decode_tables);
  218.     share->decode_tables=decode_table;
  219.     for (i=0 ; i < trees ; i++)
  220.       share->decode_trees[i].table=ADD_TO_PTR(share->decode_trees[i].table,
  221.                           diff, uint16*);
  222.   }
  223.  
  224.     /* Fix record-ref-length for keys */
  225.   if (fix_keys)
  226.   {
  227.     for (i=0 ; i < share->base.keys ; i++)
  228.     {
  229.       share->keyinfo[i].base.keylength+=(uint16) diff_length;
  230.       share->keyinfo[i].base.minlength+=(uint16) diff_length;
  231.       share->keyinfo[i].base.maxlength+=(uint16) diff_length;
  232.       share->keyinfo[i].seg[share->keyinfo[i].base.keysegs].base.length=
  233.     (uint16) rec_reflength;
  234.     }
  235.   }
  236.  
  237.   if (bit_buff.error || bit_buff.pos < bit_buff.end)
  238.   {                    /* info_length was wrong */
  239.     my_errno=HA_ERR_WRONG_IN_RECORD;
  240.     my_free((gptr) share->decode_trees,MYF(0));
  241.     my_free((gptr) share->decode_tables,MYF(0));
  242.     DBUG_RETURN(1);
  243.   }
  244.   DBUG_RETURN(0);
  245. }
  246.  
  247.  
  248.     /* Read on huff-code-table from datafile */
  249.  
  250. static void read_huff_table(BIT_BUFF *bit_buff, DECODE_TREE *decode_tree,
  251.                 uint16 **decode_table, byte **intervall_buff,
  252.                 uint16 *tmp_buff)
  253. {
  254.   uint min_chr,elements,char_bits,offset_bits,size,intervall_length,table_bits,
  255.   next_free_offset;
  256.   uint16 *ptr,*end;
  257.  
  258.   LINT_INIT(ptr);
  259.   if (!get_bits(bit_buff,1))
  260.   {
  261.     min_chr=get_bits(bit_buff,8);
  262.     elements=get_bits(bit_buff,9);
  263.     char_bits=get_bits(bit_buff,5);
  264.     offset_bits=get_bits(bit_buff,5);
  265.     intervall_length=0;
  266.     ptr=tmp_buff;
  267.   }
  268.   else
  269.   {
  270.     min_chr=0;
  271.     elements=get_bits(bit_buff,15);
  272.     intervall_length=get_bits(bit_buff,16);
  273.     char_bits=get_bits(bit_buff,5);
  274.     offset_bits=get_bits(bit_buff,5);
  275.     decode_tree->quick_table_bits=0;
  276.     ptr= *decode_table;
  277.   }
  278.   size=elements*2-2;
  279.  
  280.   for (end=ptr+size ; ptr < end ; ptr++)
  281.   {
  282.     if (get_bit(bit_buff))
  283.       *ptr= (uint16) get_bits(bit_buff,offset_bits);
  284.     else
  285.       *ptr= (uint16) (IS_CHAR + (get_bits(bit_buff,char_bits) + min_chr));
  286.   }
  287.   skipp_to_next_byte(bit_buff);
  288.  
  289.   decode_tree->table= *decode_table;
  290.   decode_tree->intervalls= *intervall_buff;
  291.   if (! intervall_length)
  292.   {
  293.     table_bits=find_longest_bitstream(tmp_buff);
  294.     if (table_bits > nisam_quick_table_bits)
  295.       table_bits=nisam_quick_table_bits;
  296.     next_free_offset= (1 << table_bits);
  297.     make_quick_table(*decode_table,tmp_buff,&next_free_offset,0,table_bits,
  298.              table_bits);
  299.     (*decode_table)+= next_free_offset;
  300.     decode_tree->quick_table_bits=table_bits;
  301.   }
  302.   else
  303.   {
  304.     (*decode_table)=end;
  305.     bit_buff->pos-= bit_buff->bits/8;
  306.     memcpy(*intervall_buff,bit_buff->pos,(size_t) intervall_length);
  307.     (*intervall_buff)+=intervall_length;
  308.     bit_buff->pos+=intervall_length;
  309.     bit_buff->bits=0;
  310.   }
  311.   return;
  312. }
  313.  
  314.  
  315. static void make_quick_table(uint16 *to_table, uint16 *decode_table, uint *next_free_offset, uint value, uint bits, uint max_bits)
  316. {
  317.   if (!bits--)
  318.   {
  319.     to_table[value]= (uint16) *next_free_offset;
  320.     *next_free_offset=copy_decode_table(to_table, *next_free_offset,
  321.                     decode_table);
  322.     return;
  323.   }
  324.   if (!(*decode_table & IS_CHAR))
  325.   {
  326.     make_quick_table(to_table,decode_table+ *decode_table,
  327.              next_free_offset,value,bits,max_bits);
  328.   }
  329.   else
  330.     fill_quick_table(to_table+value,bits,max_bits,(uint) *decode_table);
  331.   decode_table++;
  332.   value|= (1 << bits);
  333.   if (!(*decode_table & IS_CHAR))
  334.   {
  335.     make_quick_table(to_table,decode_table+ *decode_table,
  336.              next_free_offset,value,bits,max_bits);
  337.   }
  338.   else
  339.     fill_quick_table(to_table+value,bits,max_bits,(uint) *decode_table);
  340.   return;
  341. }
  342.  
  343.  
  344. static void fill_quick_table(uint16 *table, uint bits, uint max_bits, uint value)
  345. {
  346.   uint16 *end;
  347.   value|=(max_bits-bits) << 8;
  348.   for (end=table+ (1 << bits) ;
  349.        table < end ;
  350.        *table++ = (uint16) value | IS_CHAR) ;
  351. }
  352.  
  353.  
  354. static uint copy_decode_table(uint16 *to_pos, uint offset, uint16 *decode_table)
  355. {
  356.   uint prev_offset;
  357.   prev_offset= offset;
  358.  
  359.   if (!(*decode_table & IS_CHAR))
  360.   {
  361.     to_pos[offset]=2;
  362.     offset=copy_decode_table(to_pos,offset+2,decode_table+ *decode_table);
  363.   }
  364.   else
  365.   {
  366.     to_pos[offset]= *decode_table;
  367.     offset+=2;
  368.   }
  369.   decode_table++;
  370.  
  371.   if (!(*decode_table & IS_CHAR))
  372.   {
  373.     to_pos[prev_offset+1]=(uint16) (offset-prev_offset-1);
  374.     offset=copy_decode_table(to_pos,offset,decode_table+ *decode_table);
  375.   }
  376.   else
  377.     to_pos[prev_offset+1]= *decode_table;
  378.   return offset;
  379. }
  380.  
  381.  
  382. static uint find_longest_bitstream(uint16 *table)
  383. {
  384.   uint length=1,length2;
  385.   if (!(*table & IS_CHAR))
  386.     length=find_longest_bitstream(table+ *table)+1;
  387.   table++;
  388.   if (!(*table & IS_CHAR))
  389.   {
  390.     length2=find_longest_bitstream(table+ *table)+1;
  391.     length=max(length,length2);
  392.   }
  393.   return length;
  394. }
  395.  
  396.  
  397.     /* Read record from datafile */
  398.     /* Returns length of packed record, -1 if error */
  399.  
  400. int _nisam_read_pack_record(N_INFO *info, ulong filepos, byte *buf)
  401. {
  402.   BLOCK_INFO block_info;
  403.   File file;
  404.   DBUG_ENTER("_nisam_read_pack_record");
  405.  
  406.   if (filepos == NI_POS_ERROR)
  407.     DBUG_RETURN(-1);            /* _search() didn't find record */
  408.  
  409.   file=info->dfile;
  410.   if (_nisam_pack_get_block_info(&block_info,info->s->pack.ref_length,file,
  411.                   filepos))
  412.     goto err;
  413.   if (my_read(file,(byte*) info->rec_buff,block_info.rec_len,MYF(MY_NABP)))
  414.     goto panic;
  415.   info->update|= HA_STATE_AKTIV;
  416.   DBUG_RETURN(_nisam_pack_rec_unpack(info,buf,info->rec_buff,
  417.                      block_info.rec_len));
  418. panic:
  419.   my_errno=HA_ERR_WRONG_IN_RECORD;
  420. err:
  421.   DBUG_RETURN(-1);
  422. }
  423.  
  424.  
  425.  
  426. int _nisam_pack_rec_unpack(register N_INFO *info, register byte *to,
  427.                byte *from, uint reclength)
  428. {
  429.   byte *end_field;
  430.   reg3 N_RECINFO *end;
  431.   N_RECINFO *current_field;
  432.   ISAM_SHARE *share=info->s;
  433.   DBUG_ENTER("_nisam_pack_rec_unpack");
  434.  
  435.   init_bit_buffer(&info->bit_buff,from,reclength);
  436.  
  437.   for (current_field=share->rec, end=current_field+share->base.fields ;
  438.        current_field < end ;
  439.        current_field++,to=end_field)
  440.   {
  441.     end_field=to+current_field->base.length;
  442.     (*current_field->unpack)(current_field,&info->bit_buff,(uchar*) to,
  443.                  (uchar*) end_field);
  444.   }
  445.   if (! info->bit_buff.error &&
  446.       info->bit_buff.pos - info->bit_buff.bits/8 == info->bit_buff.end)
  447.     DBUG_RETURN(0);
  448.   my_errno=HA_ERR_WRONG_IN_RECORD;
  449.   info->update&= ~HA_STATE_AKTIV;
  450.   DBUG_RETURN(-1);
  451. } /* _nisam_pack_rec_unpack */
  452.  
  453.  
  454.     /* Return function to unpack field */
  455.  
  456. static void (*get_unpack_function(N_RECINFO *rec))(N_RECINFO *, BIT_BUFF *, uchar *, uchar *)
  457. {
  458.   switch (rec->base_type) {
  459.   case FIELD_SKIPP_ZERO:
  460.     if (rec->pack_type & PACK_TYPE_ZERO_FILL)
  461.       return &uf_zerofill_skipp_zero;
  462.     return &uf_skipp_zero;
  463.   case FIELD_NORMAL:
  464.     if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
  465.       return &uf_space_normal;
  466.     if (rec->pack_type & PACK_TYPE_ZERO_FILL)
  467.       return &uf_zerofill_normal;
  468.     return &decode_bytes;
  469.   case FIELD_SKIPP_ENDSPACE:
  470.     if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
  471.     {
  472.       if (rec->pack_type & PACK_TYPE_SELECTED)
  473.     return &uf_space_endspace_selected;
  474.       return &uf_space_endspace;
  475.     }
  476.     if (rec->pack_type & PACK_TYPE_SELECTED)
  477.       return &uf_endspace_selected;
  478.     return &uf_endspace;
  479.   case FIELD_SKIPP_PRESPACE:
  480.     if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
  481.     {
  482.       if (rec->pack_type & PACK_TYPE_SELECTED)
  483.     return &uf_space_prespace_selected;
  484.       return &uf_space_prespace;
  485.     }
  486.     if (rec->pack_type & PACK_TYPE_SELECTED)
  487.       return &uf_prespace_selected;
  488.     return &uf_prespace;
  489.   case FIELD_CONSTANT:
  490.     return &uf_constant;
  491.   case FIELD_INTERVALL:
  492.     return &uf_intervall;
  493.   case FIELD_ZERO:
  494.     return &uf_zero;
  495.   case FIELD_BLOB:        /* Write this sometimes.. */
  496.   case FIELD_LAST:
  497.   default:
  498.     return 0;            /* This should never happend */
  499.   }
  500. }
  501.  
  502.     /* De different functions to unpack a field */
  503.  
  504. static void uf_zerofill_skipp_zero(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  505. {
  506.   if (get_bit(bit_buff))
  507.     bzero((char*) to,(uint) (end-to));
  508.   else
  509.   {
  510. #ifdef WORDS_BIGENDIAN
  511.     bzero((char*) to,rec->space_length_bits);
  512.     decode_bytes(rec,bit_buff,to+rec->space_length_bits,end);
  513. #else
  514.     end-=rec->space_length_bits;
  515.     decode_bytes(rec,bit_buff,to,end);
  516.     bzero((byte*) end,rec->space_length_bits);
  517. #endif
  518.   }
  519. }
  520.  
  521. static void uf_skipp_zero(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  522. {
  523.   if (get_bit(bit_buff))
  524.     bzero((char*) to,(uint) (end-to));
  525.   else
  526.     decode_bytes(rec,bit_buff,to,end);
  527. }
  528.  
  529. static void uf_space_normal(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  530. {
  531.   if (get_bit(bit_buff))
  532.     bfill((byte*) to,(end-to),' ');
  533.   else
  534.     decode_bytes(rec,bit_buff,to,end);
  535. }
  536.  
  537. static void uf_space_endspace_selected(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  538. {
  539.   uint spaces;
  540.   if (get_bit(bit_buff))
  541.     bfill((byte*) to,(end-to),' ');
  542.   else
  543.   {
  544.     if (get_bit(bit_buff))
  545.     {
  546.       if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  547.       {
  548.     bit_buff->error=1;
  549.     return;
  550.       }
  551.       if (to+spaces != end)
  552.     decode_bytes(rec,bit_buff,to,end-spaces);
  553.       bfill((byte*) end-spaces,spaces,' ');
  554.     }
  555.     else
  556.       decode_bytes(rec,bit_buff,to,end);
  557.   }
  558. }
  559.  
  560. static void uf_endspace_selected(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  561. {
  562.   uint spaces;
  563.   if (get_bit(bit_buff))
  564.   {
  565.     if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  566.     {
  567.       bit_buff->error=1;
  568.       return;
  569.     }
  570.     if (to+spaces != end)
  571.       decode_bytes(rec,bit_buff,to,end-spaces);
  572.     bfill((byte*) end-spaces,spaces,' ');
  573.   }
  574.   else
  575.     decode_bytes(rec,bit_buff,to,end);
  576. }
  577.  
  578. static void uf_space_endspace(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  579. {
  580.   uint spaces;
  581.   if (get_bit(bit_buff))
  582.     bfill((byte*) to,(end-to),' ');
  583.   else
  584.   {
  585.     if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  586.     {
  587.       bit_buff->error=1;
  588.       return;
  589.     }
  590.     if (to+spaces != end)
  591.       decode_bytes(rec,bit_buff,to,end-spaces);
  592.     bfill((byte*) end-spaces,spaces,' ');
  593.   }
  594. }
  595.  
  596. static void uf_endspace(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to,
  597.             uchar *end)
  598. {
  599.   uint spaces;
  600.   if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  601.   {
  602.     bit_buff->error=1;
  603.     return;
  604.   }
  605.   if (to+spaces != end)
  606.     decode_bytes(rec,bit_buff,to,end-spaces);
  607.   bfill((byte*) end-spaces,spaces,' ');
  608. }
  609.  
  610. static void uf_space_prespace_selected(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  611. {
  612.   uint spaces;
  613.   if (get_bit(bit_buff))
  614.     bfill((byte*) to,(end-to),' ');
  615.   else
  616.   {
  617.     if (get_bit(bit_buff))
  618.     {
  619.       if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  620.       {
  621.     bit_buff->error=1;
  622.     return;
  623.       }
  624.       bfill((byte*) to,spaces,' ');
  625.       if (to+spaces != end)
  626.     decode_bytes(rec,bit_buff,to+spaces,end);
  627.     }
  628.     else
  629.       decode_bytes(rec,bit_buff,to,end);
  630.   }
  631. }
  632.  
  633.  
  634. static void uf_prespace_selected(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  635. {
  636.   uint spaces;
  637.   if (get_bit(bit_buff))
  638.   {
  639.     if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  640.     {
  641.       bit_buff->error=1;
  642.       return;
  643.     }
  644.     bfill((byte*) to,spaces,' ');
  645.     if (to+spaces != end)
  646.       decode_bytes(rec,bit_buff,to+spaces,end);
  647.   }
  648.   else
  649.     decode_bytes(rec,bit_buff,to,end);
  650. }
  651.  
  652.  
  653. static void uf_space_prespace(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  654. {
  655.   uint spaces;
  656.   if (get_bit(bit_buff))
  657.     bfill((byte*) to,(end-to),' ');
  658.   else
  659.   {
  660.     if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  661.     {
  662.       bit_buff->error=1;
  663.       return;
  664.     }
  665.     bfill((byte*) to,spaces,' ');
  666.     if (to+spaces != end)
  667.       decode_bytes(rec,bit_buff,to+spaces,end);
  668.   }
  669. }
  670.  
  671. static void uf_prespace(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  672. {
  673.   uint spaces;
  674.   if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
  675.   {
  676.     bit_buff->error=1;
  677.     return;
  678.   }
  679.   bfill((byte*) to,spaces,' ');
  680.   if (to+spaces != end)
  681.     decode_bytes(rec,bit_buff,to+spaces,end);
  682. }
  683.  
  684. static void uf_zerofill_normal(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  685. {
  686. #ifdef WORDS_BIGENDIAN
  687.   bzero((char*) to,rec->space_length_bits);
  688.   decode_bytes(rec,bit_buff,(uchar*) to+rec->space_length_bits,end);
  689. #else
  690.   end-=rec->space_length_bits;
  691.   decode_bytes(rec,bit_buff,(uchar*) to,end);
  692.   bzero((byte*) end,rec->space_length_bits);
  693. #endif
  694. }
  695.  
  696. static void uf_constant(N_RECINFO *rec,
  697.             BIT_BUFF *bit_buff __attribute__((unused)),
  698.             uchar *to, uchar *end)
  699. {
  700.   memcpy(to,rec->huff_tree->intervalls,(size_t) (end-to));
  701. }
  702.  
  703. static void uf_intervall(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  704. {
  705.   reg1 uint field_length=(uint) (end-to);
  706.   memcpy(to,rec->huff_tree->intervalls+field_length*decode_pos(bit_buff,
  707.                                    rec->huff_tree),
  708.      (size_t) field_length);
  709. }
  710.  
  711.  
  712. /*ARGSUSED*/
  713. static void uf_zero(N_RECINFO *rec __attribute__((unused)),
  714.             BIT_BUFF *bit_buff  __attribute__((unused)),
  715.             uchar *to, uchar *end)
  716. {
  717.   bzero((char*) to,(uint) (end-to));
  718. }
  719.  
  720.  
  721.     /* Functions to decode of buffer of bits */
  722.  
  723. #if BITS_SAVED == 64
  724.  
  725. static void decode_bytes(rec,bit_buff,to,end)
  726. N_RECINFO *rec;
  727. BIT_BUFF *bit_buff;
  728. uchar *to,*end;
  729. {
  730.   reg1 uint bits,low_byte;
  731.   reg3 uint16 *pos;
  732.   reg4 uint table_bits,table_and;
  733.   DECODE_TREE *decode_tree;
  734.  
  735.   decode_tree=rec->decode_tree;
  736.   bits=bit_buff->bits;            /* Save in reg for quicker access */
  737.   table_bits=decode_tree->quick_table_bits;
  738.   table_and= (1 << table_bits)-1;
  739.  
  740.   do
  741.   {
  742.     if (bits <= 32)
  743.     {
  744.       if (bit_buff->pos > bit_buff->end+4)
  745.     return;                /* Can't be right */
  746.       bit_buff->current_byte= (bit_buff->current_byte << 32) +
  747.     ((((uint) bit_buff->pos[3])) +
  748.      (((uint) bit_buff->pos[2]) << 8) +
  749.      (((uint) bit_buff->pos[1]) << 16) +
  750.      (((uint) bit_buff->pos[0]) << 24));
  751.       bit_buff->pos+=4;
  752.       bits+=32;
  753.     }
  754.     /* First use info in quick_table */
  755.     low_byte=(uint) (bit_buff->current_byte >> (bits - table_bits)) & table_and;
  756.     low_byte=decode_tree->table[low_byte];
  757.     if (low_byte & IS_CHAR)
  758.     {
  759.       *to++ = (low_byte & 255);        /* Found char in quick table */
  760.       bits-=  ((low_byte >> 8) & 31);    /* Remove bits used */
  761.     }
  762.     else
  763.     {                    /* Map through rest of decode-table */
  764.       pos=decode_tree->table+low_byte;
  765.       bits-=table_bits;
  766.       for (;;)
  767.       {
  768.     low_byte=(uint) (bit_buff->current_byte >> (bits-8));
  769.     decode_bytes_test_bit(0);
  770.     decode_bytes_test_bit(1);
  771.     decode_bytes_test_bit(2);
  772.     decode_bytes_test_bit(3);
  773.     decode_bytes_test_bit(4);
  774.     decode_bytes_test_bit(5);
  775.     decode_bytes_test_bit(6);
  776.     decode_bytes_test_bit(7);
  777.     bits-=8;
  778.       }
  779.       *to++ = *pos;
  780.     }
  781.   } while (to != end);
  782.  
  783.   bit_buff->bits=bits;
  784.   return;
  785. }
  786.  
  787. #else
  788.  
  789. static void decode_bytes(N_RECINFO *rec, BIT_BUFF *bit_buff, uchar *to, uchar *end)
  790. {
  791.   reg1 uint bits,low_byte;
  792.   reg3 uint16 *pos;
  793.   reg4 uint table_bits,table_and;
  794.   DECODE_TREE *decode_tree;
  795.  
  796.   decode_tree=rec->huff_tree;
  797.   bits=bit_buff->bits;            /* Save in reg for quicker access */
  798.   table_bits=decode_tree->quick_table_bits;
  799.   table_and= (1 << table_bits)-1;
  800.  
  801.   do
  802.   {
  803.     if (bits < table_bits)
  804.     {
  805.       if (bit_buff->pos > bit_buff->end+1)
  806.     return;                /* Can't be right */
  807. #if BITS_SAVED == 32
  808.       bit_buff->current_byte= (bit_buff->current_byte << 24) +
  809.     (((uint) ((uchar) bit_buff->pos[2]))) +
  810.       (((uint) ((uchar) bit_buff->pos[1])) << 8) +
  811.         (((uint) ((uchar) bit_buff->pos[0])) << 16);
  812.       bit_buff->pos+=3;
  813.       bits+=24;
  814. #else
  815.       if (bits)                /* We must have at leasts 9 bits */
  816.       {
  817.     bit_buff->current_byte=  (bit_buff->current_byte << 8) +
  818.       (uint) ((uchar) bit_buff->pos[0]);
  819.     bit_buff->pos++;
  820.     bits+=8;
  821.       }
  822.       else
  823.       {
  824.     bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) +
  825.       ((uint) ((uchar) bit_buff->pos[1]));
  826.     bit_buff->pos+=2;
  827.     bits+=16;
  828.       }
  829. #endif
  830.     }
  831.     /* First use info in quick_table */
  832.     low_byte=(bit_buff->current_byte >> (bits - table_bits)) & table_and;
  833.     low_byte=decode_tree->table[low_byte];
  834.     if (low_byte & IS_CHAR)
  835.     {
  836.       *to++ = (low_byte & 255);        /* Found char in quick table */
  837.       bits-=  ((low_byte >> 8) & 31);    /* Remove bits used */
  838.     }
  839.     else
  840.     {                    /* Map through rest of decode-table */
  841.       pos=decode_tree->table+low_byte;
  842.       bits-=table_bits;
  843.       for (;;)
  844.       {
  845.     if (bits < 8)
  846.     {                /* We don't need to check end */
  847. #if BITS_SAVED == 32
  848.       bit_buff->current_byte= (bit_buff->current_byte << 24) +
  849.         (((uint) ((uchar) bit_buff->pos[2]))) +
  850.           (((uint) ((uchar) bit_buff->pos[1])) << 8) +
  851.         (((uint) ((uchar) bit_buff->pos[0])) << 16);
  852.       bit_buff->pos+=3;
  853.       bits+=24;
  854. #else
  855.       bit_buff->current_byte=  (bit_buff->current_byte << 8) +
  856.         (uint) ((uchar) bit_buff->pos[0]);
  857.       bit_buff->pos+=1;
  858.       bits+=8;
  859. #endif
  860.     }
  861.     low_byte=(uint) (bit_buff->current_byte >> (bits-8));
  862.     decode_bytes_test_bit(0);
  863.     decode_bytes_test_bit(1);
  864.     decode_bytes_test_bit(2);
  865.     decode_bytes_test_bit(3);
  866.     decode_bytes_test_bit(4);
  867.     decode_bytes_test_bit(5);
  868.     decode_bytes_test_bit(6);
  869.     decode_bytes_test_bit(7);
  870.     bits-=8;
  871.       }
  872.       *to++ = (uchar) *pos;
  873.     }
  874.   } while (to != end);
  875.  
  876.   bit_buff->bits=bits;
  877.   return;
  878. }
  879. #endif /* BIT_SAVED == 64 */
  880.  
  881.  
  882. static uint decode_pos(BIT_BUFF *bit_buff, DECODE_TREE *decode_tree)
  883. {
  884.   uint16 *pos=decode_tree->table;
  885.   for (;;)
  886.   {
  887.     if (get_bit(bit_buff))
  888.       pos++;
  889.     if (*pos & IS_CHAR)
  890.       return (uint) (*pos & ~IS_CHAR);
  891.     pos+= *pos;
  892.   }
  893. }
  894.  
  895.  
  896. int _nisam_read_rnd_pack_record(N_INFO *info, byte *buf,
  897.                 register ulong filepos,
  898.                 int skipp_deleted_blocks)
  899. {
  900.   uint b_type;
  901.   BLOCK_INFO block_info;
  902.   ISAM_SHARE *share=info->s;
  903.   DBUG_ENTER("_nisam_read_rnd_pack_record");
  904.  
  905.   if (filepos >= share->state.data_file_length)
  906.   {
  907.     my_errno= HA_ERR_END_OF_FILE;
  908.     goto err;
  909.   }
  910.  
  911.   if (info->opt_flag & READ_CACHE_USED)
  912.   {
  913.     if (_nisam_read_cache(&info->rec_cache,(byte*) block_info.header,filepos,
  914.               share->pack.ref_length, skipp_deleted_blocks))
  915.       goto err;
  916.     b_type=_nisam_pack_get_block_info(&block_info,share->pack.ref_length,-1,
  917.                       filepos);
  918.   }
  919.   else
  920.     b_type=_nisam_pack_get_block_info(&block_info,share->pack.ref_length,
  921.                       info->dfile,filepos);
  922.   if (b_type)
  923.     goto err;
  924. #ifndef DBUG_OFF
  925.   if (block_info.rec_len > share->max_pack_length)
  926.   {
  927.     my_errno=HA_ERR_WRONG_IN_RECORD;
  928.     goto err;
  929.   }
  930. #endif
  931.   if (info->opt_flag & READ_CACHE_USED)
  932.   {
  933.     if (_nisam_read_cache(&info->rec_cache,(byte*) info->rec_buff,
  934.               block_info.filepos, block_info.rec_len,
  935.               skipp_deleted_blocks))
  936.       goto err;
  937.   }
  938.   else
  939.   {
  940.     if (my_read(info->dfile,(byte*) info->rec_buff,block_info.rec_len,
  941.         MYF(MY_NABP)))
  942.       goto err;
  943.   }
  944.   info->packed_length=block_info.rec_len;
  945.   info->lastpos=filepos;
  946.   info->nextpos=block_info.filepos+block_info.rec_len;
  947.   info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
  948.  
  949.   DBUG_RETURN (_nisam_pack_rec_unpack(info,buf,info->rec_buff,
  950.                       block_info.rec_len));
  951. err:
  952.   DBUG_RETURN(-1);
  953. }
  954.  
  955.  
  956.     /* Read and process header from a huff-record-file */
  957.  
  958. uint _nisam_pack_get_block_info(BLOCK_INFO *info, uint ref_length, File file,
  959.                 ulong filepos)
  960. {
  961.   uchar *header=info->header;
  962.  
  963.   if (file >= 0)
  964.   {
  965.     VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
  966.     if (my_read(file,(char*) header,ref_length,MYF(MY_NABP)))
  967.       return BLOCK_FATAL_ERROR;
  968.   }
  969.   DBUG_DUMP("header",(byte*) header,ref_length);
  970.  
  971.   switch (ref_length) {
  972.   case 1:
  973.     info->rec_len=header[0];
  974.     info->filepos=filepos+1;
  975.     break;
  976.   case 2:
  977.     info->rec_len=uint2korr(header);
  978.     info->filepos=filepos+2;
  979.     break;
  980.   case 3:
  981.     info->rec_len=(uint) (uint3korr(header));
  982.     info->filepos=filepos+3;
  983.     break;
  984.   default: break;
  985.   }
  986.   return 0;
  987. }
  988.  
  989.  
  990.     /* routines for bit buffer */
  991.     /* Buffer must be 6 byte bigger */
  992. static void init_bit_buffer(BIT_BUFF *bit_buff, char *buffer, uint length)
  993. {
  994.   bit_buff->pos=(uchar*) buffer;
  995.   bit_buff->end=(uchar*) buffer+length;
  996.   bit_buff->bits=bit_buff->error=0;
  997.   bit_buff->current_byte=0;            /* Avoid purify errors */
  998. }
  999.  
  1000. static uint fill_and_get_bits(BIT_BUFF *bit_buff, uint count)
  1001. {
  1002.   uint tmp;
  1003.   count-=bit_buff->bits;
  1004.   tmp=(bit_buff->current_byte & mask[bit_buff->bits]) << count;
  1005.   fill_buffer(bit_buff);
  1006.   bit_buff->bits=BITS_SAVED - count;
  1007.   return tmp+(bit_buff->current_byte >> (BITS_SAVED - count));
  1008. }
  1009.  
  1010.     /* Fill in empty bit_buff->current_byte from buffer */
  1011.     /* Sets bit_buff->error if buffer is exhausted */
  1012.  
  1013. static void fill_buffer(BIT_BUFF *bit_buff)
  1014. {
  1015.   if (bit_buff->pos >= bit_buff->end)
  1016.   {
  1017.     bit_buff->error= 1;
  1018.     bit_buff->current_byte=0;
  1019.     return;
  1020.   }
  1021. #if BITS_SAVED == 64
  1022.   bit_buff->current_byte=  ((((uint) ((uchar) bit_buff->pos[7]))) +
  1023.                  (((uint) ((uchar) bit_buff->pos[6])) << 8) +
  1024.                  (((uint) ((uchar) bit_buff->pos[5])) << 16) +
  1025.                  (((uint) ((uchar) bit_buff->pos[4])) << 24) +
  1026.                  ((ulonglong)
  1027.                   ((((uint) ((uchar) bit_buff->pos[3]))) +
  1028.                    (((uint) ((uchar) bit_buff->pos[2])) << 8) +
  1029.                    (((uint) ((uchar) bit_buff->pos[1])) << 16) +
  1030.                    (((uint) ((uchar) bit_buff->pos[0])) << 24)) << 32));
  1031.   bit_buff->pos+=8;
  1032. #else
  1033. #if BITS_SAVED == 32
  1034.   bit_buff->current_byte=  (((uint) ((uchar) bit_buff->pos[3])) +
  1035.                  (((uint) ((uchar) bit_buff->pos[2])) << 8) +
  1036.                  (((uint) ((uchar) bit_buff->pos[1])) << 16) +
  1037.                  (((uint) ((uchar) bit_buff->pos[0])) << 24));
  1038.   bit_buff->pos+=4;
  1039. #else
  1040.   bit_buff->current_byte=  (uint) (((uint) ((uchar) bit_buff->pos[1]))+
  1041.                     (((uint) ((uchar) bit_buff->pos[0])) << 8));
  1042.   bit_buff->pos+=2;
  1043. #endif
  1044. #endif
  1045. }
  1046.  
  1047.     /* Get number of bits neaded to represent value */
  1048.  
  1049. static uint max_bit(register uint value)
  1050. {
  1051.   reg2 uint power=1;
  1052.  
  1053.   while ((value>>=1))
  1054.     power++;
  1055.   return (power);
  1056. }
  1057.  
  1058.  
  1059. /*****************************************************************************
  1060.     Some redefined functions to handle files when we are using memmap
  1061. *****************************************************************************/
  1062.  
  1063. #ifdef HAVE_MMAP
  1064.  
  1065. #include <sys/mman.h>
  1066.  
  1067. static int _nisam_read_mempack_record(N_INFO *info,ulong filepos,byte *buf);
  1068. static int _nisam_read_rnd_mempack_record(N_INFO*, byte *,ulong, int);
  1069.  
  1070. #ifndef MAP_NORESERVE
  1071. #define MAP_NORESERVE 0        /* For irix */
  1072. #endif
  1073. #ifndef MAP_FAILED
  1074. #define MAP_FAILED -1
  1075. #endif
  1076.  
  1077. my_bool _nisam_memmap_file(N_INFO *info)
  1078. {
  1079.   byte *file_map;
  1080.   ISAM_SHARE *share=info->s;
  1081.   DBUG_ENTER("_nisam_memmap_file");
  1082.  
  1083.   if (!info->s->file_map)
  1084.   {
  1085.     if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
  1086.     share->state.data_file_length+MEMMAP_EXTRA_MARGIN)
  1087.     {
  1088.       DBUG_PRINT("warning",("File isn't extended for memmap"));
  1089.       DBUG_RETURN(0);
  1090.     }
  1091.     file_map=(byte*)
  1092.       mmap(0,share->state.data_file_length+MEMMAP_EXTRA_MARGIN,PROT_READ,
  1093.        MAP_SHARED | MAP_NORESERVE,info->dfile,0L);
  1094.     if (file_map == (byte*) MAP_FAILED)
  1095.     {
  1096.       DBUG_PRINT("warning",("mmap failed: errno: %d",errno));
  1097.       my_errno=errno;
  1098.       DBUG_RETURN(0);
  1099.     }
  1100.     info->s->file_map=file_map;
  1101.   }
  1102.   info->opt_flag|= MEMMAP_USED;
  1103.   info->read_record=share->read_record=_nisam_read_mempack_record;
  1104.   share->read_rnd=_nisam_read_rnd_mempack_record;
  1105.   DBUG_RETURN(1);
  1106. }
  1107.  
  1108.  
  1109. void _nisam_unmap_file(N_INFO *info)
  1110. {
  1111.   if (info->s->file_map)
  1112.     (void) munmap((caddr_t) info->s->file_map,
  1113.           (size_t) info->s->state.data_file_length+
  1114.           MEMMAP_EXTRA_MARGIN);
  1115. }
  1116.  
  1117.  
  1118. static void _nisam_mempack_get_block_info(BLOCK_INFO *info, uint ref_length,
  1119.                       uchar *header)
  1120. {
  1121.   if (ref_length == 1)                /* This is most usual */
  1122.     info->rec_len=header[0];
  1123.   else if (ref_length == 2)
  1124.     info->rec_len=uint2korr(header);
  1125.   else
  1126.     info->rec_len=(uint) (uint3korr(header));
  1127. }
  1128.  
  1129.  
  1130. static int _nisam_read_mempack_record(N_INFO *info, ulong filepos, byte *buf)
  1131. {
  1132.   BLOCK_INFO block_info;
  1133.   ISAM_SHARE *share=info->s;
  1134.   DBUG_ENTER("ni_read_mempack_record");
  1135.  
  1136.   if (filepos == NI_POS_ERROR)
  1137.     DBUG_RETURN(-1);            /* _search() didn't find record */
  1138.  
  1139.   _nisam_mempack_get_block_info(&block_info,share->pack.ref_length,
  1140.                 (uchar*) share->file_map+filepos);
  1141.   DBUG_RETURN(_nisam_pack_rec_unpack(info,buf,share->file_map+
  1142.                      share->pack.ref_length+filepos,
  1143.                      block_info.rec_len));
  1144. }
  1145.  
  1146.  
  1147. /*ARGSUSED*/
  1148. static int _nisam_read_rnd_mempack_record(N_INFO *info, byte *buf,
  1149.                       register ulong filepos,
  1150.                       int skipp_deleted_blocks
  1151.                       __attribute__((unused)))
  1152. {
  1153.   BLOCK_INFO block_info;
  1154.   ISAM_SHARE *share=info->s;
  1155.   DBUG_ENTER("_nisam_read_rnd_mempack_record");
  1156.  
  1157.   if (filepos >= share->state.data_file_length)
  1158.   {
  1159.     my_errno=HA_ERR_END_OF_FILE;
  1160.     goto err;
  1161.   }
  1162.  
  1163.   _nisam_mempack_get_block_info(&block_info,share->pack.ref_length,
  1164.                 (uchar*) share->file_map+filepos);
  1165. #ifndef DBUG_OFF
  1166.   if (block_info.rec_len > info->s->max_pack_length)
  1167.   {
  1168.     my_errno=HA_ERR_WRONG_IN_RECORD;
  1169.     goto err;
  1170.   }
  1171. #endif
  1172.   info->packed_length=block_info.rec_len;
  1173.   info->lastpos=filepos;
  1174.   info->nextpos=filepos+share->pack.ref_length+block_info.rec_len;
  1175.   info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
  1176.  
  1177.   DBUG_RETURN (_nisam_pack_rec_unpack(info,buf,share->file_map+
  1178.                       share->pack.ref_length+filepos,
  1179.                       block_info.rec_len));
  1180. err:
  1181.   DBUG_RETURN(-1);
  1182. }
  1183.  
  1184. #endif /* HAVE_MMAP */
  1185.