~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_packrec.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2006 MySQL 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; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
        /* Functions to compressed records */
 
17
 
 
18
#include "fulltext.h"
 
19
 
 
20
#define IS_CHAR ((uint) 32768)          /* Bit if char (not offset) in tree */
 
21
 
 
22
/* Some definitions to keep in sync with myisampack.c */
 
23
#define HEAD_LENGTH     32              /* Length of fixed header */
 
24
 
 
25
#if INT_MAX > 32767
 
26
#define BITS_SAVED 32
 
27
#define MAX_QUICK_TABLE_BITS 9          /* Because we may shift in 24 bits */
 
28
#else
 
29
#define BITS_SAVED 16
 
30
#define MAX_QUICK_TABLE_BITS 6
 
31
#endif
 
32
 
 
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))
 
39
 
 
40
#define decode_bytes_test_bit(bit) \
 
41
  if (low_byte & (1 << (7-bit))) \
 
42
    pos++; \
 
43
  if (*pos & IS_CHAR) \
 
44
  { bits-=(bit+1); break; } \
 
45
  pos+= *pos
 
46
 
 
47
/* Size in uint16 of a Huffman tree for byte compression of 256 byte values. */
 
48
#define OFFSET_TABLE_SIZE 512
 
49
 
 
50
static uint read_huff_table(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree,
 
51
                            uint16 **decode_table,uchar **intervall_buff,
 
52
                            uint16 *tmp_buff);
 
53
static void make_quick_table(uint16 *to_table,uint16 *decode_table,
 
54
                             uint *next_free,uint value,uint bits,
 
55
                             uint max_bits);
 
56
static void fill_quick_table(uint16 *table,uint bits, uint max_bits,
 
57
                             uint value);
 
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);
 
61
static void (*get_unpack_function(MI_COLUMNDEF *rec))(MI_COLUMNDEF *field,
 
62
                                                    MI_BIT_BUFF *buff,
 
63
                                                    uchar *to,
 
64
                                                    uchar *end);
 
65
static void uf_zerofill_skip_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
66
                                   uchar *to,uchar *end);
 
67
static void uf_skip_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
68
                          uchar *to,uchar *end);
 
69
static void uf_space_normal(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
70
                            uchar *to,uchar *end);
 
71
static void uf_space_endspace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
72
                                       uchar *to, uchar *end);
 
73
static void uf_endspace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
74
                                 uchar *to,uchar *end);
 
75
static void uf_space_endspace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
76
                              uchar *to,uchar *end);
 
77
static void uf_endspace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
78
                        uchar *to,uchar *end);
 
79
static void uf_space_prespace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
80
                                       uchar *to, uchar *end);
 
81
static void uf_prespace_selected(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
82
                                 uchar *to,uchar *end);
 
83
static void uf_space_prespace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
84
                              uchar *to,uchar *end);
 
85
static void uf_prespace(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
86
                        uchar *to,uchar *end);
 
87
static void uf_zerofill_normal(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
88
                               uchar *to,uchar *end);
 
89
static void uf_constant(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
90
                        uchar *to,uchar *end);
 
91
static void uf_intervall(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
92
                         uchar *to,uchar *end);
 
93
static void uf_zero(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
94
                    uchar *to,uchar *end);
 
95
static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
96
                    uchar *to, uchar *end);
 
97
static void uf_varchar1(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
98
                        uchar *to, uchar *end);
 
99
static void uf_varchar2(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
100
                        uchar *to, uchar *end);
 
101
static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,
 
102
                         uchar *to,uchar *end);
 
103
static uint decode_pos(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree);
 
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);
 
106
static void fill_buffer(MI_BIT_BUFF *bit_buff);
 
107
static uint max_bit(uint value);
 
108
#ifdef HAVE_MMAP
 
109
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
 
110
                                         MI_BLOCK_INFO *info, uchar **rec_buff_p,
 
111
                                         uchar *header);
 
112
#endif
 
113
 
 
114
static mi_bit_type mask[]=
 
115
{
 
116
   0x00000000,
 
117
   0x00000001, 0x00000003, 0x00000007, 0x0000000f,
 
118
   0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
 
119
   0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
 
120
   0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
 
121
#if BITS_SAVED > 16
 
122
   0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
 
123
   0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
 
124
   0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
 
125
   0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff,
 
126
#endif
 
127
 };
 
128
 
 
129
 
 
130
        /* Read all packed info, allocate memory and fix field structs */
 
131
 
 
132
my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
 
133
{
 
134
  File file;
 
135
  int diff_length;
 
136
  uint i,trees,huff_tree_bits,rec_reflength,length;
 
137
  uint16 *decode_table,*tmp_buff;
 
138
  ulong elements,intervall_length;
 
139
  uchar *disk_cache;
 
140
  uchar *intervall_buff;
 
141
  uchar header[HEAD_LENGTH];
 
142
  MYISAM_SHARE *share=info->s;
 
143
  MI_BIT_BUFF bit_buff;
 
144
  DBUG_ENTER("_mi_read_pack_info");
 
145
 
 
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;
 
150
 
 
151
  file=info->dfile;
 
152
  my_errno=0;
 
153
  if (my_read(file,(uchar*) header,sizeof(header),MYF(MY_NABP)))
 
154
  {
 
155
    if (!my_errno)
 
156
      my_errno=HA_ERR_END_OF_FILE;
 
157
    goto err0;
 
158
  }
 
159
  /* Only the first three bytes of magic number are independent of version. */
 
160
  if (memcmp((uchar*) header, (uchar*) myisam_pack_file_magic, 3))
 
161
  {
 
162
    my_errno=HA_ERR_WRONG_IN_RECORD;
 
163
    goto err0;
 
164
  }
 
165
  share->pack.version= header[3]; /* fourth byte of magic number */
 
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;
 
175
  if (fix_keys)
 
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));
 
190
 
 
191
  /*
 
192
    Memory segment #1:
 
193
    - Decode tree heads
 
194
    - Distinct column values
 
195
  */
 
196
  if (!(share->decode_trees=(MI_DECODE_TREE*)
 
197
        my_malloc((uint) (trees*sizeof(MI_DECODE_TREE)+
 
198
                          intervall_length*sizeof(uchar)),
 
199
                  MYF(MY_WME))))
 
200
    goto err0;
 
201
  intervall_buff=(uchar*) (share->decode_trees+trees);
 
202
 
 
203
  /*
 
204
    Memory segment #2:
 
205
    - Decode tables
 
206
    - Quick decode tables
 
207
    - Temporary decode table
 
208
    - Compressed data file header cache
 
209
    This segment will be reallocated after construction of the tables.
 
210
  */
 
211
  length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits));
 
212
  if (!(share->decode_tables=(uint16*)
 
213
        my_malloc((length + OFFSET_TABLE_SIZE) * sizeof(uint16) +
 
214
                  (uint) (share->pack.header_length - sizeof(header)),
 
215
                  MYF(MY_WME | MY_ZEROFILL))))
 
216
    goto err1;
 
217
  tmp_buff=share->decode_tables+length;
 
218
  disk_cache= (uchar*) (tmp_buff+OFFSET_TABLE_SIZE);
 
219
 
 
220
  if (my_read(file,disk_cache,
 
221
              (uint) (share->pack.header_length-sizeof(header)),
 
222
              MYF(MY_NABP)))
 
223
    goto err2;
 
224
 
 
225
  huff_tree_bits=max_bit(trees ? trees-1 : 0);
 
226
  init_bit_buffer(&bit_buff, disk_cache,
 
227
                  (uint) (share->pack.header_length-sizeof(header)));
 
228
  /* Read new info for each field */
 
229
  for (i=0 ; i < share->base.fields ; i++)
 
230
  {
 
231
    share->rec[i].base_type=(enum en_fieldtype) get_bits(&bit_buff,5);
 
232
    share->rec[i].pack_type=(uint) get_bits(&bit_buff,6);
 
233
    share->rec[i].space_length_bits=get_bits(&bit_buff,5);
 
234
    share->rec[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
 
235
                                                                huff_tree_bits);
 
236
    share->rec[i].unpack=get_unpack_function(share->rec+i);
 
237
    DBUG_PRINT("info", ("col: %2u  type: %2u  pack: %u  slbits: %2u",
 
238
                        i, share->rec[i].base_type, share->rec[i].pack_type,
 
239
                        share->rec[i].space_length_bits));
 
240
  }
 
241
  skip_to_next_byte(&bit_buff);
 
242
  /*
 
243
    Construct the decoding tables from the file header. Keep track of
 
244
    the used memory.
 
245
  */
 
