~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_packrec.c

  • Committer: Brian Aker
  • Date: 2008-07-16 21:28:26 UTC
  • mfrom: (77.3.28 glibclient)
  • Revision ID: brian@tangent.org-20080716212826-p44t3u6v1zb0dmxg
Merge from Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
141
141
  uchar header[HEAD_LENGTH];
142
142
  MYISAM_SHARE *share=info->s;
143
143
  MI_BIT_BUFF bit_buff;
144
 
  DBUG_ENTER("_mi_read_pack_info");
145
144
 
146
145
  if (myisam_quick_table_bits < 4)
147
146
    myisam_quick_table_bits=4;
177
176
  share->base.min_block_length=share->min_pack_length+1;
178
177
  if (share->min_pack_length > 254)
179
178
    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
179
 
191
180
  /*
192
181
    Memory segment #1:
234
223
    share->rec[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
235
224
                                                                huff_tree_bits);
236
225
    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
226
  }
241
227
  skip_to_next_byte(&bit_buff);
242
228
  /*
285
271
  if (bit_buff.error || bit_buff.pos < bit_buff.end)
286
272
    goto err3;
287
273
 
288
 
  DBUG_RETURN(0);
 
274
  return(0);
289
275
 
290
276
err3:
291
277
  my_errno=HA_ERR_WRONG_IN_RECORD;
294
280
err1:
295
281
  my_free((uchar*) share->decode_trees,MYF(0));
296
282
err0:
297
 
  DBUG_RETURN(1);
 
283
  return(1);
298
284
}
299
285
 
300
286
 
323
309
  uint min_chr,elements,char_bits,offset_bits,size,intervall_length,table_bits,
324
310
  next_free_offset;
325
311
  uint16 *ptr,*end;
326
 
  DBUG_ENTER("read_huff_table");
327
312
 
328
313
  if (!get_bits(bit_buff,1))
329
314
  {
334
319
    offset_bits=get_bits(bit_buff,5);
335
320
    intervall_length=0;
336
321
    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
322
    if (elements > 256)
343
323
    {
344
 
      DBUG_PRINT("error", ("ERROR: illegal number of tree elements: %u",
345
 
                           elements));
346
 
      DBUG_RETURN(1);
 
324
      return(1);
347
325
    }
348
326
  }
349
327
  else
356
334
    offset_bits=get_bits(bit_buff,5);
357
335
    decode_tree->quick_table_bits=0;
358
336
    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
337
  }
365
338
  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
339
 
370
340
  for (end=ptr+size ; ptr < end ; ptr++)
371
341
  {
374
344
      *ptr= (uint16) get_bits(bit_buff,offset_bits);
375
345
      if ((ptr + *ptr >= end) || !*ptr)
376
346
      {
377
 
        DBUG_PRINT("error", ("ERROR: illegal pointer in decode tree"));
378
 
        DBUG_RETURN(1);
 
347
        return(1);
379
348
      }
380
349
    }
381
350
    else
391
360
    /* Find longest Huffman code from begin to end of tree in bits. */
392
361
    table_bits= find_longest_bitstream(tmp_buff, ptr);
393
362
    if (table_bits >= OFFSET_TABLE_SIZE)
394
 
      DBUG_RETURN(1);
 
363
      return(1);
395
364
    if (table_bits > myisam_quick_table_bits)
396
365
      table_bits=myisam_quick_table_bits;
397
 
    DBUG_PRINT("info", ("table bits:            %u", table_bits));
398
366
 
399
367
    next_free_offset= (1 << table_bits);
400
368
    make_quick_table(*decode_table,tmp_buff,&next_free_offset,0,table_bits,
417
385
    bit_buff->pos+=intervall_length;
418
386
    bit_buff->bits=0;
419
387
  }
420
 
  DBUG_RETURN(0);
 
388
  return(0);
421
389
}
422
390
 
423
391
 
464
432
                             uint *next_free_offset, uint value, uint bits,
465
433
                             uint max_bits)
466
434
{
467
 
  DBUG_ENTER("make_quick_table");
468
 
 
469
435
  /*
470
436
    When down the table to the requested maximum, copy the rest of the
471
437
    Huffman table.
483
449
    */
484
450
    *next_free_offset= copy_decode_table(to_table, *next_free_offset,
485
451
                                         decode_table);
486
 
    DBUG_VOID_RETURN;
 
452
    return;
487
453
  }
