~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_packrec.c

Removed/replaced DBUG symbols and standardized TRUE/FALSE

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