summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/heap/ha_heap.cc32
-rw-r--r--storage/heap/ha_heap.h2
-rw-r--r--storage/heap/heapdef.h2
-rw-r--r--storage/heap/hp_close.c3
-rw-r--r--storage/heap/hp_create.c53
-rw-r--r--storage/heap/hp_open.c81
-rw-r--r--storage/heap/hp_test1.c4
-rw-r--r--storage/heap/hp_test2.c8
8 files changed, 132 insertions, 53 deletions
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index f2b67f20c57..2e7c47e17b4 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -22,7 +22,7 @@
#include "mysql_priv.h"
#include <mysql/plugin.h>
#include "ha_heap.h"
-
+#include "heapdef.h"
static handler *heap_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -61,8 +61,8 @@ static handler *heap_create_handler(handlerton *hton,
*****************************************************************************/
ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
- :handler(hton, table_arg), file(0), records_changed(0),
- key_stat_version(0)
+ :handler(hton, table_arg), file(0), records_changed(0), internal_table(0),
+ key_stat_version(0)
{}
@@ -90,13 +90,25 @@ const char **ha_heap::bas_ext() const
int ha_heap::open(const char *name, int mode, uint test_if_locked)
{
- if (!(file= heap_open(name, mode)) && my_errno == ENOENT)
+ if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) ||
+ !(file= heap_open(name, mode)) && my_errno == ENOENT)
{
HA_CREATE_INFO create_info;
+ internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
bzero(&create_info, sizeof(create_info));
+ file= 0;
if (!create(name, table, &create_info))
{
- file= heap_open(name, mode);
+ file= internal_table ?
+ heap_open_from_share(internal_share, mode) :
+ heap_open_from_share_and_register(internal_share, mode);
+ if (!file)
+ {
+ /* Couldn't open table; Remove the newly created table */
+ pthread_mutex_lock(&THR_LOCK_heap);
+ hp_free(internal_share);
+ pthread_mutex_unlock(&THR_LOCK_heap);
+ }
implicit_emptied= 1;
}
}
@@ -120,7 +132,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
int ha_heap::close(void)
{
- return heap_close(file);
+ return internal_table ? hp_close(file) : heap_close(file);
}
@@ -542,7 +554,7 @@ int ha_heap::delete_table(const char *name)
void ha_heap::drop_table(const char *name)
{
- heap_drop_table(file);
+ file->s->delete_on_close= 1;
close();
}
@@ -681,16 +693,16 @@ int ha_heap::create(const char *name, TABLE *table_arg,
create_info->auto_increment_value - 1 : 0);
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
hp_create_info.with_auto_increment= found_real_auto_increment;
+ hp_create_info.internal_table= internal_table;
max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row);
error= heap_create(name,
keys, keydef, share->reclength,
(ulong) ((share->max_rows < max_rows &&
share->max_rows) ?
share->max_rows : max_rows),
- (ulong) share->min_rows, &hp_create_info);
+ (ulong) share->min_rows, &hp_create_info, &internal_share);
my_free((uchar*) keydef, MYF(0));
- if (file)
- info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ DBUG_ASSERT(file == 0);
return (error);
}
diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h
index c414383a4aa..7db775ca15a 100644
--- a/storage/heap/ha_heap.h
+++ b/storage/heap/ha_heap.h
@@ -25,10 +25,12 @@
class ha_heap: public handler
{
HP_INFO *file;
+ HP_SHARE *internal_share;
key_map btree_keys;
/* number of records changed since last statistics update */
uint records_changed;
uint key_stat_version;
+ my_bool internal_table;
public:
ha_heap(handlerton *hton, TABLE_SHARE *table);
~ha_heap() {}
diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h
index c43d73eb96d..3fc94062303 100644
--- a/storage/heap/heapdef.h
+++ b/storage/heap/heapdef.h
@@ -16,6 +16,7 @@
/* This file is included in all heap-files */
#include <my_base.h> /* This includes global */
+C_MODE_START
#ifdef THREAD
#include <my_pthread.h>
#endif
@@ -107,3 +108,4 @@ extern pthread_mutex_t THR_LOCK_heap;
#define pthread_mutex_lock(A)
#define pthread_mutex_unlock(A)
#endif
+C_MODE_END
diff --git a/storage/heap/hp_close.c b/storage/heap/hp_close.c
index 79fed859487..d571815980c 100644
--- a/storage/heap/hp_close.c
+++ b/storage/heap/hp_close.c
@@ -42,7 +42,8 @@ int hp_close(register HP_INFO *info)
}
#endif
info->s->changed=0;
- heap_open_list=list_delete(heap_open_list,&info->open_list);
+ if (info->open_list.data)
+ heap_open_list=list_delete(heap_open_list,&info->open_list);
if (!--info->s->open_count && info->s->delete_on_close)
hp_free(info->s); /* Table was deleted */
my_free((uchar*) info,MYF(0));
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index b910b89ffcd..b6814fc1614 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -19,23 +19,27 @@ static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2);
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
ulong max_records);
+/* Create a heap table */
+
int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records,
- HP_CREATE_INFO *create_info)
+ HP_CREATE_INFO *create_info, HP_SHARE **res)
{
uint i, j, key_segs, max_length, length;
- HP_SHARE *share;
+ HP_SHARE *share= 0;
HA_KEYSEG *keyseg;
-
DBUG_ENTER("heap_create");
- pthread_mutex_lock(&THR_LOCK_heap);
- if ((share= hp_find_named_heap(name)) && share->open_count == 0)
+ if (!create_info->internal_table)
{
- hp_free(share);
- share= NULL;
- }
-
+ pthread_mutex_lock(&THR_LOCK_heap);
+ if ((share= hp_find_named_heap(name)) && share->open_count == 0)
+ {
+ hp_free(share);
+ share= 0;
+ }
+ }
+
if (!share)
{
HP_KEYDEF *keyinfo;
@@ -131,10 +135,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
keys*sizeof(HP_KEYDEF)+
key_segs*sizeof(HA_KEYSEG),
MYF(MY_ZEROFILL))))
- {
- pthread_mutex_unlock(&THR_LOCK_heap);
- DBUG_RETURN(1);
- }
+ goto err;
share->keydef= (HP_KEYDEF*) (share + 1);
share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys);
@@ -189,20 +190,33 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
if (!(share->name= my_strdup(name,MYF(0))))
{
my_free((uchar*) share,MYF(0));
- pthread_mutex_unlock(&THR_LOCK_heap);
- DBUG_RETURN(1);
+ goto err;
}
#ifdef THREAD
thr_lock_init(&share->lock);
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
#endif
- share->open_list.data= (void*) share;
- heap_share_list= list_add(heap_share_list,&share->open_list);
+ if (!create_info->internal_table)
+ {
+ share->open_list.data= (void*) share;
+ heap_share_list= list_add(heap_share_list,&share->open_list);
+ }
+ else
+ share->delete_on_close= 1;
}
- pthread_mutex_unlock(&THR_LOCK_heap);
+ if (!create_info->internal_table)
+ pthread_mutex_unlock(&THR_LOCK_heap);
+
+ *res= share;
DBUG_RETURN(0);
+
+err:
+ if (!create_info->internal_table)
+ pthread_mutex_unlock(&THR_LOCK_heap);
+ DBUG_RETURN(1);
} /* heap_create */
+
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
{
uint not_used[2];
@@ -279,7 +293,8 @@ void heap_drop_table(HP_INFO *info)
void hp_free(HP_SHARE *share)
{
- heap_share_list= list_delete(heap_share_list, &share->open_list);
+ if (share->open_list.data) /* If not internal table */
+ heap_share_list= list_delete(heap_share_list, &share->open_list);
hp_clear(share); /* Remove blocks from memory */
#ifdef THREAD
thr_lock_delete(&share->lock);
diff --git a/storage/heap/hp_open.c b/storage/heap/hp_open.c
index d252704a11b..4d5ec6e27ac 100644
--- a/storage/heap/hp_open.c
+++ b/storage/heap/hp_open.c
@@ -22,43 +22,34 @@
#include "my_sys.h"
-HP_INFO *heap_open(const char *name, int mode)
+/*
+ Open heap table based on HP_SHARE structure
+
+ NOTE
+ This doesn't register the table in the open table list.
+*/
+
+HP_INFO *heap_open_from_share(HP_SHARE *share, int mode)
{
HP_INFO *info;
- HP_SHARE *share;
+ DBUG_ENTER("heap_open_from_share");
- DBUG_ENTER("heap_open");
- pthread_mutex_lock(&THR_LOCK_heap);
- if (!(share= hp_find_named_heap(name)))
- {
- my_errno= ENOENT;
- pthread_mutex_unlock(&THR_LOCK_heap);
- DBUG_RETURN(0);
- }
if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) +
2 * share->max_key_length,
MYF(MY_ZEROFILL))))
{
- pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
share->open_count++;
#ifdef THREAD
thr_lock_data_init(&share->lock,&info->lock,NULL);
#endif
- info->open_list.data= (void*) info;
- heap_open_list= list_add(heap_open_list,&info->open_list);
- pthread_mutex_unlock(&THR_LOCK_heap);
-
info->s= share;
info->lastkey= (uchar*) (info + 1);
info->recbuf= (uchar*) (info->lastkey + share->max_key_length);
info->mode= mode;
info->current_record= (ulong) ~0L; /* No current record */
- info->current_ptr= 0;
- info->current_hash_ptr= 0;
info->lastinx= info->errkey= -1;
- info->update= 0;
#ifndef DBUG_OFF
info->opt_flag= READ_CHECK_USED; /* Check when changing */
#endif
@@ -68,7 +59,59 @@ HP_INFO *heap_open(const char *name, int mode)
DBUG_RETURN(info);
}
- /* map name to a heap-nr. If name isn't found return 0 */
+
+/*
+ Open heap table based on HP_SHARE structure and register it
+*/
+
+HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode)
+{
+ HP_INFO *info;
+ DBUG_ENTER("heap_open_from_share_and_register");
+
+ pthread_mutex_lock(&THR_LOCK_heap);
+ if ((info= heap_open_from_share(share, mode)))
+ {
+ info->open_list.data= (void*) info;
+ heap_open_list= list_add(heap_open_list,&info->open_list);
+ }
+ pthread_mutex_unlock(&THR_LOCK_heap);
+ DBUG_RETURN(info);
+}
+
+
+/*
+ Open heap table based on name
+
+ NOTE
+ This register the table in the open table list. so that it can be
+ found by future heap_open() calls.
+*/
+
+HP_INFO *heap_open(const char *name, int mode)
+{
+ HP_INFO *info;
+ HP_SHARE *share;
+ DBUG_ENTER("heap_open");
+
+ pthread_mutex_lock(&THR_LOCK_heap);
+ if (!(share= hp_find_named_heap(name)))
+ {
+ my_errno= ENOENT;
+ pthread_mutex_unlock(&THR_LOCK_heap);
+ DBUG_RETURN(0);
+ }
+ if ((info= heap_open_from_share(share, mode)))
+ {
+ info->open_list.data= (void*) info;
+ heap_open_list= list_add(heap_open_list,&info->open_list);
+ }
+ pthread_mutex_unlock(&THR_LOCK_heap);
+ DBUG_RETURN(info);
+}
+
+
+/* map name to a heap-nr. If name isn't found return 0 */
HP_SHARE *hp_find_named_heap(const char *name)
{
diff --git a/storage/heap/hp_test1.c b/storage/heap/hp_test1.c
index aad5677db69..24eea141ad9 100644
--- a/storage/heap/hp_test1.c
+++ b/storage/heap/hp_test1.c
@@ -37,6 +37,7 @@ int main(int argc, char **argv)
HP_KEYDEF keyinfo[10];
HA_KEYSEG keyseg[4];
HP_CREATE_INFO hp_create_info;
+ HP_SHARE *tmp_share;
MY_INIT(argv[0]);
filename= "test1";
@@ -52,6 +53,7 @@ int main(int argc, char **argv)
keyinfo[0].seg[0].start=1;
keyinfo[0].seg[0].length=6;
keyinfo[0].seg[0].charset= &my_charset_latin1;
+ keyinfo[0].seg[0].null_bit= 0;
keyinfo[0].flag = HA_NOSAME;
deleted=0;
@@ -59,7 +61,7 @@ int main(int argc, char **argv)
printf("- Creating heap-file\n");
if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L,
- &hp_create_info) ||
+ &hp_create_info, &tmp_share) ||
!(file= heap_open(filename, 2)))
goto err;
printf("- Writing records:s\n");
diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c
index 46b1fd61d46..e2a8e2f6926 100644
--- a/storage/heap/hp_test2.c
+++ b/storage/heap/hp_test2.c
@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
char record[128],record2[128],record3[128],key[10];
const char *filename,*filename2;
HP_INFO *file,*file2;
+ HP_SHARE *tmp_share;
HP_KEYDEF keyinfo[MAX_KEYS];
HA_KEYSEG keyseg[MAX_KEYS*5];
HEAP_PTR position;
@@ -126,7 +127,7 @@ int main(int argc, char *argv[])
printf("- Creating heap-file\n");
if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
- (ulong) recant/2, &hp_create_info) ||
+ (ulong) recant/2, &hp_create_info, &tmp_share) ||
!(file= heap_open(filename, 2)))
goto err;
signal(SIGINT,endprog);
@@ -562,8 +563,9 @@ int main(int argc, char *argv[])
heap_close(file2);
printf("- Creating output heap-file 2\n");
- if (heap_create(filename2,1,keyinfo,reclength,0L,0L,&hp_create_info) ||
- !(file2= heap_open(filename2, 2)))
+ if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info,
+ &tmp_share) ||
+ !(file2= heap_open_from_share_and_register(tmp_share, 2)))
goto err;
printf("- Copying and removing records\n");