488
454
 
489
455
  /* Descent on the left side. Left side bits are clear (0). */
522
488
    fill_quick_table(to_table + value, bits, max_bits, (uint) *decode_table);
523
489
  }
524
490
 
525
 
  DBUG_VOID_RETURN;
 
491
  return;
526
492
}
527
493
 
528
494
 
554
520
                             uint value)
555
521
{
556
522
  uint16 *end;
557
 
  DBUG_ENTER("fill_quick_table");
558
523
 
559
524
  /*
560
525
    Bits 1..8 of value represent the decoded byte value.
567
532
  {
568
533
    *table= (uint16) value;
569
534
  }
570
 
  DBUG_VOID_RETURN;
 
535
  return;
571
536
}
572
537
 
573
538
 
591
556
                              uint16 *decode_table)
592
557
{
593
558
  uint prev_offset= offset;
594
 
  DBUG_ENTER("copy_decode_table");
595
559
 
596
560
  /* Descent on the left side. */
597
561
  if (!(*decode_table & IS_CHAR))
623
587
    /* Copy the byte value. */
624
588
    to_pos[prev_offset+1]= *decode_table;
625
589
  }
626
 
  DBUG_RETURN(offset);
 
590
  return(offset);
627
591
}
628
592
 
629
593
 
661
625
    uint16 *next= table + *table;
662
626
    if (next > end || next == table)
663
627
    {
664
 
      DBUG_PRINT("error", ("ERROR: illegal pointer in decode tree"));
665
628
      return OFFSET_TABLE_SIZE;
666
629
    }
667
630
    length= find_longest_bitstream(next, end) + 1;
672
635
    uint16 *next= table + *table;
673
636
    if (next > end || next == table)
674
637
    {
675
 
      DBUG_PRINT("error", ("ERROR: illegal pointer in decode tree"));
676
638
      return OFFSET_TABLE_SIZE;
677
639
    }
678
640
    length2= find_longest_bitstream(next, end) + 1;
700
662
{
701
663
  MI_BLOCK_INFO block_info;
702
664
  File file;
703
 
  DBUG_ENTER("mi_read_pack_record");
704
665
 
705
666
  if (filepos == HA_OFFSET_ERROR)
706
 
    DBUG_RETURN(-1);                    /* _search() didn't find record */
 
667
    return(-1);                 /* _search() didn't find record */
707
668
 
708
669
  file=info->dfile;
709
670
  if (_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
713
674
              block_info.rec_len - block_info.offset, MYF(MY_NABP)))
714
675
    goto panic;
715
676
  info->update|= HA_STATE_AKTIV;
716
 
  DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
677
  return(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
717
678
                                  info->rec_buff, block_info.rec_len));
718
679
panic:
719
680
  my_errno=HA_ERR_WRONG_IN_RECORD;
720
681
err:
721
 
  DBUG_RETURN(-1);
 
682
  return(-1);
722
683
}
723
684
 
724
685
 
730
691
  register MI_COLUMNDEF *end;
731
692
  MI_COLUMNDEF *current_field;
732
693
  MYISAM_SHARE *share=info->s;
733
 
  DBUG_ENTER("_mi_pack_rec_unpack");
734
694
 
735
695
  init_bit_buffer(bit_buff, (uchar*) from, reclength);
736
696
 
744
704
  }
745
705
  if (!bit_buff->error &&
746
706
      bit_buff->pos - bit_buff->bits / 8 == bit_buff->end)
747
 
    DBUG_RETURN(0);
 
707
    return(0);
748
708
  info->update&= ~HA_STATE_AKTIV;
749
 
  DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD);
 
709
  return(my_errno=HA_ERR_WRONG_IN_RECORD);
750
710
} /* _mi_pack_rec_unpack */
751
711
 
752
712
 
1292
1252
  uint b_type;
1293
1253
  MI_BLOCK_INFO block_info;
1294
1254
  MYISAM_SHARE *share=info->s;
1295
 
  DBUG_ENTER("_mi_read_rnd_pack_record");
1296
1255
 
1297
1256
  if (filepos >= info->state->data_file_length)
1298
1257
  {
1314
1273
                                   &info->rec_buff, info->dfile, filepos);
1315
1274
  if (b_type)
1316
1275
    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
1276
 
