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 */
16
#include "heap_priv.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
#include "drizzled/plugin/daemon.h"
16
#define DRIZZLE_SERVER 1
17
#include <drizzled/server_includes.h>
26
18
#include "ha_heap.h"
31
using namespace drizzled;
34
static const string engine_name("MEMORY");
36
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
38
static const char *ha_heap_exts[] = {
42
class HeapEngine : public plugin::StorageEngine
45
explicit HeapEngine(string name_arg) :
46
plugin::StorageEngine(name_arg,
47
HTON_STATS_RECORDS_IS_EXACT |
52
HTON_SKIP_STORE_LOCK |
55
pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
60
hp_panic(HA_PANIC_CLOSE);
62
pthread_mutex_destroy(&THR_LOCK_heap);
65
virtual Cursor *create(TableShare &table,
66
memory::Root *mem_root)
68
return new (mem_root) ha_heap(*this, table);
71
const char **bas_ext() const {
75
int doCreateTable(Session &session,
77
drizzled::TableIdentifier &identifier,
78
message::Table &create_proto);
80
/* For whatever reason, internal tables can be created by Cursor::open()
82
Instead of diving down a rat hole, let's just cry ourselves to sleep
83
at night with this odd hackish workaround.
85
int heap_create_table(Session *session, const char *table_name,
88
message::Table &create_proto,
89
HP_SHARE **internal_share);
91
int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
93
int doDropTable(Session&, TableIdentifier &identifier);
95
int doGetTableDefinition(Session& session,
96
TableIdentifier &identifier,
97
message::Table &table_message);
99
/* Temp only engine, so do not return values. */
100
void doGetTableNames(CachedDirectory &, SchemaIdentifier& , set<string>&) { };
102
uint32_t max_supported_keys() const { return MAX_KEY; }
103
uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
105
uint32_t index_flags(enum ha_key_alg algorithm) const
107
return ((algorithm == HA_KEY_ALG_BTREE) ?
112
HA_ONLY_WHOLE_INDEX |
113
HA_KEY_SCAN_NOT_ROR);
116
bool doDoesTableExist(Session& session, TableIdentifier &identifier);
117
void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
118
drizzled::SchemaIdentifier &schema_identifier,
119
drizzled::TableIdentifiers &set_of_identifiers);
122
void HeapEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
123
drizzled::SchemaIdentifier&,
124
drizzled::TableIdentifiers&)
128
bool HeapEngine::doDoesTableExist(Session& session, TableIdentifier &identifier)
130
return session.doesTableMessageExist(identifier);
133
int HeapEngine::doGetTableDefinition(Session &session,
134
TableIdentifier &identifier,
135
message::Table &table_proto)
137
if (session.getTableMessage(identifier, table_proto))
143
We have to ignore ENOENT entries as the MEMORY table is created on open and
144
not when doing a CREATE on the table.
146
int HeapEngine::doDropTable(Session &session, TableIdentifier &identifier)
148
session.removeTableMessage(identifier);
150
int error= heap_delete_table(identifier.getPath().c_str());
158
static HeapEngine *heap_storage_engine= NULL;
160
static int heap_init(plugin::Context &context)
162
heap_storage_engine= new HeapEngine(engine_name);
163
context.add(heap_storage_engine);
21
static handler *heap_create_handler(handlerton *hton,
25
int heap_deinit(void *p __attribute__((unused)))
28
return hp_panic(HA_PANIC_CLOSE);
32
int heap_init(void *p)
34
handlerton *heap_hton;
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;
44
static handler *heap_create_handler(handlerton *hton,
48
return new (mem_root) ha_heap(hton, table);
168
52
/*****************************************************************************
170
54
*****************************************************************************/
172
ha_heap::ha_heap(plugin::StorageEngine &engine_arg,
173
TableShare &table_arg)
174
:Cursor(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
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),
62
static const char *ha_heap_exts[] = {
66
const char **ha_heap::bas_ext() const
179
Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to
180
rec_per_key) after 1/MEMORY_STATS_UPDATE_THRESHOLD fraction of table records
181
have been inserted/updated/deleted. delete_all_rows() and table flush cause
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
185
78
hash index statistics must be updated when number of table records changes
186
from 0 to non-zero value and vice versa. Otherwise records_in_range may
79
from 0 to non-zero value and vice versa. Otherwise records_in_range may
187
80
erroneously return 0 and 'range' may miss records.
189
#define MEMORY_STATS_UPDATE_THRESHOLD 10
82
#define HEAP_STATS_UPDATE_THRESHOLD 10
191
84
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
193
if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && errno == ENOENT))
86
if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
195
88
HA_CREATE_INFO create_info;
196
89
internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
197
90
memset(&create_info, 0, sizeof(create_info));
199
HP_SHARE *internal_share= NULL;
200
message::Table create_proto;
202
if (!heap_storage_engine->heap_create_table(ha_session(), name, table,
92
if (!create(name, table, &create_info))
207
94
file= internal_table ?
208
95
heap_open_from_share(internal_share, mode) :
877
752
HP_CREATE_INFO hp_create_info;
878
753
hp_create_info.auto_key= auto_key;
879
754
hp_create_info.auto_key_type= auto_key_type;
880
hp_create_info.auto_increment= (create_proto.options().has_auto_increment_value() ?
881
create_proto.options().auto_increment_value() - 1 : 0);
882
hp_create_info.max_table_size=session->variables.max_heap_table_size;
755
hp_create_info.auto_increment= (create_info->auto_increment_value ?
756
create_info->auto_increment_value - 1 : 0);
757
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
883
758
hp_create_info.with_auto_increment= found_real_auto_increment;
884
759
hp_create_info.internal_table= internal_table;
885
760
hp_create_info.max_chunk_size= share->block_size;
886
761
hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
888
error= heap_create(internal::fn_format(buff,table_name,"","",
889
MY_REPLACE_EXT|MY_UNPACK_FILENAME),
891
column_count, columndef,
892
max_key_fieldnr, key_part_size,
893
share->reclength, mem_per_row_keys,
894
static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
896
&hp_create_info, internal_share);
762
error= heap_create(fn_format(buff,name,"","",
763
MY_REPLACE_EXT|MY_UNPACK_FILENAME),
765
column_count, columndef,
766
max_key_fieldnr, key_part_size,
767
share->reclength, mem_per_row_keys,
768
(uint32_t) share->max_rows, (uint32_t) share->min_rows,
769
&hp_create_info, &internal_share);
898
771
free((unsigned char*) keydef);
899
772
free((void *) columndef);
905
void ha_heap::get_auto_increment(uint64_t, uint64_t, uint64_t,
778
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
780
table->file->info(HA_STATUS_AUTO);
781
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
782
create_info->auto_increment_value= stats.auto_increment_value;
783
if (!(create_info->used_fields & HA_CREATE_USED_BLOCK_SIZE))
785
if (file->s->recordspace.is_variable_size)
786
create_info->block_size= file->s->recordspace.chunk_length;
788
create_info->block_size= 0;
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)),
906
795
uint64_t *first_value,
907
796
uint64_t *nb_reserved_values)