246
  decode_table=share->decode_tables;
 
247
  for (i=0 ; i < trees ; i++)
 
248
    if (read_huff_table(&bit_buff,share->decode_trees+i,&decode_table,
 
249
                        &intervall_buff,tmp_buff))
 
250
      goto err3;
 
251
  /* Reallocate the decoding tables to the used size. */
 
252
  decode_table=(uint16*)
 
253
    my_realloc((uchar*) share->decode_tables,
 
254
               (uint) ((uchar*) decode_table - (uchar*) share->decode_tables),
 
255
               MYF(MY_HOLD_ON_ERROR));
 
256
  /* Fix the table addresses in the tree heads. */
 
257
  {
 
258
    long diff=PTR_BYTE_DIFF(decode_table,share->decode_tables);
 
259
    share->decode_tables=decode_table;
 
260
    for (i=0 ; i < trees ; i++)
 
261
      share->decode_trees[i].table=ADD_TO_PTR(share->decode_trees[i].table,
 
262
                                              diff, uint16*);
 
263
  }
 
264
 
 
265
  /* Fix record-ref-length for keys */
 
266
  if (fix_keys)
 
267
  {
 
268
    for (i=0 ; i < share->base.keys ; i++)
 
269
    {
 
270
      MI_KEYDEF *keyinfo= &share->keyinfo[i];
 
271
      keyinfo->keylength+= (uint16) diff_length;
 
272
      keyinfo->minlength+= (uint16) diff_length;
 
273
      keyinfo->maxlength+= (uint16) diff_length;
 
274
      keyinfo->seg[keyinfo->flag & HA_FULLTEXT ?
 
275
                   FT_SEGS : keyinfo->keysegs].length= (uint16) rec_reflength;
 
276
    }
 
277
    if (share->ft2_keyinfo.seg)
 
278
    {
 
279
      MI_KEYDEF *ft2_keyinfo= &share->ft2_keyinfo;
 
280
      ft2_keyinfo->keylength+= (uint16) diff_length;
 
281
      ft2_keyinfo->minlength+= (uint16) diff_length;
 
282
      ft2_keyinfo->maxlength+= (uint16) diff_length;
 
283
    }
 
284
  }
 
285
 
 
286
  if (bit_buff.error || bit_buff.pos < bit_buff.end)
 
287
    goto err3;
 
288
 
 
289
  DBUG_RETURN(0);
 
290
 
 
291
err3:
 
292
  my_errno=HA_ERR_WRONG_IN_RECORD;
 
293
err2:
 
294
  my_free((uchar*) share->decode_tables,MYF(0));
 
295
err1:
 
296
  my_free((uchar*) share->decode_trees,MYF(0));
 
297
err0:
 
298
  DBUG_RETURN(1);
 
299
}
 
300
 
 
301
 
 
302
/*
 
303
  Read a huff-code-table from datafile.
 
304
 
 
305
  SYNOPSIS
 
306
    read_huff_table()
 
307
      bit_buff                  Bit buffer pointing at start of the
 
308
                                decoding table in the file header cache.
 
309
      decode_tree               Pointer to the decode tree head.
 
310
      decode_table      IN/OUT  Address of a pointer to the next free space.
 
311
      intervall_buff    IN/OUT  Address of a pointer to the next unused values.
 
312
      tmp_buff                  Buffer for temporary extraction of a full
 
313
                                decoding table as read from bit_buff.
 
314
 
 
315
  RETURN
 
316
    0           OK.
 
317
    1           Error.
 
318
*/
 
319
 
 
320
static uint read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree,
 
321
                            uint16 **decode_table, uchar **intervall_buff,
 
322
                            uint16 *tmp_buff)
 
323
{
 
324
  uint min_chr,elements,char_bits,offset_bits,size,intervall_length,table_bits,
 
325
  next_free_offset;
 
326
  uint16 *ptr,*end;
 
327
  DBUG_ENTER("read_huff_table");
 
328
 
 
329
  if (!get_bits(bit_buff,1))
 
330
  {
 
331
    /* Byte value compression. */
 
332
    min_chr=get_bits(bit_buff,8);
 
333
    elements=get_bits(bit_buff,9);
 
334
    char_bits=get_bits(bit_buff,5);
 
335
    offset_bits=get_bits(bit_buff,5);
 
336
    intervall_length=0;
 
337
    ptr=tmp_buff;
 
338
    DBUG_PRINT("info", ("byte value compression"));
 
339
    DBUG_PRINT("info", ("minimum byte value:    %u", min_chr));
 
340
    DBUG_PRINT("info", ("number of tree nodes:  %u", elements));
 
341
    DBUG_PRINT("info", ("bits for values:       %u", char_bits));
 
342
    DBUG_PRINT("info", ("bits for tree offsets: %u", offset_bits));
 
343
    if (elements > 256)
 
344
    {
 
345
      DBUG_PRINT("error", ("ERROR: illegal number of tree elements: %u",
 
346
                           elements));
 
347
      DBUG_RETURN(1);
 
348
    }
 
349
  }
 
350
  else
 
351
  {
 
352
    /* Distinct column value compression. */
 
353
    min_chr=0;
 
354
    elements=get_bits(bit_buff,15);
 
355
    intervall_length=get_bits(bit_buff,16);
 
356
    char_bits=get_bits(bit_buff,5);
 
357
    offset_bits=get_bits(bit_buff,5);
 
358
    decode_tree->quick_table_bits=0;
 
359
    ptr= *decode_table;
 
360
    DBUG_PRINT("info", ("distinct column value compression"));
 
361
    DBUG_PRINT("info", ("number of tree nodes:  %u", elements));
 
362
    DBUG_PRINT("info", ("value buffer length:   %u", intervall_length));
 
363
    DBUG_PRINT("info", ("bits for value index:  %u", char_bits));
 
364
    DBUG_PRINT("info", ("bits for tree offsets: %u", offset_bits));
 
365
  }
 
366
  size=elements*2-2;
 
367
  DBUG_PRINT("info", ("tree size in uint16:   %u", size));
 
368
  DBUG_PRINT("info", ("tree size in bytes:    %u",
 
369
                      size * (uint) sizeof(uint16)));
 
370
 
 
371
  for (end=ptr+size ; ptr < end ; ptr++)
 
372
  {
 
373
    if (get_bit(bit_buff))
 
374
    {
 
375
      *ptr= (uint16) get_bits(bit_buff,offset_bits);
 
376
      if ((ptr + *ptr >= end) || !*ptr)
 
377
      {
 
378
        DBUG_PRINT("error", ("ERROR: illegal pointer in decode tree"));
 
379
        DBUG_RETURN(1);
 
380
      }
 
381
    }
 
382
    else
 
383
      *ptr= (uint16) (IS_CHAR + (get_bits(bit_buff,char_bits) + min_chr));
 
384
  }
 
385
  skip_to_next_byte(bit_buff);
 
386
 
 
387
  decode_tree->table= *decode_table;
 
388
  decode_tree->intervalls= *intervall_buff;
 
389
  if (! intervall_length)
 
390
  {
 
391
    /* Byte value compression. ptr started from tmp_buff. */
 
392
    /* Find longest Huffman code from begin to end of tree in bits. */
 
393
    table_bits= find_longest_bitstream(tmp_buff, ptr);
 
394
    if (table_bits >= OFFSET_TABLE_SIZE)
 
395
      DBUG_RETURN(1);
 
396
    if (table_bits > myisam_quick_table_bits)
 
397
      table_bits=myisam_quick_table_bits;
 
398
    DBUG_PRINT("info", ("table bits:            %u", table_bits));
 
399
 
 
400
    next_free_offset= (1 << table_bits);
 
401
    make_quick_table(*decode_table,tmp_buff,&next_free_offset,0,table_bits,
 
402
                     table_bits);
 
403
    (*decode_table)+= next_free_offset;
 
404
    decode_tree->quick_table_bits=table_bits;
 
405
  }
 
406
  else
 
407
  {
 
408
    /* Distinct column value compression. ptr started from *decode_table */
 
409
    (*decode_table)=end;
 
410
    /*
 
411
      get_bits() moves some bytes to a cache buffer in advance. May need
 
412
      to step back.
 
413
    */
 
414
    bit_buff->pos-= bit_buff->bits/8;
 
415
    /* Copy the distinct column values from the buffer. */
 
416
    memcpy(*intervall_buff,bit_buff->pos,(size_t) intervall_length);
 
417
    (*intervall_buff)+=intervall_length;
 
418
    bit_buff->pos+=intervall_length;
 
419
    bit_buff->bits=0;
 
420
  }
 
421
  DBUG_RETURN(0);
 
422
}
 
