~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

  • Committer: Lee Bieber
  • Date: 2010-08-21 22:42:44 UTC
  • mto: (1727.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1728.
  • Revision ID: lbieber@kalebral-2.local-20100821224244-kh3gmsvi45dlbuu1
For the feature request (https://blueprints.launchpad.net/drizzle/+spec/limit-maximum-sort-size) 
that is requesting the ability to cap various buffers, we first tried setting the join buffer to 
1 to see how that would affect the test results and expose test results that need to 
sorted (by adding --sorted_result). 

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "heap_priv.h"
17
17
#include <drizzled/error.h>
60
60
    hp_panic(HA_PANIC_CLOSE);
61
61
  }
62
62
 
63
 
  virtual Cursor *create(Table &table)
 
63
  virtual Cursor *create(TableShare &table)
64
64
  {
65
65
    return new ha_heap(*this, table);
66
66
  }
93
93
                           const TableIdentifier &identifier,
94
94
                           message::Table &table_message);
95
95
 
 
96
  /* Temp only engine, so do not return values. */
 
97
  void doGetTableNames(CachedDirectory &, const SchemaIdentifier& , set<string>&) { };
 
98
 
96
99
  uint32_t max_supported_keys()          const { return MAX_KEY; }
97
100
  uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
98
101
 
99
 
  uint32_t index_flags(enum  ha_key_alg ) const
 
102
  uint32_t index_flags(enum  ha_key_alg algorithm) const
100
103
  {
101
 
    return ( HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
 
104
    return ((algorithm == HA_KEY_ALG_BTREE) ?
 
105
            HA_READ_NEXT |
 
106
            HA_READ_PREV |
 
107
            HA_READ_ORDER |
 
108
            HA_READ_RANGE :
 
109
            HA_ONLY_WHOLE_INDEX |
 
110
            HA_KEY_SCAN_NOT_ROR);
102
111
  }
103
112
 
104
113
  bool doDoesTableExist(Session& session, const TableIdentifier &identifier);
105
114
  void doGetTableIdentifiers(CachedDirectory &directory,
106
115
                             const SchemaIdentifier &schema_identifier,
107
 
                             TableIdentifier::vector &set_of_identifiers);
 
116
                             TableIdentifiers &set_of_identifiers);
108
117
};
109
118
 
110
119
void HeapEngine::doGetTableIdentifiers(CachedDirectory&,
111
120
                                       const SchemaIdentifier&,
112
 
                                       TableIdentifier::vector&)
 
121
                                       TableIdentifiers&)
113
122
{
114
123
}
115
124
 
116
125
bool HeapEngine::doDoesTableExist(Session& session, const TableIdentifier &identifier)
117
126
{
118
 
  return session.getMessageCache().doesTableMessageExist(identifier);
 
127
  return session.doesTableMessageExist(identifier);
119
128
}
120
129
 
121
130
int HeapEngine::doGetTableDefinition(Session &session,
122
131
                                     const TableIdentifier &identifier,
123
132
                                     message::Table &table_proto)
124
133
{
125
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
 
134
  if (session.getTableMessage(identifier, table_proto))
126
135
    return EEXIST;
127
136
 
128
137
  return ENOENT;
133
142
*/
134
143
int HeapEngine::doDropTable(Session &session, const TableIdentifier &identifier)
135
144
{
136
 
  session.getMessageCache().removeTableMessage(identifier);
 
145
  session.removeTableMessage(identifier);
137
146
 
138
147
  int error= heap_delete_table(identifier.getPath().c_str());
139
148
 
158
167
*****************************************************************************/
159
168
 
160
169
ha_heap::ha_heap(plugin::StorageEngine &engine_arg,
161
 
                 Table &table_arg)
 
170
                 TableShare &table_arg)
162
171
  :Cursor(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
163
172
  internal_table(0)
164
173
{}
176
185
*/
177
186
#define MEMORY_STATS_UPDATE_THRESHOLD 10
178
187
 
179
 
int ha_heap::doOpen(const drizzled::TableIdentifier &identifier, int mode, uint32_t test_if_locked)
 
188
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
180
189
{
181
 
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(identifier.getPath().c_str(), mode)) && errno == ENOENT))
 
