~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

  • Committer: Brian Aker
  • Date: 2010-07-09 20:51:34 UTC
  • mfrom: (1643.4.3 drizzle)
  • Revision ID: brian@gaz-20100709205134-ru4s0889youfrmm5
Merge of Patrick

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#include <drizzled/error.h>
18
18
#include <drizzled/table.h>
19
19
#include <drizzled/session.h>
20
 
#include <drizzled/current_session.h>
21
20
#include <drizzled/field/timestamp.h>
22
21
#include <drizzled/field/varstring.h>
23
22
#include "drizzled/plugin/daemon.h"
74
73
 
75
74
  int doCreateTable(Session &session,
76
75
                    Table &table_arg,
77
 
                    drizzled::TableIdentifier &identifier,
 
76
                    const TableIdentifier &identifier,
78
77
                    message::Table &create_proto);
79
78
 
80
79
  /* For whatever reason, internal tables can be created by Cursor::open()
88
87
                        message::Table &create_proto,
89
88
                        HP_SHARE **internal_share);
90
89
 
91
 
  int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
 
90
  int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
92
91
 
93
 
  int doDropTable(Session&, TableIdentifier &identifier);
 
92
  int doDropTable(Session&, const TableIdentifier &identifier);
94
93
 
95
94
  int doGetTableDefinition(Session& session,
96
 
                           TableIdentifier &identifier,
 
95
                           const TableIdentifier &identifier,
97
96
                           message::Table &table_message);
98
97
 
99
98
  /* Temp only engine, so do not return values. */
100
 
  void doGetTableNames(CachedDirectory &, SchemaIdentifier& , set<string>&) { };
 
99
  void doGetTableNames(CachedDirectory &, const SchemaIdentifier& , set<string>&) { };
101
100
 
102
101
  uint32_t max_supported_keys()          const { return MAX_KEY; }
103
102
  uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
113
112
            HA_KEY_SCAN_NOT_ROR);
114
113
  }
115
114
 
116
 
  bool doDoesTableExist(Session& session, TableIdentifier &identifier);
117
 
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
118
 
                             drizzled::SchemaIdentifier &schema_identifier,
119
 
                             drizzled::TableIdentifiers &set_of_identifiers);
 
115
  bool doDoesTableExist(Session& session, const TableIdentifier &identifier);
 
116
  void doGetTableIdentifiers(CachedDirectory &directory,
 
117
                             const SchemaIdentifier &schema_identifier,
 
118
                             TableIdentifiers &set_of_identifiers);
120
119
};
121
120
 
122
 
void HeapEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
123
 
                                       drizzled::SchemaIdentifier&,
124
 
                                       drizzled::TableIdentifiers&)
 
121
void HeapEngine::doGetTableIdentifiers(CachedDirectory&,
 
122
                                       const SchemaIdentifier&,
 
123
                                       TableIdentifiers&)
125
124
{
126
125
}
127
126
 
128
 
bool HeapEngine::doDoesTableExist(Session& session, TableIdentifier &identifier)
 
127
bool HeapEngine::doDoesTableExist(Session& session, const TableIdentifier &identifier)
129
128
{
130
129
  return session.doesTableMessageExist(identifier);
131
130
}
132
131
 
133
132
int HeapEngine::doGetTableDefinition(Session &session,
134
 
                                     TableIdentifier &identifier,
 
133
                                     const TableIdentifier &identifier,
135
134
                                     message::Table &table_proto)
136
135
{
137
136
  if (session.getTableMessage(identifier, table_proto))
143
142
  We have to ignore ENOENT entries as the MEMORY table is created on open and
144
143
  not when doing a CREATE on the table.
145
144
*/
146
 
int HeapEngine::doDropTable(Session &session, TableIdentifier &identifier)
 
145
int HeapEngine::doDropTable(Session &session, const TableIdentifier &identifier)
147
146
{
148
147
  session.removeTableMessage(identifier);
149
148
 
157
156
 
158
157
static HeapEngine *heap_storage_engine= NULL;
159
158
 
160
 
static int heap_init(plugin::Context &context)
 
159
static int heap_init(module::Context &context)
161
160
{
162
161
  heap_storage_engine= new HeapEngine(engine_name);
163
162
  context.add(heap_storage_engine);
199
198
    HP_SHARE *internal_share= NULL;
200
199
    message::Table create_proto;
201
200
 
202
 
    if (!heap_storage_engine->heap_create_table(ha_session(), name, table,
 
201
    if (!heap_storage_engine->heap_create_table(table->in_use, name, table,
203
202
                                                internal_table,
204
203
                                                create_proto,
205
204
                                                &internal_share))
214
213
        hp_free(internal_share);
215
214
        pthread_mutex_unlock(&THR_LOCK_heap);
216
215
      }
217
 
      implicit_emptied= 1;
218
216
    }
219
217
  }
220
218
  ref_length= sizeof(HEAP_PTR);
230
228
      ha_heap::info(), which is always called before key statistics are
231
229
      used.
232
230
    */
233
 
    key_stat_version= file->s->key_stat_version-1;
 
231
    key_stat_version= file->s->key_stat_version - 1;
234
232
  }
235
233
  return (file ? 0 : 1);
236
234
}
246
244
 