423
 
 
424
 
 
425
/*
 
426
  Make a quick_table for faster decoding.
 
427
 
 
428
  SYNOPSIS
 
429
    make_quick_table()
 
430
      to_table                  Target quick_table and remaining decode table.
 
431
      decode_table              Source Huffman (sub-)tree within tmp_buff.
 
432
      next_free_offset   IN/OUT Next free offset from to_table.
 
433
                                Starts behind quick_table on the top-level.
 
434
      value                     Huffman bits found so far.
 
435
      bits                      Remaining bits to be collected.
 
436
      max_bits                  Total number of bits to collect (table_bits).
 
437
 
 
438
  DESCRIPTION
 
439
 
 
440
    The quick table is an array of 16-bit values. There exists one value
 
441
    for each possible code representable by max_bits (table_bits) bits.
 
442
    In most cases table_bits is 9. So there are 512 16-bit values.
 
443
 
 
444
    If the high-order bit (16) is set (IS_CHAR) then the array slot for
 
445
    this value is a valid Huffman code for a resulting byte value.
 
446
 
 
447
    The low-order 8 bits (1..8) are the resulting byte value.
 
448
 
 
449
    Bits 9..14 are the length of the Huffman code for this byte value.
 
450
    This means so many bits from the input stream were needed to
 
451
    represent this byte value. The remaining bits belong to later
 
452
    Huffman codes. This also means that for every Huffman code shorter
 
453
    than table_bits there are multiple entires in the array, which
 
454
    differ just in the unused bits.
 
455
 
 
456
    If the high-order bit (16) is clear (0) then the remaining bits are
 
457
    the position of the remaining Huffman decode tree segment behind the
 
458
    quick table.
 
459
 
 
460
  RETURN
 
461
    void
 
462
*/
 
463
 
 
464
static void make_quick_table(uint16 *to_table, uint16 *decode_table,
 
465
                             uint *next_free_offset, uint value, uint bits,
 
466
                             uint max_bits)
 
467
{
 
468
  DBUG_ENTER("make_quick_table");
 
469
 
 
470
  /*
 
471
    When down the table to the requested maximum, copy the rest of the
 
472
    Huffman table.
 
473
  */
 
474
  if (!bits--)
 
475
  {
 
476
    /*
 
477
      Remaining left  Huffman tree segment starts behind quick table.
 
478
      Remaining right Huffman tree segment starts behind left segment.
 
479
    */
 
480
    to_table[value]= (uint16) *next_free_offset;
 
481
    /*
 
482
      Re-construct the remaining Huffman tree segment at
 
483
      next_free_offset in to_table.
 
484
    */
 
485
    *next_free_offset= copy_decode_table(to_table, *next_free_offset,
 
486
                                         decode_table);
 
487
    DBUG_VOID_RETURN;
 
488
  }
 
489
 
 
490
  /* Descent on the left side. Left side bits are clear (0). */
 
491
  if (!(*decode_table & IS_CHAR))
 
492
  {
 
493
    /* Not a leaf. Follow the pointer. */
 
494
    make_quick_table(to_table, decode_table + *decode_table,
 
495
                     next_free_offset, value, bits, max_bits);
 
496
  }
 
497
  else
 
498
  {
 
499
    /*
 
500
      A leaf. A Huffman code is complete. Fill the quick_table
 
501
      array for all possible bit strings starting with this Huffman
 
502
      code.
 
503
    */
 
504
    fill_quick_table(to_table + value, bits, max_bits, (uint) *decode_table);
 
505
  }
 
506
 
 
507
  /* Descent on the right side. Right side bits are set (1). */
 
508
  decode_table++;
 
509
  value|= (1 << bits);
 
510
  if (!(*decode_table & IS_CHAR))
 
511
  {
 
512
    /* Not a leaf. Follow the pointer. */
 
513
    make_quick_table(to_table, decode_table + *decode_table,
 
514
                     next_free_offset, value, bits, max_bits);
 
515
  }
 
516
  else
 
517
  {
 
518
    /*
 
519
      A leaf. A Huffman code is complete. Fill the quick_table
 
520
      array for all possible bit strings starting with this Huffman
 
521
      code.
 
522
    */
 
523
    fill_quick_table(to_table + value, bits, max_bits, (uint) *decode_table);
 
524
  }
 
525
 
 
526
  DBUG_VOID_RETURN;
 
527
}
 
528
 
 
529
 
 
530
/*
 
531
  Fill quick_table for all possible values starting with this Huffman code.
 
532
 
 
533
  SYNOPSIS
 
534
    fill_quick_table()
 
535
      table                     Target quick_table position.
 
536
      bits                      Unused bits from max_bits.
 
537
      max_bits                  Total number of bits to collect (table_bits).
 
538
      value                     The byte encoded by the found Huffman code.
 
539
 
 
540
  DESCRIPTION
 
541
 
 
542
    Fill the segment (all slots) of the quick_table array with the
 
543
    resulting value for the found Huffman code. There are as many slots
 
544
    as there are combinations representable by the unused bits.
 
545
 
 
546
    In most cases we use 9 table bits. Assume a 3-bit Huffman code. Then
 
547
    there are 6 unused bits. Hence we fill 2**6 = 64 slots with the
 
548
    value.
 
549
 
 
550
  RETURN
 
551
    void
 
552
*/
 
553
 
 
554
static void fill_quick_table(uint16 *table, uint bits, uint max_bits,
 
555
                             uint value)
 
556
{
 
557
  uint16 *end;
 
558
  DBUG_ENTER("fill_quick_table");
 
559
 
 
560
  /*
 
561
    Bits 1..8 of value represent the decoded byte value.
 
562
    Bits 9..14 become the length of the Huffman code for this byte value.
 
563
    Bit 16 flags a valid code (IS_CHAR).
 
564
  */
 
565
  value|= (max_bits - bits) << 8 | IS_CHAR;
 
566
 
 
567
  for (end= table + ((my_ptrdiff_t) 1 << bits); table < end; table++)
 
568
  {
 
569
    *table= (uint16) value;
 
570
  }
 
571
  DBUG_VOID_RETURN;
 
572
}
 
573
 
 
574
 
 
575
/*
 
576
  Reconstruct a decode subtree at the target position.
 
577
 
 
578
  SYNOPSIS
 
579
    copy_decode_table()
 
580
      to_pos                    Target quick_table and remaining decode table.
 
581
      offset                    Next free offset from to_pos.
 
582
      decode_table              Source Huffman subtree within tmp_buff.
 
583
 
 
584
  NOTE
 
585
    Pointers in the decode tree are relative to the pointers position.
 
586
 
 
587
  RETURN
 
588
    next free offset from to_pos.
 
589
*/
 
590
 
 
591
static uint copy_decode_table(uint16 *to_pos, uint offset,
 
592
                              uint16 *decode_table)
 
593
{
 
594
  uint prev_offset= offset;
 
595
  DBUG_ENTER("copy_decode_table");
 
596
 
 
597
  /* Descent on the left side. */
 
598
  if (!(*decode_table & IS_CHAR))
 
599
  {
 
600
    /* Set a pointer to the next target node. */
 
601
    to_pos[offset]=2;
 
602
    /* Copy the left hand subtree there. */
 
603
    offset=copy_decode_table(to_pos,offset+2,decode_table+ *decode_table);
 
604
  }
 
605
  else
 
606
  {
 
607
    /* Copy the byte value. */
 
608
    to_pos[offset]= *decode_table;
 
609
    /* Step behind this node. */
 
610
    offset+=2;
 
611
  }
 
612
 
 
613
  /* Descent on the right side. */
 
614
  decode_table++;
 
615
  if (!(*decode_table & IS_CHAR))
 
616
  {
 
617
    /* Set a pointer to the next free target node. */
 
618
    to_pos[prev_offset+1]=(uint16) (offset-prev_offset-1);
 
619
    /* Copy the right hand subtree to the entry of that node. */
 
620
    offset=copy_decode_table(to_pos,offset,decode_table+ *decode_table);
 
621
  }
 
622
  else
 
623
  {
 
624
    /* Copy the byte value. */
 
625
    to_pos[prev_offset+1]= *decode_table;
 
626
  }
 
627
  DBUG_RETURN(offset);
 
628
}
 