1325
1277
  if (info->opt_flag & READ_CACHE_USED)
1326
1278
  {
1341
1293
  info->nextpos=block_info.filepos+block_info.rec_len;
1342
1294
  info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
1343
1295
 
1344
 
  DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
1296
  return (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
1345
1297
                                   info->rec_buff, block_info.rec_len));
1346
1298
 err:
1347
 
  DBUG_RETURN(my_errno);
 
1299
  return(my_errno);
1348
1300
}
1349
1301
 
1350
1302
 
1367
1319
    VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
1368
1320
    if (my_read(file, header,ref_length,MYF(MY_NABP)))
1369
1321
      return BLOCK_FATAL_ERROR;
1370
 
    DBUG_DUMP("header",(uchar*) header,ref_length);
1371
1322
  }
1372
1323
  head_length= read_pack_length((uint) myisam->s->pack.version, header,
1373
1324
                                &info->rec_len);
1482
1433
my_bool _mi_memmap_file(MI_INFO *info)
1483
1434
{
1484
1435
  MYISAM_SHARE *share=info->s;
1485
 
  DBUG_ENTER("mi_memmap_file");
1486
1436
 
1487
1437
  if (!info->s->file_map)
1488
1438
  {
1489
1439
    if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
1490
1440
        share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
1491
1441
    {
1492
 
      DBUG_PRINT("warning",("File isn't extended for memmap"));
1493
 
      DBUG_RETURN(0);
 
1442
      return(0);
1494
1443
    }
1495
1444
    if (mi_dynmap_file(info, share->state.state.data_file_length))
1496
 
      DBUG_RETURN(0);
 
1445
      return(0);
1497
1446
  }
1498
1447
  info->opt_flag|= MEMMAP_USED;
1499
1448
  info->read_record= share->read_record= _mi_read_mempack_record;
1500
1449
  share->read_rnd= _mi_read_rnd_mempack_record;
1501
 
  DBUG_RETURN(1);
 
1450
  return(1);
1502
1451
}
1503
1452
 
1504
1453
 
1535
1484
  MI_BLOCK_INFO block_info;
1536
1485
  MYISAM_SHARE *share=info->s;
1537
1486
  uchar *pos;
1538
 
  DBUG_ENTER("mi_read_mempack_record");
1539
1487
 
1540
1488
  if (filepos == HA_OFFSET_ERROR)
1541
 
    DBUG_RETURN(-1);                    /* _search() didn't find record */
 
1489
    return(-1);                 /* _search() didn't find record */
1542
1490
 
1543
1491
  if (!(pos= (uchar*) _mi_mempack_get_block_info(info, &info->bit_buff,
1544
1492
                                                &block_info, &info->rec_buff,
1545
1493
                                                (uchar*) share->file_map+
1546
1494
                                                filepos)))
1547
 
    DBUG_RETURN(-1);
1548
 
  DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
1495
    return(-1);
 
1496
  return(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
1549
1497
                                  pos, block_info.rec_len));
1550
1498
}
1551
1499
 
1559
1507
  MI_BLOCK_INFO block_info;
1560
1508
  MYISAM_SHARE *share=info->s;
1561
1509
  uchar *pos,*start;
1562
 
  DBUG_ENTER("_mi_read_rnd_mempack_record");
1563
1510
 
1564
1511
  if (filepos >= share->state.state.data_file_length)
1565
1512
  {
1572
1519
                                                (start=share->file_map+
1573
1520
                                                 filepos))))
1574
1521
    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
1522
  info->packed_length=block_info.rec_len;
1583
1523
  info->lastpos=filepos;
1584
1524
  info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len;
1585
1525
  info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
1586
1526
 
1587
 
  DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
 
1527
  return (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
1588
1528
                                   pos, block_info.rec_len));
1589
1529
 err:
1590
 
  DBUG_RETURN(my_errno);
 
1530
  return(my_errno);
1591
1531
}
1592
1532
 
1593
1533
#endif /* HAVE_MMAP */
1610
1550
  *(uchar*) block_buff=255;
1611
1551
  if (version == 1) /* old format */
1612
1552
  {
1613
 
    DBUG_ASSERT(length <= 0xFFFFFF);
 
1553
    assert(length <= 0xFFFFFF);
1614
1554
    int3store(block_buff + 1, (ulong) length);
1615
1555
    return 4;
1616
1556
  }