247
245
  DESCRIPTION
248
246
    Do same as default implementation but use file->s->name instead of
249
 
    table->s->path. This is needed by Windows where the clone() call sees
250
 
    '/'-delimited path in table->s->path, while ha_peap::open() was called
 
247
    table->getShare()->path. This is needed by Windows where the clone() call sees
 
248
    '/'-delimited path in table->getShare()->path, while ha_peap::open() was called
251
249
    with '\'-delimited path.
252
250
*/
253
251
 
254
252
Cursor *ha_heap::clone(memory::Root *mem_root)
255
253
{
256
 
  Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
 
254
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*(table->getMutableShare()), mem_root);
 
255
  TableIdentifier identifier(table->getShare()->getSchemaName(),
 
256
                             table->getShare()->getTableName(),
 
257
                             table->getShare()->getPath());
257
258
 
258
 
  if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat,
 
259
  if (new_handler && !new_handler->ha_open(identifier, table, file->s->name, table->db_stat,
259
260
                                           HA_OPEN_IGNORE_IF_LOCKED))
260
261
    return new_handler;
261
262
  return NULL;
264
265
 
265
266
const char *ha_heap::index_type(uint32_t inx)
266
267
{
267
 
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
268
  return ((table_share->getKeyInfo(inx).algorithm == HA_KEY_ALG_BTREE) ?
268
269
          "BTREE" : "HASH");
269
270
}
270
271
 