629
 
 
630
 
 
631
/*
 
632
  Find the length of the longest Huffman code in this table in bits.
 
633
 
 
634
  SYNOPSIS
 
635
    find_longest_bitstream()
 
636
      table                     Code (sub-)table start.
 
637
      end                       End of code table.
 
638
 
 
639
  IMPLEMENTATION
 
640
 
 
641
    Recursively follow the branch(es) of the code pair on every level of
 
642
    the tree until two byte values (and no branch) are found. Add one to
 
643
    each level when returning back from each recursion stage.
 
644
 
 
645
    'end' is used for error checking only. A clean tree terminates
 
646
    before reaching 'end'. Hence the exact value of 'end' is not too
 
647
    important. However having it higher than necessary could lead to
 
648
    misbehaviour should 'next' jump into the dirty area.
 
649
 
 
650
  RETURN
 
651
    length                  Length of longest Huffman code in bits.
 
652
    >= OFFSET_TABLE_SIZE    Error, broken tree. It does not end before 'end'.
 
653
*/
 
654
 
 
655
static uint find_longest_bitstream(uint16 *table, uint16 *end)
 
656
{
 
657
  uint length= 1;
 
658
  uint length2;
 
659
 
 
660
  if (!(*table & IS_CHAR))
 
661
  {
 
662
    uint16 *next= table + *table;
 
663
    if (next > end || next == table)
 
664
    {
 
665
      DBUG_PRINT("error", ("ERROR: illegal pointer in decode tree"));
 
666
      return OFFSET_TABLE_SIZE;
 
667
    }
 
668
    length= find_longest_bitstream(next, end) + 1;
 
669
  }
 
670
  table++;
 
671
  if (!(*table & IS_CHAR))
 
672
  {
 
673
    uint16 *next= table + *table;
 
674
    if (next > end || next == table)
 
675
    {
 
676
      DBUG_PRINT("error", ("ERROR: illegal pointer in decode tree"));
 
677
      return OFFSET_TABLE_SIZE;
 
678
    }
 
679
    length2= find_longest_bitstream(next, end) + 1;
 
680
    length=max(length,length2);
 
681
  }
 
682
  return length;
 
683
}
 
684
 
 
685
 
 
686
/*
 
687
  Read record from datafile.
 
688
 
 
689
  SYNOPSIS
 
690
    _mi_read_pack_record()
 
691
    info                        A pointer to MI_INFO.
 
692
    filepos                     File offset of the record.
 
693
    buf                 RETURN  The buffer to receive the record.
 
694
 
 
695
  RETURN
 
696
    0                                   on success
 
697
    HA_ERR_WRONG_IN_RECORD or -1        on error
 
698
*/
 
699
 
 
700
int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, uchar *buf)
 
701
{
 
702
  MI_BLOCK_INFO block_info;
 
703
  File file;
 
704
  DBUG_ENTER("mi_read_pack_record");
 
705
 
 
706
  if (filepos == HA_OFFSET_ERROR)
 
707
    DBUG_RETURN(-1);                    /* _search() didn't find record */
 
708
 
 
709
  file=info->dfile;
 
710
  if (_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
 
711
                              &info->rec_buff, file, filepos))
 
712
    goto err;
 
713
  if (my_read(file,(uchar*) info->rec_buff + block_info.offset ,
 
714
              block_info.rec_len - block_info.offset, MYF(MY_NABP)))
 
715
    goto panic;
 
716
  info->update|= HA_STATE_AKTIV;
 
717
  DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
718
                                  info->rec_buff, block_info.rec_len));
 
719
panic:
 
720
  my_errno=HA_ERR_WRONG_IN_RECORD;
 
721
err:
 
722
  DBUG_RETURN(-1);
 
723
}
 
724
 
 
725
 
 
726
 
 
727
int _mi_pack_rec_unpack(register MI_INFO *info, MI_BIT_BUFF *bit_buff,
 
728
                        register uchar *to, uchar *from, ulong reclength)
 
729
{
 
730
  uchar *end_field;
 
731
  register MI_COLUMNDEF *end;
 
732
  MI_COLUMNDEF *current_field;
 
733
  MYISAM_SHARE *share=info->s;
 
734
  DBUG_ENTER("_mi_pack_rec_unpack");
 
735
 
 
736
  init_bit_buffer(bit_buff, (uchar*) from, reclength);
 
737
 
 
738
  for (current_field=share->rec, end=current_field+share->base.fields ;
 
739
       current_field < end ;
 
740
       current_field++,to=end_field)
 
741
  {
 
742
    end_field=to+current_field->length;
 
743
    (*current_field->unpack)(current_field, bit_buff, (uchar*) to,
 
744
                             (uchar*) end_field);
 
745
  }
 
746
  if (!bit_buff->error &&
 
747
      bit_buff->pos - bit_buff->bits / 8 == bit_buff->end)
 
748
    DBUG_RETURN(0);
 
749
  info->update&= ~HA_STATE_AKTIV;
 
750
  DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD);
 
751
} /* _mi_pack_rec_unpack */
 
752
 
 
753
 
 
754
        /* Return function to unpack field */
 
755
 
 
756
static void (*get_unpack_function(MI_COLUMNDEF *rec))
 
757
(MI_COLUMNDEF *, MI_BIT_BUFF *, uchar *, uchar *)
 
758
{
 
759
  switch (rec->base_type) {
 
760
  case FIELD_SKIP_ZERO:
 
761
    if (rec->pack_type & PACK_TYPE_ZERO_FILL)
 
762
      return &uf_zerofill_skip_zero;
 
763
    return &uf_skip_zero;
 
764
  case FIELD_NORMAL:
 
765
    if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
 
766
      return &uf_space_normal;
 
767
    if (rec->pack_type & PACK_TYPE_ZERO_FILL)
 
768
      return &uf_zerofill_normal;
 
769
    return &decode_bytes;
 
770
  case FIELD_SKIP_ENDSPACE:
 
771
    if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
 
772
    {
 
773
      if (rec->pack_type & PACK_TYPE_SELECTED)
 
774
        return &uf_space_endspace_selected;
 
775
      return &uf_space_endspace;
 
776
    }
 
777
    if (rec->pack_type & PACK_TYPE_SELECTED)
 
778
      return &uf_endspace_selected;
 
779
    return &uf_endspace;
 
780
  case FIELD_SKIP_PRESPACE:
 
781
    if (rec->pack_type & PACK_TYPE_SPACE_FIELDS)
 
782
    {
 
783
      if (rec->pack_type & PACK_TYPE_SELECTED)
 
784
        return &uf_space_prespace_selected;
 
785
      return &uf_space_prespace;
 
786
    }
 
787
    if (rec->pack_type & PACK_TYPE_SELECTED)
 
788
      return &uf_prespace_selected;
 
789
    return &uf_prespace;
 
790
  case FIELD_CONSTANT:
 
791
    return &uf_constant;
 
792
  case FIELD_INTERVALL:
 
793
    return &uf_intervall;
 
794
  case FIELD_ZERO:
 
795
  case FIELD_CHECK:
 
796
    return &uf_zero;
 
797
  case FIELD_BLOB:
 
798
    return &uf_blob;
 
799
  case FIELD_VARCHAR:
 
800
    if (rec->length <= 256)                      /* 255 + 1 byte length */
 
801
      return &uf_varchar1;
 
802
    return &uf_varchar2;
 
803
  case FIELD_LAST:
 
804
  default:
 
805
    return 0;                   /* This should never happend */
 
806
  }
 
807
}
 
808
 
 
809
        /* The different functions to unpack a field */
 
810
 
 
811
static void uf_zerofill_skip_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
812
                                   uchar *to, uchar *end)
 
813
{
 
814
  if (get_bit(bit_buff))
 
815
    bzero((char*) to,(uint) (end-to));
 
816
  else
 
817
  {
 
818
    end-=rec->space_length_bits;
 
819
    decode_bytes(rec,bit_buff,to,end);
 
820
    bzero((char*) end,rec->space_length_bits);
 
821
  }
 
822
}
 
823
 
 
824
static void uf_skip_zero(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
825
                          uchar *end)
 
826
{
 
827
  if (get_bit(bit_buff))
 
828
    bzero((char*) to,(uint) (end-to));
 
829
  else
 
830
    decode_bytes(rec,bit_buff,to,end);
 
831
}
 
832
 
 
833
static void uf_space_normal(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
834
                            uchar *end)
 
835
{
 
836
  if (get_bit(bit_buff))
 
837
    bfill((uchar*) to,(end-to),' ');
 
838
  else
 
839
    decode_bytes(rec,bit_buff,to,end);
 
840
}
 
