~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

  • Committer: Brian Aker
  • Date: 2009-05-11 17:50:22 UTC
  • Revision ID: brian@gaz-20090511175022-y35q9ky6uh9ldcjt
Replacing Sun employee copyright headers (aka... anything done by a Sun
employee is copyright by Sun).

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#define DRIZZLE_SERVER 1
17
16
#include <drizzled/server_includes.h>
 
17
#include <drizzled/error.h>
 
18
#include <drizzled/table.h>
 
19
#include <drizzled/session.h>
 
20
#include <drizzled/current_session.h>
 
21
#include <drizzled/field/timestamp.h>
 
22
#include <drizzled/field/varstring.h>
 
23
 
 
24
#include "heap.h"
18
25
#include "ha_heap.h"
19
26
#include "heapdef.h"
20
27
 
21
 
static handler *heap_create_handler(handlerton *hton,
22
 
                                    TABLE_SHARE *table, 
23
 
                                    MEM_ROOT *mem_root);
24
 
 
25
 
int heap_deinit(void *p __attribute__((unused)))
26
 
            
27
 
{
 
28
#include <string>
 
29
 
 
30
using namespace std;
 
31
 
 
32
static const string engine_name("MEMORY");
 
33
 
 
34
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
 
35
 
 
36
 
 
37
class HeapEngine : public StorageEngine
 
38
{
 
39
public:
 
40
  HeapEngine(string name_arg) : StorageEngine(name_arg, HTON_CAN_RECREATE)
 
41
  {
 
42
    addAlias("HEAP");
 
43
  }
 
44
 
 
45
  virtual handler *create(TableShare *table,
 
46
                          MEM_ROOT *mem_root)
 
47
  {
 
48
    return new (mem_root) ha_heap(this, table);
 
49
  }
 
50
};
 
51
 
 
52
static HeapEngine *engine= NULL;
 
53
int heap_init(PluginRegistry &registry)
 
54
{
 
55
  engine= new HeapEngine(engine_name);
 
56
  registry.add(engine);
 
57
  pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
 
58
  return 0;
 
59
}
 
60
 
 
61
int heap_deinit(PluginRegistry &registry)
 
62
{
 
63
  registry.remove(engine);
 
64
  delete engine;
 
65
 
 
66
  pthread_mutex_destroy(&THR_LOCK_heap);
 
67
 
28
68
  return hp_panic(HA_PANIC_CLOSE);
29
69
}
30
70
 
31
71
 
32
 
int heap_init(void *p)
33
 
{
34
 
  handlerton *heap_hton;
35
 
 
36
 
  heap_hton= (handlerton *)p;
37
 
  heap_hton->state=      SHOW_OPTION_YES;
38
 
  heap_hton->create=     heap_create_handler;
39
 
  heap_hton->flags=      HTON_CAN_RECREATE;
40
 
 
41
 
  return 0;
42
 
}
43
 
 
44
 
static handler *heap_create_handler(handlerton *hton,
45
 
                                    TABLE_SHARE *table, 
46
 
                                    MEM_ROOT *mem_root)
47
 
{
48
 
  return new (mem_root) ha_heap(hton, table);
49
 
}
50
 
 
51
72
 
52
73
/*****************************************************************************
53
74
** HEAP tables
54
75
*****************************************************************************/
55
76
 
56
 
ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
57
 
  :handler(hton, table_arg), file(0), records_changed(0), key_stat_version(0), 
 
77
ha_heap::ha_heap(StorageEngine *engine_arg, TableShare *table_arg)
 
78
  :handler(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
58
79
  internal_table(0)
59
80
{}
60
81
 
69
90
}
70
91
 
71
92
/*
72
 
  Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to 
73
 
  rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records 
74
 
  have been inserted/updated/deleted. delete_all_rows() and table flush cause 
 
93
  Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
 
94
  rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records
 
95
  have been inserted/updated/deleted. delete_all_rows() and table flush cause
75
96
  immediate update.
76
97
 
77
98
  NOTE
78
99
   hash index statistics must be updated when number of table records changes
79
 
   from 0 to non-zero value and vice versa. Otherwise records_in_range may 
 
100
   from 0 to non-zero value and vice versa. Otherwise records_in_range may
80
101
   erroneously return 0 and 'range' may miss records.
81
102
*/
82
103
#define HEAP_STATS_UPDATE_THRESHOLD 10
132
153
  Create a copy of this table
133
154
 
134
155
  DESCRIPTION
135
 
    Do same as default implementation but use file->s->name instead of 
 
156
    Do same as default implementation but use file->s->name instead of
136
157
    table->s->path. This is needed by Windows where the clone() call sees
137
 
    '/'-delimited path in table->s->path, while ha_peap::open() was called 
 
158
    '/'-delimited path in table->s->path, while ha_peap::open() was called
138
159
    with '\'-delimited path.
139
160
*/
140
161
 
148
169
}
149
170
 