288
289
void ha_heap::set_keys_for_scanning(void)
289
290
{
290
291
  btree_keys.reset();
291
 
  for (uint32_t i= 0 ; i < table->s->keys ; i++)
 
292
  for (uint32_t i= 0 ; i < table->getShare()->sizeKeys() ; i++)
292
293
  {
293
294
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
294
295
      btree_keys.set(i);
298
299
 
299
300
void ha_heap::update_key_stats()
300
301
{
301
 
  for (uint32_t i= 0; i < table->s->keys; i++)
 
302
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++)
302
303
  {
303
 
    KEY *key=table->key_info+i;
 
304
    KeyInfo *key= &table->key_info[i];
304
305
    if (!key->rec_per_key)
305
306
      continue;
306
307
    if (key->algorithm != HA_KEY_ALG_BTREE)
323
324
}
324
325
 
325
326
 
326
 
int ha_heap::write_row(unsigned char * buf)
 
327
int ha_heap::doInsertRecord(unsigned char * buf)
327
328
{
328
329
  int res;
329
 
  ha_statistic_increment(&system_status_var::ha_write_count);
330
330
  if (table->next_number_field && buf == table->record[0])
331
331
  {
332
332
    if ((res= update_auto_increment()))
345
345
  return res;
346
346
}
347
347
 
348
 
int ha_heap::update_row(const unsigned char * old_data, unsigned char * new_data)
 
348
int ha_heap::doUpdateRecord(const unsigned char * old_data, unsigned char * new_data)
349
349
{
350
350
  int res;
351
 
  ha_statistic_increment(&system_status_var::ha_update_count);
352
 
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
353
 
    table->timestamp_field->set_time();
 
351
 
354
352
  res= heap_update(file,old_data,new_data);
355
353
  if (!res && ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
356
354
              file->s->records)
364
362
  return res;
365
363
}
366
364
 
367
 
int ha_heap::delete_row(const unsigned char * buf)
 
365
int ha_heap::doDeleteRecord(const unsigned char * buf)
368
366
{
369
367
  int res;
370
 
  ha_statistic_increment(&system_status_var::ha_delete_count);
 
368
 
371
369
  res= heap_delete(file,buf);
372
 
  if (!res && table->s->tmp_table == message::Table::STANDARD &&
 
370
  if (!res && table->getShare()->getType() == message::Table::STANDARD &&
373
371
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->s->records)
374
372
  {
375
373
    /*
449
447
  return error;
450
448
}
451
449
 
452
 
int ha_heap::rnd_init(bool scan)
 
450
int ha_heap::doStartTableScan(bool scan)
453
451
{
454
452
  return scan ? heap_scan_init(file) : 0;
455
453
}
527
525
int ha_heap::delete_all_rows()
528
526
{
529
527
  heap_clear(file);
530
 
  if (table->s->tmp_table == message::Table::STANDARD)
 
528
  if (table->getShare()->getType() == message::Table::STANDARD)
531
529
  {
532
530
    /*
533
531
       We can perform this safely since only one writer at the time is
652
650
}
653
651
 
654
652
 
655
 
int HeapEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
 
653
int HeapEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
656
654
{
657
655
  session.renameTableMessage(from, to);
658
656
  return heap_rename(from.getPath().c_str(), to.getPath().c_str());
662
660
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
663
661
                                  key_range *max_key)
664
662
{
665
 
  KEY *key=table->key_info+inx;
 
663
  KeyInfo *key= &table->key_info[inx];
666
664
  if (key->algorithm == HA_KEY_ALG_BTREE)
667
665
    return hp_rb_records_in_range(file, inx, min_key, max_key);
668
666
 
683
681
 
684
682
int HeapEngine::doCreateTable(Session &session,
685
683
                              Table &table_arg,
686
 
                              drizzled::TableIdentifier &identifier,
 
684
                              const TableIdentifier &identifier,
687
685
                              message::Table& create_proto)
688
686
{
689
687
  int error;
710
708
                                  message::Table &create_proto,
711
709
                                  HP_SHARE **internal_share)
712
710
{
713
 
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
 
711
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->getShare()->sizeKeys();
714
712
  uint32_t auto_key= 0, auto_key_type= 0;
715
713
  uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
716
 
  uint32_t column_idx, column_count= table_arg->s->fields;
 
714
  uint32_t column_idx, column_count= table_arg->getShare()->sizeFields();
717
715
  HP_COLUMNDEF *columndef;
718
716
  HP_KEYDEF *keydef;
719
717
  HA_KEYSEG *seg;
720
718
  char buff[FN_REFLEN];
721
719
  int error;
722
 
  TableShare *share= table_arg->s;
723
720
  bool found_real_auto_increment= 0;
724
721
 
725
722
  /* 
728
725
   * can return a number more than that, we trap it here instead of casting
729
726
   * to a truncated integer.
730
727
   */
731
 
  uint64_t num_rows= share->getMaxRows();
 
728
  uint64_t num_rows= table_arg->getShare()->getMaxRows();
732
729
  if (num_rows > UINT32_MAX)
733
730
    return -1;
734
731
 
737
734
 
738
735
  for (column_idx= 0; column_idx < column_count; column_idx++)
739
736
  {
740
 
    Field* field= *(table_arg->field + column_idx);
 
737
    Field* field= *(table_arg->getFields() + column_idx);
741
738
    HP_COLUMNDEF* column= columndef + column_idx;
742
739
    column->type= (uint16_t)field->type();
743
740
    column->length= field->pack_length();
777
774
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
778
775
  for (key= 0; key < keys; key++)
779
776
  {
780
 
    KEY *pos= table_arg->key_info+key;
781
 
    KEY_PART_INFO *key_part=     pos->key_part;
782
 
    KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
 
777
    KeyInfo *pos= &table_arg->key_info[key];
 
778
    KeyPartInfo *key_part=     pos->key_part;
 
779
    KeyPartInfo *key_part_end= key_part + pos->key_parts;
783
780
 
784
781
    keydef[key].keysegs=   (uint) pos->key_parts;
785
782
    keydef[key].flag=      (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
844
841
      }
845
842
      if (field->flags & AUTO_INCREMENT_FLAG &&
846
843
          table_arg->found_next_number_field &&
847
 
          key == share->next_number_index)
 
844
          key == table_arg->getShare()->next_number_index)
848
845
      {
849
846
        /*
850
847
          Store key number and type for found auto_increment key
861
858
    }
862
859
  }
863
860
 
864
 
  if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
 
861
  if (key_part_size < table_arg->getShare()->null_bytes + ((table_arg->getShare()->last_null_bit_pos+7) >> 3))
865
862
  {
866
863
    /* Make sure to include null fields regardless of the presense of keys */
867
 
    key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
 
864
    key_part_size = table_arg->getShare()->null_bytes + ((table_arg->getShare()->last_null_bit_pos+7) >> 3);
868
865
  }
869
866
 
870
867
 
871
868
 
872
869
  if (table_arg->found_next_number_field)
873
870
  {
874
 
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
875
 
    found_real_auto_increment= share->next_number_key_offset == 0;
 
871
    keydef[table_arg->getShare()->next_number_index].flag|= HA_AUTO_KEY;
 
872
    found_real_auto_increment= table_arg->getShare()->next_number_key_offset == 0;
876
873
  }
877
874
  HP_CREATE_INFO hp_create_info;
878
875
  hp_create_info.auto_key= auto_key;
882
879
  hp_create_info.max_table_size=session->variables.max_heap_table_size;
883
880
  hp_create_info.with_auto_increment= found_real_auto_increment;
884
881
  hp_create_info.internal_table= internal_table;
885
 
  hp_create_info.max_chunk_size= share->block_size;
886
 
  hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
 
882
  hp_create_info.max_chunk_size= table_arg->getShare()->block_size;
 
883
  hp_create_info.is_dynamic= (table_arg->getShare()->row_type == ROW_TYPE_DYNAMIC);
887
884
 
888
885
  error= heap_create(internal::fn_format(buff,table_name,"","",
889
886
                              MY_REPLACE_EXT|MY_UNPACK_FILENAME),
890
887
                    keys, keydef,
891
888
                    column_count, columndef,
892
889
                    max_key_fieldnr, key_part_size,
893
 
                    share->reclength, mem_per_row_keys,
 
890
                    table_arg->getShare()->getRecordLength(), mem_per_row_keys,
894
891
                    static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
895
892
                    0, // Factor out MIN
896
893
                    &hp_create_info, internal_share);