841
 
 
842
static void uf_space_endspace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
843
                                       uchar *to, uchar *end)
 
844
{
 
845
  uint spaces;
 
846
  if (get_bit(bit_buff))
 
847
    bfill((uchar*) to,(end-to),' ');
 
848
  else
 
849
  {
 
850
    if (get_bit(bit_buff))
 
851
    {
 
852
      if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
853
      {
 
854
        bit_buff->error=1;
 
855
        return;
 
856
      }
 
857
      if (to+spaces != end)
 
858
        decode_bytes(rec,bit_buff,to,end-spaces);
 
859
      bfill((uchar*) end-spaces,spaces,' ');
 
860
    }
 
861
    else
 
862
      decode_bytes(rec,bit_buff,to,end);
 
863
  }
 
864
}
 
865
 
 
866
static void uf_endspace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
867
                                 uchar *to, uchar *end)
 
868
{
 
869
  uint spaces;
 
870
  if (get_bit(bit_buff))
 
871
  {
 
872
    if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
873
    {
 
874
      bit_buff->error=1;
 
875
      return;
 
876
    }
 
877
    if (to+spaces != end)
 
878
      decode_bytes(rec,bit_buff,to,end-spaces);
 
879
    bfill((uchar*) end-spaces,spaces,' ');
 
880
  }
 
881
  else
 
882
    decode_bytes(rec,bit_buff,to,end);
 
883
}
 
884
 
 
885
static void uf_space_endspace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
886
                              uchar *end)
 
887
{
 
888
  uint spaces;
 
889
  if (get_bit(bit_buff))
 
890
    bfill((uchar*) to,(end-to),' ');
 
891
  else
 
892
  {
 
893
    if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
894
    {
 
895
      bit_buff->error=1;
 
896
      return;
 
897
    }
 
898
    if (to+spaces != end)
 
899
      decode_bytes(rec,bit_buff,to,end-spaces);
 
900
    bfill((uchar*) end-spaces,spaces,' ');
 
901
  }
 
902
}
 
903
 
 
904
static void uf_endspace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
905
                        uchar *end)
 
906
{
 
907
  uint spaces;
 
908
  if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
909
  {
 
910
    bit_buff->error=1;
 
911
    return;
 
912
  }
 
913
  if (to+spaces != end)
 
914
    decode_bytes(rec,bit_buff,to,end-spaces);
 
915
  bfill((uchar*) end-spaces,spaces,' ');
 
916
}
 
917
 
 
918
static void uf_space_prespace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
919
                                       uchar *to, uchar *end)
 
920
{
 
921
  uint spaces;
 
922
  if (get_bit(bit_buff))
 
923
    bfill((uchar*) to,(end-to),' ');
 
924
  else
 
925
  {
 
926
    if (get_bit(bit_buff))
 
927
    {
 
928
      if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
929
      {
 
930
        bit_buff->error=1;
 
931
        return;
 
932
      }
 
933
      bfill((uchar*) to,spaces,' ');
 
934
      if (to+spaces != end)
 
935
        decode_bytes(rec,bit_buff,to+spaces,end);
 
936
    }
 
937
    else
 
938
      decode_bytes(rec,bit_buff,to,end);
 
939
  }
 
940
}
 
941
 
 
942
 
 
943
static void uf_prespace_selected(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
944
                                 uchar *to, uchar *end)
 
945
{
 
946
  uint spaces;
 
947
  if (get_bit(bit_buff))
 
948
  {
 
949
    if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
950
    {
 
951
      bit_buff->error=1;
 
952
      return;
 
953
    }
 
954
    bfill((uchar*) to,spaces,' ');
 
955
    if (to+spaces != end)
 
956
      decode_bytes(rec,bit_buff,to+spaces,end);
 
957
  }
 
958
  else
 
959
    decode_bytes(rec,bit_buff,to,end);
 
960
}
 
961
 
 
962
 
 
963
static void uf_space_prespace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
964
                              uchar *end)
 
965
{
 
966
  uint spaces;
 
967
  if (get_bit(bit_buff))
 
968
    bfill((uchar*) to,(end-to),' ');
 
969
  else
 
970
  {
 
971
    if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
972
    {
 
973
      bit_buff->error=1;
 
974
      return;
 
975
    }
 
976
    bfill((uchar*) to,spaces,' ');
 
977
    if (to+spaces != end)
 
978
      decode_bytes(rec,bit_buff,to+spaces,end);
 
979
  }
 
980
}
 
981
 
 
982
static void uf_prespace(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
983
                        uchar *end)
 
984
{
 
985
  uint spaces;
 
986
  if ((spaces=get_bits(bit_buff,rec->space_length_bits))+to > end)
 
987
  {
 
988
    bit_buff->error=1;
 
989
    return;
 
990
  }
 
991
  bfill((uchar*) to,spaces,' ');
 
992
  if (to+spaces != end)
 
993
    decode_bytes(rec,bit_buff,to+spaces,end);
 
994
}
 
995
 
 
996
static void uf_zerofill_normal(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
997
                               uchar *end)
 
998
{
 
999
  end-=rec->space_length_bits;
 
1000
  decode_bytes(rec,bit_buff,(uchar*) to,end);
 
1001
  bzero((char*) end,rec->space_length_bits);
 
1002
}
 
1003
 
 
1004
static void uf_constant(MI_COLUMNDEF *rec,
 
1005
                        MI_BIT_BUFF *bit_buff __attribute__((unused)),
 
1006
                        uchar *to,
 
1007
                        uchar *end)
 
1008
{
 
1009
  memcpy(to,rec->huff_tree->intervalls,(size_t) (end-to));
 
1010
}
 
1011
 
 
1012
static void uf_intervall(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
1013
                         uchar *end)
 
1014
{
 
1015
  register uint field_length=(uint) (end-to);
 
1016
  memcpy(to,rec->huff_tree->intervalls+field_length*decode_pos(bit_buff,
 
1017
                                                               rec->huff_tree),
 
1018
         (size_t) field_length);
 
1019
}
 
1020
 
 
1021
 
 
1022
/*ARGSUSED*/
 
1023
static void uf_zero(MI_COLUMNDEF *rec __attribute__((unused)),
 
1024
                    MI_BIT_BUFF *bit_buff __attribute__((unused)),
 
1025
                    uchar *to, uchar *end)
 
1026
{
 
1027
  bzero((char*) to,(uint) (end-to));
 
1028
}
 
1029
 
 
1030
static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
1031
                    uchar *to, uchar *end)
 
1032
{
 
1033
  if (get_bit(bit_buff))
 
1034
    bzero((uchar*) to,(end-to));
 
1035
  else
 
1036
  {
 
1037
    ulong length=get_bits(bit_buff,rec->space_length_bits);
 
1038
    uint pack_length=(uint) (end-to)-portable_sizeof_char_ptr;
 
1039
    if (bit_buff->blob_pos+length > bit_buff->blob_end)
 
1040
    {
 
1041
      bit_buff->error=1;
 
1042
      bzero((uchar*) to,(end-to));
 
1043
      return;
 
1044
    }
 
1045
    decode_bytes(rec,bit_buff,bit_buff->blob_pos,bit_buff->blob_pos+length);
 
1046
    _my_store_blob_length((uchar*) to,pack_length,length);
 
1047
    memcpy_fixed((char*) to+pack_length,(char*) &bit_buff->blob_pos,
 
1048
                 sizeof(char*));
 
1049
    bit_buff->blob_pos+=length;
 
1050
  }
 
1051
}
 
1052
 
 
1053
 
 
1054
static void uf_varchar1(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
1055
                       uchar *to, uchar *end __attribute__((unused)))
 
1056
{
 
1057
  if (get_bit(bit_buff))
 
1058
    to[0]= 0;                           /* Zero lengths */
 
1059
  else
 
1060
  {
 
1061
    ulong length=get_bits(bit_buff,rec->space_length_bits);
 
1062
    *to= (uchar) length;
 
1063
    decode_bytes(rec,bit_buff,to+1,to+1+length);
 
1064
  }
 
1065
}
 
1066
 
 
1067
 
 
1068
static void uf_varchar2(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
 
1069
                       uchar *to, uchar *end __attribute__((unused)))
 
1070
{
 
1071
  if (get_bit(bit_buff))
 
1072
    to[0]=to[1]=0;                              /* Zero lengths */
 
1073
  else
 
1074
  {
 
1075
    ulong length=get_bits(bit_buff,rec->space_length_bits);
 
1076
    int2store(to,length);
 
1077
    decode_bytes(rec,bit_buff,to+2,to+2+length);
 
1078
  }
 
1079
}
 
