diff options
Diffstat (limited to 'storage')
-rw-r--r-- | storage/heap/ha_heap.cc | 32 | ||||
-rw-r--r-- | storage/heap/ha_heap.h | 2 | ||||
-rw-r--r-- | storage/heap/heapdef.h | 2 | ||||
-rw-r--r-- | storage/heap/hp_close.c | 3 | ||||
-rw-r--r-- | storage/heap/hp_create.c | 53 | ||||
-rw-r--r-- | storage/heap/hp_open.c | 81 | ||||
-rw-r--r-- | storage/heap/hp_test1.c | 4 | ||||
-rw-r--r-- | storage/heap/hp_test2.c | 8 |
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"); |