190
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && errno == ENOENT))
182
191
  {
183
192
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
184
193
    file= 0;
185
194
    HP_SHARE *internal_share= NULL;
186
195
    message::Table create_proto;
187
196
 
188
 
    if (not heap_storage_engine->heap_create_table(getTable()->in_use,
189
 
                                                   identifier.getPath().c_str(),
190
 
                                                   getTable(),
191
 
                                                   internal_table,
192
 
                                                   create_proto,
193
 
                                                   &internal_share))
 
197
    if (!heap_storage_engine->heap_create_table(table->in_use, name, table,
 
198
                                                internal_table,
 
199
                                                create_proto,
 
200
                                                &internal_share))
194
201
    {
195
202
        file= internal_table ?
196
203
          heap_open_from_share(internal_share, mode) :
240
247
 
241
248
Cursor *ha_heap::clone(memory::Root *)
242
249
{
243
 
  Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
244
 
  TableIdentifier identifier(getTable()->getShare()->getSchemaName(),
245
 
                             getTable()->getShare()->getTableName(),
246
 
                             getTable()->getShare()->getPath());
 
250
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*(table->getMutableShare()));
 
251
  TableIdentifier identifier(table->getShare()->getSchemaName(),
 
252
                             table->getShare()->getTableName(),
 
253
                             table->getShare()->getPath());
247
254
 
248
 
  if (new_handler && !new_handler->ha_open(identifier, getTable()->db_stat,
 
255
  if (new_handler && !new_handler->ha_open(identifier, table, file->getShare()->name.c_str(), table->db_stat,
249
256
                                           HA_OPEN_IGNORE_IF_LOCKED))
250
257
    return new_handler;
251
258
  return NULL;
252
259
}
253
260
 
254
261
 
255
 
const char *ha_heap::index_type(uint32_t )
 
262
const char *ha_heap::index_type(uint32_t inx)
256
263
{
257
 
  return ("HASH");
 
264
  return ((table_share->getKeyInfo(inx).algorithm == HA_KEY_ALG_BTREE) ?
 
265
          "BTREE" : "HASH");
258
266
}
259
267
 
260
268
 
276
284
 
277
285
void ha_heap::set_keys_for_scanning(void)
278
286
{
 
287
  btree_keys.reset();
 
288
  for (uint32_t i= 0 ; i < table->getShare()->sizeKeys() ; i++)
 
289
  {
 
290
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
 
291
      btree_keys.set(i);
 
292
  }
279
293
}
280
294
 
281
295
 
282
296
void ha_heap::update_key_stats()
283
297
{
284
 
  for (uint32_t i= 0; i < getTable()->getShare()->sizeKeys(); i++)
 
298
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++)
285
299
  {
286
 
    KeyInfo *key= &getTable()->key_info[i];
287
 
 
 
300
    KeyInfo *key= &table->key_info[i];
288
301
    if (!key->rec_per_key)
289
302
      continue;
290
 
 
 
303
    if (key->algorithm != HA_KEY_ALG_BTREE)
291
304
    {
292
305
      if (key->flags & HA_NOSAME)
293
306
        key->rec_per_key[key->key_parts-1]= 1;
310
323
int ha_heap::doInsertRecord(unsigned char * buf)
311
324
{
312
325
  int res;
313
 
  if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
 
326
  if (table->next_number_field && buf == table->getInsertRecord())
314
327
  {
315
328
    if ((res= update_auto_increment()))
316
329
      return res;
350
363
  int res;
351
364
 
352
365
  res= heap_delete(file,buf);
353
 
  if (!res && getTable()->getShare()->getType() == message::Table::STANDARD &&
 
366
  if (!res && table->getShare()->getType() == message::Table::STANDARD &&
354
367
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->getShare()->records)
355
368
  {
356
369
    /*
369
382
  assert(inited==INDEX);
370
383
  ha_statistic_increment(&system_status_var::ha_read_key_count);
371
384
  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
372
 
  getTable()->status = error ? STATUS_NOT_FOUND : 0;
 
385
  table->status = error ? STATUS_NOT_FOUND : 0;
373
386
  return error;
374
387
}
375
388
 
380
393
  ha_statistic_increment(&system_status_var::ha_read_key_count);
381
394
  int error= heap_rkey(file, buf, active_index, key, keypart_map,
382
395
                       HA_READ_PREFIX_LAST);
383
 
  getTable()->status= error ? STATUS_NOT_FOUND : 0;
 
396
  table->status= error ? STATUS_NOT_FOUND : 0;
384
397
  return error;
385
398
}
386
399
 
390
403
{
391
404
  ha_statistic_increment(&system_status_var::ha_read_key_count);
392
405
  int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
393
 
  getTable()->status = error ? STATUS_NOT_FOUND : 0;
 
406
  table->status = error ? STATUS_NOT_FOUND : 0;
394
407
  return error;
395
408
}
396
409
 
399
412
  assert(inited==INDEX);
400
413
  ha_statistic_increment(&system_status_var::ha_read_next_count);
401
414
  int error=heap_rnext(file,buf);
402
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
415
  table->status=error ? STATUS_NOT_FOUND: 0;
403
416
  return error;
404
417
}
405
418
 
408
421
  assert(inited==INDEX);
409
422
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
410
423
  int error=heap_rprev(file,buf);
411
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
424
  table->status=error ? STATUS_NOT_FOUND: 0;
412
425
  return error;
413
426
}
414
427
 
417
430
  assert(inited==INDEX);
418
431
  ha_statistic_increment(&system_status_var::ha_read_first_count);
419
432
  int error=heap_rfirst(file, buf, active_index);
420
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
433
  table->status=error ? STATUS_NOT_FOUND: 0;
421
434
  return error;
422
435
}
423
436
 
426
439
  assert(inited==INDEX);
427
440
  ha_statistic_increment(&system_status_var::ha_read_last_count);
428
441
  int error=heap_rlast(file, buf, active_index);
429
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
442
  table->status=error ? STATUS_NOT_FOUND: 0;
430
443
  return error;
431
444
}
432
445
 
439
452
{
440
453
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
441
454
  int error=heap_scan(file, buf);
442
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
455
  table->status=error ? STATUS_NOT_FOUND: 0;
443
456
  return error;
444
457
}
445
458
 
450
463
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
451
464
  memcpy(&heap_position, pos, sizeof(HEAP_PTR));
452
465
  error=heap_rrnd(file, buf, heap_position);
453
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
466
  table->status=error ? STATUS_NOT_FOUND: 0;
454
467
  return error;
455
468
}
456
469
 
499
512
int ha_heap::delete_all_rows()
500
513
{
501
514
  heap_clear(file);
502
 
  if (getTable()->getShare()->getType() == message::Table::STANDARD)
 
515
  if (table->getShare()->getType() == message::Table::STANDARD)
503
516
  {
504
517
    /*
505
518
       We can perform this safely since only one writer at the time is
626
639
 
627
640
int HeapEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
628
641
{
629
 
  session.getMessageCache().renameTableMessage(from, to);
 
642
  session.renameTableMessage(from, to);
630
643
  return heap_rename(from.getPath().c_str(), to.getPath().c_str());
631
644
}
632
645
 
634
647
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
635
648
                                  key_range *max_key)
636
649
{
637
 
  KeyInfo *key= &getTable()->key_info[inx];
 
650
  KeyInfo *key= &table->key_info[inx];
 
651
  if (key->algorithm == HA_KEY_ALG_BTREE)
 
652
    return hp_rb_records_in_range(file, inx, min_key, max_key);
638
653
 
639
654
  if (!min_key || !max_key ||
640
655
      min_key->length != max_key->length ||
667
682
 
668
683
  if (error == 0)
669
684
  {
670
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
685
    session.storeTableMessage(identifier, create_proto);
671
686
  }
672
687
 
673
688
  return error;
685
700
  uint32_t auto_key= 0, auto_key_type= 0;
686
701
  uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
687
702
  uint32_t column_count= table_arg->getShare()->sizeFields();
 
703
  std::vector<HP_COLUMNDEF> columndef;
688
704
  std::vector<HP_KEYDEF> keydef;
 
705
  char buff[FN_REFLEN];
689
706
  int error;
690
707
  bool found_real_auto_increment= 0;
691
708
 
699
716
  if (num_rows > UINT32_MAX)
700
717
    return -1;
701
718
 
 
719
  columndef.resize(column_count);
 
720
 
 
721
  for (uint32_t column_idx= 0; column_idx < column_count; column_idx++)
 
722
  {
 
723
    Field* field= *(table_arg->getFields() + column_idx);
 
724
    HP_COLUMNDEF* column= &columndef[column_idx];
 
725
    column->type= (uint16_t)field->type();
 
726
    column->length= field->pack_length();
 
727
    column->offset= field->offset(field->getTable()->getInsertRecord());
 
728
 
 
729
    if (field->null_bit)
 
730
    {
 
731
      column->null_bit= field->null_bit;
 
732
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->getInsertRecord());
 
733
    }
 
734
    else
 
735
    {
 
736
      column->null_bit= 0;
 
737
      column->null_pos= 0;
 
738
    }
 
739
 
 
740
    if (field->type() == DRIZZLE_TYPE_VARCHAR)
 
741
    {
 
742
      column->length_bytes= (uint8_t)(((Field_varstring*)field)->length_bytes);
 
743
    }
 
744
    else
 
745
    {
 
746
      column->length_bytes= 0;
 
747
    }
 
748
  }
 
749
 
702
750
  for (key= parts= 0; key < keys; key++)
703
751
    parts+= table_arg->key_info[key].key_parts;
704
752
 
717
765
    keydef[key].flag=      (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
718
766
    keydef[key].seg=       seg;
719
767
 
720
 
    mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
 
768
    switch (pos->algorithm) {
 
769
    case HA_KEY_ALG_UNDEF:
 
770
    case HA_KEY_ALG_HASH:
 
771
      keydef[key].algorithm= HA_KEY_ALG_HASH;
 
772
      mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
 
773
      break;
 
774
    case HA_KEY_ALG_BTREE:
 
775
      keydef[key].algorithm= HA_KEY_ALG_BTREE;
 
776
      mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
 
777
      break;
 
778
    default:
 
779
      assert(0); // cannot happen
 
780
    }
721
781
 
722
782
    for (; key_part != key_part_end; key_part++, seg++)
723
783
    {
724
784
      Field *field= key_part->field;
725
785
 
 
786
      if (pos->algorithm == HA_KEY_ALG_BTREE)
 
787
      {
 
788
        seg->type= field->key_type();
 
789
      }
 
790
      else
726
791
      {
727
792
        if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT &&
728
793
            seg->type != HA_KEYTYPE_VARTEXT1 &&
738
803
      next_field_pos= seg->start + seg->length;
739
804
      if (field->type() == DRIZZLE_TYPE_VARCHAR)
740
805
      {
741
 
        next_field_pos+= (uint8_t)(((Field_varstring*)field)->pack_length_no_ptr());
 
806
        next_field_pos+= (uint8_t)(((Field_varstring*)field)->length_bytes);
742
807
      }
743
808
 
744
809
      if (next_field_pos > key_part_size) {
770
835
        auto_key= key+ 1;
771
836
        auto_key_type= field->key_type();
772
837
      }
773
 
      if ((uint)field->position() + 1 > max_key_fieldnr)
 
838
      if ((uint)field->field_index + 1 > max_key_fieldnr)
774
839
      {
775
840
        /* Do not use seg->fieldnr as it's not reliable in case of temp tables */
776
 
        max_key_fieldnr= field->position() + 1;
 
841
        max_key_fieldnr= field->field_index + 1;
777
842
      }
778
843
    }
779
844
  }
800
865
  hp_create_info.with_auto_increment= found_real_auto_increment;
801
866
  hp_create_info.internal_table= internal_table;
802
867
  hp_create_info.max_chunk_size= table_arg->getShare()->block_size;
 
868
  hp_create_info.is_dynamic= false;
803
869
 
804
 
  error= heap_create(table_name,
805
 
                     keys, &keydef[0],
806
 
                     column_count,
807
 
                     key_part_size,
808
 
                     table_arg->getShare()->getRecordLength(), mem_per_row_keys,
809
 
                     static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
810
 
                     0, // Factor out MIN
811
 
                     &hp_create_info, internal_share);
 
870
  error= heap_create(internal::fn_format(buff,table_name,"","",
 
871
                              MY_REPLACE_EXT|MY_UNPACK_FILENAME),
 
872
                    keys, &keydef[0],
 
873
                    column_count, &columndef[0],
 
874
                    max_key_fieldnr, key_part_size,
 
875
                    table_arg->getShare()->getRecordLength(), mem_per_row_keys,
 
876
                    static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
 
877
                    0, // Factor out MIN
 
878
                    &hp_create_info, internal_share);
812
879
 
813
880
  return (error);
814
881
}