1080
 
 
1081
        /* Functions to decode of buffer of bits */
 
1082
 
 
1083
#if BITS_SAVED == 64
 
1084
 
 
1085
static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,
 
1086
                         uchar *end)
 
1087
{
 
1088
  register uint bits,low_byte;
 
1089
  register uint16 *pos;
 
1090
  register uint table_bits,table_and;
 
1091
  MI_DECODE_TREE *decode_tree;
 
1092
 
 
1093
  decode_tree=rec->decode_tree;
 
1094
  bits=bit_buff->bits;                  /* Save in reg for quicker access */
 
1095
  table_bits=decode_tree->quick_table_bits;
 
1096
  table_and= (1 << table_bits)-1;
 
1097
 
 
1098
  do
 
1099
  {
 
1100
    if (bits <= 32)
 
1101
    {
 
1102
      if (bit_buff->pos > bit_buff->end+4)
 
1103
      {
 
1104
        bit_buff->error=1;
 
1105
        return;                         /* Can't be right */
 
1106
      }
 
1107
      bit_buff->current_byte= (bit_buff->current_byte << 32) +
 
1108
        ((((uint) bit_buff->pos[3])) +
 
1109
         (((uint) bit_buff->pos[2]) << 8) +
 
1110
         (((uint) bit_buff->pos[1]) << 16) +
 
1111
         (((uint) bit_buff->pos[0]) << 24));
 
1112
      bit_buff->pos+=4;
 
1113
      bits+=32;
 
1114
    }
 
1115
    /*
 
1116
      First use info in quick_table.
 
1117
 
 
1118
      The quick table is an array of 16-bit values. There exists one
 
1119
      value for each possible code representable by table_bits bits.
 
1120
      In most cases table_bits is 9. So there are 512 16-bit values.
 
1121
 
 
1122
      If the high-order bit (16) is set (IS_CHAR) then the array slot
 
1123
      for this value is a valid Huffman code for a resulting byte value.
 
1124
 
 
1125
      The low-order 8 bits (1..8) are the resulting byte value.
 
1126
 
 
1127
      Bits 9..14 are the length of the Huffman code for this byte value.
 
1128
      This means so many bits from the input stream were needed to
 
1129
      represent this byte value. The remaining bits belong to later
 
1130
      Huffman codes. This also means that for every Huffman code shorter
 
1131
      than table_bits there are multiple entires in the array, which
 
1132
      differ just in the unused bits.
 
1133
 
 
1134
      If the high-order bit (16) is clear (0) then the remaining bits are
 
1135
      the position of the remaining Huffman decode tree segment behind the
 
1136
      quick table.
 
1137
    */
 
1138
    low_byte=(uint) (bit_buff->current_byte >> (bits - table_bits)) & table_and;
 
1139
    low_byte=decode_tree->table[low_byte];
 
1140
    if (low_byte & IS_CHAR)
 
1141
    {
 
1142
      /*
 
1143
        All Huffman codes of less or equal table_bits length are in the
 
1144
        quick table. This is one of them.
 
1145
      */
 
1146
      *to++ = (low_byte & 255);         /* Found char in quick table */
 
1147
      bits-=  ((low_byte >> 8) & 31);   /* Remove bits used */
 
1148
    }
 
1149
    else
 
1150
    {                                   /* Map through rest of decode-table */
 
1151
      /* This means that the Huffman code must be longer than table_bits. */
 
1152
      pos=decode_tree->table+low_byte;
 
1153
      bits-=table_bits;
 
1154
      /* NOTE: decode_bytes_test_bit() is a macro wich contains a break !!! */
 
1155
      for (;;)
 
1156
      {
 
1157
        low_byte=(uint) (bit_buff->current_byte >> (bits-8));
 
1158
        decode_bytes_test_bit(0);
 
1159
        decode_bytes_test_bit(1);
 
1160
        decode_bytes_test_bit(2);
 
1161
        decode_bytes_test_bit(3);
 
1162
        decode_bytes_test_bit(4);
 
1163
        decode_bytes_test_bit(5);
 
1164
        decode_bytes_test_bit(6);
 
1165
        decode_bytes_test_bit(7);
 
1166
        bits-=8;
 
1167
      }
 
1168
      *to++ = *pos;
 
1169
    }
 
1170
  } while (to != end);
 
1171
 
 
1172
  bit_buff->bits=bits;
 
1173
  return;
 
1174
}
 
1175
 
 
1176
#else
 
1177
 
 
1178
static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
 
1179
                         uchar *end)
 
1180
{
 
1181
  register uint bits,low_byte;
 
1182
  register uint16 *pos;
 
1183
  register uint table_bits,table_and;
 
1184
  MI_DECODE_TREE *decode_tree;
 
1185
 
 
1186
  decode_tree=rec->huff_tree;
 
1187
  bits=bit_buff->bits;                  /* Save in reg for quicker access */
 
1188
  table_bits=decode_tree->quick_table_bits;
 
1189
  table_and= (1 << table_bits)-1;
 
1190
 
 
1191
  do
 
1192
  {
 
1193
    if (bits < table_bits)
 
1194
    {
 
1195
      if (bit_buff->pos > bit_buff->end+1)
 
1196
      {
 
1197
        bit_buff->error=1;
 
1198
        return;                         /* Can't be right */
 
1199
      }
 
1200
#if BITS_SAVED == 32
 
1201
      bit_buff->current_byte= (bit_buff->current_byte << 24) +
 
1202
        (((uint) ((uchar) bit_buff->pos[2]))) +
 
1203
          (((uint) ((uchar) bit_buff->pos[1])) << 8) +
 
1204
            (((uint) ((uchar) bit_buff->pos[0])) << 16);
 
1205
      bit_buff->pos+=3;
 
1206
      bits+=24;
 
1207
#else
 
1208
      if (bits)                         /* We must have at leasts 9 bits */
 
1209
      {
 
1210
        bit_buff->current_byte=  (bit_buff->current_byte << 8) +
 
1211
          (uint) ((uchar) bit_buff->pos[0]);
 
1212
        bit_buff->pos++;
 
1213
        bits+=8;
 
1214
      }
 
1215
      else
 
1216
      {
 
1217
        bit_buff->current_byte= ((uint) ((uchar) bit_buff->pos[0]) << 8) +
 
1218
          ((uint) ((uchar) bit_buff->pos[1]));
 
1219
        bit_buff->pos+=2;
 
1220
        bits+=16;
 
1221
      }
 
1222
#endif
 
1223
    }
 
1224
        /* First use info in quick_table */
 
1225
    low_byte=(bit_buff->current_byte >> (bits - table_bits)) & table_and;
 
1226
    low_byte=decode_tree->table[low_byte];
 
1227
    if (low_byte & IS_CHAR)
 
1228
    {
 
1229
      *to++ = (low_byte & 255);         /* Found char in quick table */
 
1230
      bits-=  ((low_byte >> 8) & 31);   /* Remove bits used */
 
1231
    }
 
1232
    else
 
1233
    {                                   /* Map through rest of decode-table */
 
1234
      pos=decode_tree->table+low_byte;
 
1235
      bits-=table_bits;
 
1236
      for (;;)
 
1237
      {
 
1238
        if (bits < 8)
 
1239
        {                               /* We don't need to check end */
 
1240
#if BITS_SAVED == 32
 
1241
          bit_buff->current_byte= (bit_buff->current_byte << 24) +
 
1242
            (((uint) ((uchar) bit_buff->pos[2]))) +
 
1243
              (((uint) ((uchar) bit_buff->pos[1])) << 8) +
 
1244
                (((uint) ((uchar) bit_buff->pos[0])) << 16);
 
1245
          bit_buff->pos+=3;
 
1246
          bits+=24;
 
1247
#else
 
1248
          bit_buff->current_byte=  (bit_buff->current_byte << 8) +
 
1249
            (uint) ((uchar) bit_buff->pos[0]);
 
1250
          bit_buff->pos+=1;
 
1251
          bits+=8;
 
1252
#endif
 
1253
        }
 
1254
        low_byte=(uint) (bit_buff->current_byte >> (bits-8));
 
1255
        decode_bytes_test_bit(0);
 
1256
        decode_bytes_test_bit(1);
 
1257
        decode_bytes_test_bit(2);
 
1258
        decode_bytes_test_bit(3);
 
1259
        decode_bytes_test_bit(4);
 
1260
        decode_bytes_test_bit(5);
 
1261
        decode_bytes_test_bit(6);
 
1262
        decode_bytes_test_bit(7);
 
1263
        bits-=8;
 
1264
      }
 
1265
      *to++ = (uchar) *pos;
 
1266
    }
 
1267
  } while (to != end);
 
1268
 
 
1269
  bit_buff->bits=bits;
 
1270
  return;
 
1271
}
 