150
171
 
 
172
const char *ha_heap::index_type(uint32_t inx)
 
173
{
 
174
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
175
          "BTREE" : "HASH");
 
176
}
 
177
 
 
178
 
 
179
uint32_t ha_heap::index_flags(uint32_t inx, uint32_t, bool) const
 
180
{
 
181
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
182
          HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
 
183
          HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
 
184
}
 
185
 
 
186
 
151
187
/*
152
188
  Compute which keys to use for scanning
153
189
 
166
202
 
167
203
void ha_heap::set_keys_for_scanning(void)
168
204
{
169
 
  btree_keys.clear_all();
 
205
  btree_keys.reset();
170
206
  for (uint32_t i= 0 ; i < table->s->keys ; i++)
171
207
  {
172
208
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
173
 
      btree_keys.set_bit(i);
 
209
      btree_keys.set(i);
174
210
  }
175
211
}
176
212
 
206
242
{
207
243
  int res;
208
244
  ha_statistic_increment(&SSV::ha_write_count);
209
 
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
210
 
    table->timestamp_field->set_time();
211
245
  if (table->next_number_field && buf == table->record[0])
212
246
  {
213
247
    if ((res= update_auto_increment()))
214
248
      return res;
215
249
  }
216
250
  res= heap_write(file,buf);
217
 
  if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
 
251
  if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
218
252
               file->s->records))
219
253
  {
220
254
    /*
233
267
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
234
268
    table->timestamp_field->set_time();
235
269
  res= heap_update(file,old_data,new_data);
236
 
  if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
 
270
  if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
237
271
              file->s->records)
238
272
  {
239
273
    /*
250
284
  int res;
251
285
  ha_statistic_increment(&SSV::ha_delete_count);
252
286
  res= heap_delete(file,buf);
253
 
  if (!res && table->s->tmp_table == NO_TMP_TABLE && 
 
287
  if (!res && table->s->tmp_table == NO_TMP_TABLE &&
254
288
      ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
255
289
  {
256
290
    /*
354
388
  return error;
355
389
}
356
390
 
357
 
void ha_heap::position(const unsigned char *record __attribute__((unused)))
 
391
void ha_heap::position(const unsigned char *)
358
392
{
359
393
  *(HEAP_PTR*) ref= heap_position(file);        // Ref is aligned
360
394
}
419
453
  return 0;
420
454
}
421
455
 
422
 
int ha_heap::external_lock(THD *thd __attribute__((unused)),
423
 
                           int lock_type __attribute__((unused)))
 
456
int ha_heap::external_lock(Session *, int)
424
457
{
425
458
  return 0;                                     // No external locking
426
459
}
533
566
  return heap_indexes_are_disabled(file);
534
567
}
535
568
 
536
 
THR_LOCK_DATA **ha_heap::store_lock(THD *thd __attribute__((unused)),
 
569
THR_LOCK_DATA **ha_heap::store_lock(Session *,
537
570
                                    THR_LOCK_DATA **to,
538
571
                                    enum thr_lock_type lock_type)
539
572
{
550
583
 
551
584
int ha_heap::delete_table(const char *name)
552
585
{
553
 
  int error= heap_delete_table(name);
554
 
  return error == ENOENT ? 0 : error;
 
586
  return heap_delete_table(name);
555
587
}
556
588
 
557
589
 
558
 
void ha_heap::drop_table(const char *name __attribute__((unused)))
 
590
void ha_heap::drop_table(const char *)
559
591
{
560
592
  file->s->delete_on_close= 1;
561
593
  close();
603
635
  HA_KEYSEG *seg;
604
636
  char buff[FN_REFLEN];
605
637
  int error;
606
 
  TABLE_SHARE *share= table_arg->s;
 
638
  TableShare *share= table_arg->s;
607
639
  bool found_real_auto_increment= 0;
608
640
 
609
 
  if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count * sizeof(HP_COLUMNDEF), MYF(MY_WME))))
 
641
  if (!(columndef= (HP_COLUMNDEF*) malloc(column_count * sizeof(HP_COLUMNDEF))))
610
642
    return my_errno;
611
643
 
612
644
  for (column_idx= 0; column_idx < column_count; column_idx++)
641
673
  for (key= parts= 0; key < keys; key++)
642
674
    parts+= table_arg->key_info[key].key_parts;
643
675
 
644
 
  if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
645
 
                                       parts * sizeof(HA_KEYSEG),
646
 
                                       MYF(MY_WME))))
 
676
  if (!(keydef= (HP_KEYDEF*) malloc(keys * sizeof(HP_KEYDEF) +
 
677
                                    parts * sizeof(HA_KEYSEG))))
647
678
  {
648
679
    free((void *) columndef);
649
680
    return my_errno;
735
766
      }
736
767
    }
737
768
  }
738
 
  
 
769
 
739
770
  if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
740
771
  {
741
772
    /* Make sure to include null fields regardless of the presense of keys */