1272
#endif /* BIT_SAVED == 64 */
 
1273
 
 
1274
 
 
1275
static uint decode_pos(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree)
 
1276
{
 
1277
  uint16 *pos=decode_tree->table;
 
1278
  for (;;)
 
1279
  {
 
1280
    if (get_bit(bit_buff))
 
1281
      pos++;
 
1282
    if (*pos & IS_CHAR)
 
1283
      return (uint) (*pos & ~IS_CHAR);
 
1284
    pos+= *pos;
 
1285
  }
 
1286
}
 
1287
 
 
1288
 
 
1289
int _mi_read_rnd_pack_record(MI_INFO *info, uchar *buf,
 
1290
                             register my_off_t filepos,
 
1291
                             my_bool skip_deleted_blocks)
 
1292
{
 
1293
  uint b_type;
 
1294
  MI_BLOCK_INFO block_info;
 
1295
  MYISAM_SHARE *share=info->s;
 
1296
  DBUG_ENTER("_mi_read_rnd_pack_record");
 
1297
 
 
1298
  if (filepos >= info->state->data_file_length)
 
1299
  {
 
1300
    my_errno= HA_ERR_END_OF_FILE;
 
1301
    goto err;
 
1302
  }
 
1303
 
 
1304
  if (info->opt_flag & READ_CACHE_USED)
 
1305
  {
 
1306
    if (_mi_read_cache(&info->rec_cache, (uchar*) block_info.header,
 
1307
                       filepos, share->pack.ref_length,
 
1308
                       skip_deleted_blocks ? READING_NEXT : 0))
 
1309
      goto err;
 
1310
    b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
 
1311
                                   &info->rec_buff, -1, filepos);
 
1312
  }
 
1313
  else
 
1314
    b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
 
1315
                                   &info->rec_buff, info->dfile, filepos);
 
1316
  if (b_type)
 
1317
    goto err;                                   /* Error code is already set */
 
1318
#ifndef DBUG_OFF
 
1319
  if (block_info.rec_len > share->max_pack_length)
 
1320
  {
 
1321
    my_errno=HA_ERR_WRONG_IN_RECORD;
 
1322
    goto err;
 
1323
  }
 
1324
#endif
 
1325
 
 
1326
  if (info->opt_flag & READ_CACHE_USED)
 
1327
  {
 
1328
    if (_mi_read_cache(&info->rec_cache, (uchar*) info->rec_buff,
 
1329
                       block_info.filepos, block_info.rec_len,
 
1330
                       skip_deleted_blocks ? READING_NEXT : 0))
 
1331
      goto err;
 
1332
  }
 
1333
  else
 
1334
  {
 
1335
    if (my_read(info->dfile,(uchar*) info->rec_buff + block_info.offset,
 
1336
                block_info.rec_len-block_info.offset,
 
1337
                MYF(MY_NABP)))
 
1338
      goto err;
 
1339
  }
 
1340
  info->packed_length=block_info.rec_len;
 
1341
  info->lastpos=filepos;
 
1342
  info->nextpos=block_info.filepos+block_info.rec_len;
 
1343
  info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
 
1344
 
 
1345
  DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
1346
                                   info->rec_buff, block_info.rec_len));
 
1347
 err:
 
1348
  DBUG_RETURN(my_errno);
 
1349
}
 
1350
 
 
1351
 
 
1352
        /* Read and process header from a huff-record-file */
 
1353
 
 
1354
uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
 
1355
                             MI_BLOCK_INFO *info, uchar **rec_buff_p,
 
1356
                             File file, my_off_t filepos)
 
1357
{
 
1358
  uchar *header=info->header;
 
1359
  uint head_length, ref_length= 0;
 
1360
 
 
1361
  if (file >= 0)
 
1362
  {
 
1363
    ref_length=myisam->s->pack.ref_length;
 
1364
    /*
 
1365
      We can't use my_pread() here because mi_read_rnd_pack_record assumes
 
1366
      position is ok
 
1367
    */
 
1368
    VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
 
1369
    if (my_read(file, header,ref_length,MYF(MY_NABP)))
 
1370
      return BLOCK_FATAL_ERROR;
 
1371
    DBUG_DUMP("header",(uchar*) header,ref_length);
 
1372
  }
 
1373
  head_length= read_pack_length((uint) myisam->s->pack.version, header,
 
1374
                                &info->rec_len);
 
1375
  if (myisam->s->base.blobs)
 
1376
  {
 
1377
    head_length+= read_pack_length((uint) myisam->s->pack.version,
 
1378
                                   header + head_length, &info->blob_len);
 
1379
    /*
 
1380
      Ensure that the record buffer is big enough for the compressed
 
1381
      record plus all expanded blobs. [We do not have an extra buffer
 
1382
      for the resulting blobs. Sigh.]
 
1383
    */
 
1384
    if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
 
1385
                            rec_buff_p)))
 
1386
      return BLOCK_FATAL_ERROR;                 /* not enough memory */
 
1387
    bit_buff->blob_pos= (uchar*) *rec_buff_p + info->rec_len;
 
1388
    bit_buff->blob_end= bit_buff->blob_pos + info->blob_len;
 
1389
    myisam->blob_length=info->blob_len;
 
1390
  }
 
1391
  info->filepos=filepos+head_length;
 
1392
  if (file > 0)
 
1393
  {
 
1394
    info->offset=min(info->rec_len, ref_length - head_length);
 
1395
    memcpy(*rec_buff_p, header + head_length, info->offset);
 
1396
  }
 
1397
  return 0;
 
1398
}
 
1399
 
 
1400
 
 
1401
        /* rutines for bit buffer */
 
1402
        /* Note buffer must be 6 byte bigger than longest row */
 
1403
 
 
1404
static void init_bit_buffer(MI_BIT_BUFF *bit_buff, uchar *buffer, uint length)
 
1405
{
 
1406
  bit_buff->pos=buffer;
 
1407
  bit_buff->end=buffer+length;
 
1408
  bit_buff->bits=bit_buff->error=0;
 
1409
  bit_buff->current_byte=0;                     /* Avoid purify errors */
 
1410
}
 
1411
 
 
1412
static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff, uint count)
 
1413
{
 
1414
  uint tmp;
 
1415
  count-=bit_buff->bits;
 
1416
  tmp=(bit_buff->current_byte & mask[bit_buff->bits]) << count;
 
1417
  fill_buffer(bit_buff);
 
1418
  bit_buff->bits=BITS_SAVED - count;
 
1419
  return tmp+(bit_buff->current_byte >> (BITS_SAVED - count));
 
1420
}
 
1421
 
 
1422
        /* Fill in empty bit_buff->current_byte from buffer */
 
1423
        /* Sets bit_buff->error if buffer is exhausted */
 
1424
 
 
1425
static void fill_buffer(MI_BIT_BUFF *bit_buff)
 
1426
{
 
1427
  if (bit_buff->pos >= bit_buff->end)
 
1428
  {
 
1429
    bit_buff->error= 1;
 
1430
    bit_buff->current_byte=0;
 
1431
    return;
 
1432
  }
 
1433
#if BITS_SAVED == 64
 
1434
  bit_buff->current_byte=  ((((uint) ((uchar) bit_buff->pos[7]))) +
 
1435
                             (((uint) ((uchar) bit_buff->pos[6])) << 8) +
 
1436
                             (((uint) ((uchar) bit_buff->pos[5])) << 16) +
 
1437
                             (((uint) ((uchar) bit_buff->pos[4])) << 24) +
 
1438
                             ((ulonglong)
 
1439
                              ((((uint) ((uchar) bit_buff->pos[3]))) +
 
1440
                               (((uint) ((uchar) bit_buff->pos[2])) << 8) +
 
1441
                               (((uint) ((uchar) bit_buff->pos[1])) << 16) +
 
1442
                               (((uint) ((uchar) bit_buff->pos[0])) << 24)) << 32));
 
1443
  bit_buff->pos+=8;
 
1444
#else
 
1445
#if BITS_SAVED == 32
 
1446
  bit_buff->current_byte=  (((uint) ((uchar) bit_buff->pos[3])) +
 
1447
                             (((uint) ((uchar) bit_buff->pos[2])) << 8) +
 
1448
                             (((uint) ((uchar) bit_buff->pos[1])) << 16) +
 
1449
                             (((uint) ((uchar) bit_buff->pos[0])) << 24));
 
1450
  bit_buff->pos+=4;
 
1451
#else
 
1452
  bit_buff->current_byte=  (uint) (((uint) ((uchar) bit_buff->pos[1]))+
 
1453
                                    (((uint) ((uchar) bit_buff->pos[0])) << 8));
 
1454
  bit_buff->pos+=2;
 
1455
#endif
 
1456
#endif
 
1457
}
 
1458
 
 
1459
        /* Get number of bits neaded to represent value */
 
1460
 
 
1461
static uint max_bit(register uint value)
 
1462
{
 
1463
  register uint power=1;
 
1464
 
 
1465
  while ((value>>=1))
 
1466
    power++;
 
1467
  return (power);
 
1468
}
 
1469
 
 
1470
 
 
1471
/*****************************************************************************
 
1472
        Some redefined functions to handle files when we are using memmap
 
1473
*****************************************************************************/
 
1474
#ifdef HAVE_SYS_MMAN_H
 
1475
#include <sys/mman.h>
 
1476
#endif
 
1477
 
 
1478
#ifdef HAVE_MMAP
 
1479
 
 
1480
static int _mi_read_mempack_record(MI_INFO *info,my_off_t filepos,uchar *buf);
 
1481
static int _mi_read_rnd_mempack_record(MI_INFO*, uchar *,my_off_t, my_bool);
 
1482
 
 
1483
my_bool _mi_memmap_file(MI_INFO *info)
 
1484
{
 
1485
  MYISAM_SHARE *share=info->s;
 
1486
  DBUG_ENTER("mi_memmap_file");
 
1487
 
 
1488
  if (!info->s->file_map)
 
1489
  {
 
1490
    if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
 
1491
        share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
 
1492
    {
 
1493
      DBUG_PRINT("warning",("File isn't extended for memmap"));
 
1494
      DBUG_RETURN(0);
 
1495
    }
 
1496
    if (mi_dynmap_file(info, share->state.state.data_file_length))
 
1497
      DBUG_RETURN(0);
 
1498
  }
 
1499
  info->opt_flag|= MEMMAP_USED;
 
1500
  info->read_record= share->read_record= _mi_read_mempack_record;
 
1501
  share->read_rnd= _mi_read_rnd_mempack_record;
 
1502
  DBUG_RETURN(1);
 
1503
}
 
1504
 
 
1505
 
 
1506
void _mi_unmap_file(MI_INFO *info)
 
1507
{
 
1508
  VOID(my_munmap((char*) info->s->file_map, 
 
1509
                 (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
 
1510
}
 
1511
 
 
1512
 
 
1513
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
 
1514
                                         MI_BLOCK_INFO *info, uchar **rec_buff_p,
 
1515
                                         uchar *header)
 
1516
{
 
1517
  header+= read_pack_length((uint) myisam->s->pack.version, header,
 
1518
                            &info->rec_len);
 
1519
  if (myisam->s->base.blobs)
 
1520
  {
 
1521
    header+= read_pack_length((uint) myisam->s->pack.version, header,
 
1522
                              &info->blob_len);
 
1523
    /* mi_alloc_rec_buff sets my_errno on error */
 
1524
    if (!(mi_alloc_rec_buff(myisam, info->blob_len,
 
1525
                            rec_buff_p)))
 
1526
      return 0;                         /* not enough memory */
 
1527
    bit_buff->blob_pos= (uchar*) *rec_buff_p;
 
1528
    bit_buff->blob_end= (uchar*) *rec_buff_p + info->blob_len;
 
1529
  }
 
1530
  return header;
 
1531
}
 
1532
 
 
1533
 
 
1534
static int _mi_read_mempack_record(MI_INFO *info, my_off_t filepos, uchar *buf)
 
1535
{
 
1536
  MI_BLOCK_INFO block_info;
 
1537
  MYISAM_SHARE *share=info->s;
 
1538
  uchar *pos;
 
1539
  DBUG_ENTER("mi_read_mempack_record");
 
1540
 
 
1541
  if (filepos == HA_OFFSET_ERROR)
 
1542
    DBUG_RETURN(-1);                    /* _search() didn't find record */
 
1543
 
 
1544
  if (!(pos= (uchar*) _mi_mempack_get_block_info(info, &info->bit_buff,
 
1545
                                                &block_info, &info->rec_buff,
 
1546
                                                (uchar*) share->file_map+
 
1547
                                                filepos)))
 
1548
    DBUG_RETURN(-1);
 
1549
  DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
1550
                                  pos, block_info.rec_len));
 
1551
}
 
1552
 
 
1553
 
 
1554
/*ARGSUSED*/
 
1555
static int _mi_read_rnd_mempack_record(MI_INFO *info, uchar *buf,
 
1556
                                       register my_off_t filepos,
 
1557
                                       my_bool skip_deleted_blocks
 
1558
                                       __attribute__((unused)))
 
1559
{
 
1560
  MI_BLOCK_INFO block_info;
 
1561
  MYISAM_SHARE *share=info->s;
 
1562
  uchar *pos,*start;
 
1563
  DBUG_ENTER("_mi_read_rnd_mempack_record");
 
1564
 
 
1565
  if (filepos >= share->state.state.data_file_length)
 
1566
  {
 
1567
    my_errno=HA_ERR_END_OF_FILE;
 
1568
    goto err;
 
1569
  }
 
1570
  if (!(pos= (uchar*) _mi_mempack_get_block_info(info, &info->bit_buff,
 
1571
                                                &block_info, &info->rec_buff,
 
1572
                                                (uchar*)
 
1573
                                                (start=share->file_map+
 
1574
                                                 filepos))))
 
1575
    goto err;
 
1576
#ifndef DBUG_OFF
 
1577
  if (block_info.rec_len > info->s->max_pack_length)
 
1578
  {
 
1579
    my_errno=HA_ERR_WRONG_IN_RECORD;
 
1580
    goto err;
 
1581
  }
 
1582
#endif
 
1583
  info->packed_length=block_info.rec_len;
 
1584
  info->lastpos=filepos;
 
1585
  info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len;
 
1586
  info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
 
1587
 
 
1588
  DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
1589
                                   pos, block_info.rec_len));
 
1590
 err:
 
1591
  DBUG_RETURN(my_errno);
 
1592
}
 
1593
 
 
1594
#endif /* HAVE_MMAP */
 
1595
 
 
1596
        /* Save length of row */
 
1597
 
 
1598
uint save_pack_length(uint version, uchar *block_buff, ulong length)
 
1599
{
 
1600
  if (length < 254)
 
1601
  {
 
1602
    *(uchar*) block_buff= (uchar) length;
 
1603
    return 1;
 
1604
  }
 
1605
  if (length <= 65535)
 
1606
  {
 
1607
    *(uchar*) block_buff=254;
 
1608
    int2store(block_buff+1,(uint) length);
 
1609
    return 3;
 
1610
  }
 
1611
  *(uchar*) block_buff=255;
 
1612
  if (version == 1) /* old format */
 
1613
  {
 
1614
    DBUG_ASSERT(length <= 0xFFFFFF);
 
1615
    int3store(block_buff + 1, (ulong) length);
 
1616
    return 4;
 
1617
  }
 
1618
  else
 
1619
  {
 
1620
    int4store(block_buff + 1, (ulong) length);
 
1621
    return 5;
 
1622
  }
 
1623
}
 
1624
 
 
1625
 
 
1626
uint read_pack_length(uint version, const uchar *buf, ulong *length)
 
1627
{
 
1628
  if (buf[0] < 254)
 
1629
  {
 
1630
    *length= buf[0];
 
1631
    return 1;
 
1632
  }
 
1633
  else if (buf[0] == 254)
 
1634
  {
 
1635
    *length= uint2korr(buf + 1);
 
1636
    return 3;
 
1637
  }
 
1638
  if (version == 1) /* old format */
 
1639
  {
 
1640
    *length= uint3korr(buf + 1);
 
1641
    return 4;
 
1642
  }
 
1643
  else
 
1644
  {
 
1645
    *length= uint4korr(buf + 1);
 
1646
    return 5;
 
1647
  }
 
1648
}
 
1649
 
 
1650
 
 
1651
uint calc_pack_length(uint version, ulong length)
 
1652
{
 
1653
  return (length < 254) ? 1 : (length < 65536) ? 3 : (version == 1) ? 4 : 5;
 
1654
}