742
773
    key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
743
774
  }
744
775
 
745
 
  
746
 
  
 
776
 
 
777
 
747
778
  if (table_arg->found_next_number_field)
748
779
  {
749
780
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
754
785
  hp_create_info.auto_key_type= auto_key_type;
755
786
  hp_create_info.auto_increment= (create_info->auto_increment_value ?
756
787
                                  create_info->auto_increment_value - 1 : 0);
757
 
  hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
 
788
  hp_create_info.max_table_size=current_session->variables.max_heap_table_size;
758
789
  hp_create_info.with_auto_increment= found_real_auto_increment;
759
790
  hp_create_info.internal_table= internal_table;
760
791
  hp_create_info.max_chunk_size= share->block_size;
767
798
         share->reclength, mem_per_row_keys,
768
799
         (uint32_t) share->max_rows, (uint32_t) share->min_rows,
769
800
         &hp_create_info, &internal_share);
770
 
  
 
801
 
771
802
  free((unsigned char*) keydef);
772
803
  free((void *) columndef);
773
804
  assert(file == 0);
789
820
  }
790
821
}
791
822
 
792
 
void ha_heap::get_auto_increment(uint64_t offset __attribute__((unused)),
793
 
                                 uint64_t increment __attribute__((unused)),
794
 
                                 uint64_t nb_desired_values __attribute__((unused)),
 
823
void ha_heap::get_auto_increment(uint64_t, uint64_t, uint64_t,
795
824
                                 uint64_t *first_value,
796
825
                                 uint64_t *nb_reserved_values)
797
826
{
802
831
}
803
832
 
804
833
 
805
 
bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
806
 
                                         uint32_t table_changes)
 
834
int ha_heap::cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
807
835
{
808
 
  /* Check that auto_increment value was not changed */
809
 
  if ((info->used_fields & HA_CREATE_USED_AUTO &&
810
 
       info->auto_increment_value != 0) ||
811
 
      table_changes == IS_EQUAL_NO ||
812
 
      table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
813
 
    return COMPATIBLE_DATA_NO;
814
 
  return COMPATIBLE_DATA_YES;
 
836
  return memcmp(ref1, ref2, sizeof(HEAP_PTR));
815
837
}
816
838
 
817
 
mysql_declare_plugin(heap)
 
839
 
 
840
drizzle_declare_plugin(heap)
818
841
{
819
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
820
842
  "MEMORY",
821
843
  "1.0",
822
844
  "MySQL AB",
828
850
  NULL,                       /* system variables                */
829
851
  NULL                        /* config options                  */
830
852
}
831
 
mysql_declare_plugin_end;
 
853
drizzle_declare_plugin_end;