Added support for 'internal temporary tables' in HEAP tables.

Now we don't take any mutexes when creating or dropping internal HEAP tables during SELECT.
Change buffer sizes to size_t to make keycache 64 bit safe on platforms where sizeof(ulong) != sizeof(size_t)
parent c6653675
...@@ -2995,3 +2995,4 @@ win/vs71cache.txt ...@@ -2995,3 +2995,4 @@ win/vs71cache.txt
win/vs8cache.txt win/vs8cache.txt
zlib/*.ds? zlib/*.ds?
zlib/*.vcproj zlib/*.vcproj
support-files/mysqld_multi.server
...@@ -189,11 +189,14 @@ typedef struct st_heap_create_info ...@@ -189,11 +189,14 @@ typedef struct st_heap_create_info
ulonglong max_table_size; ulonglong max_table_size;
ulonglong auto_increment; ulonglong auto_increment;
my_bool with_auto_increment; my_bool with_auto_increment;
my_bool internal_table;
} HP_CREATE_INFO; } HP_CREATE_INFO;
/* Prototypes for heap-functions */ /* Prototypes for heap-functions */
extern HP_INFO *heap_open(const char *name, int mode); extern HP_INFO *heap_open(const char *name, int mode);
extern HP_INFO *heap_open_from_share(HP_SHARE *share, int mode);
extern HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode);
extern int heap_close(HP_INFO *info); extern int heap_close(HP_INFO *info);
extern int heap_write(HP_INFO *info,const uchar *buff); extern int heap_write(HP_INFO *info,const uchar *buff);
extern int heap_update(HP_INFO *info,const uchar *old,const uchar *newdata); extern int heap_update(HP_INFO *info,const uchar *old,const uchar *newdata);
...@@ -204,7 +207,7 @@ extern int heap_delete(HP_INFO *info,const uchar *buff); ...@@ -204,7 +207,7 @@ extern int heap_delete(HP_INFO *info,const uchar *buff);
extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag); extern int heap_info(HP_INFO *info,HEAPINFO *x,int flag);
extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records, uint reclength, ulong max_records, ulong min_records,
HP_CREATE_INFO *create_info); HP_CREATE_INFO *create_info, HP_SHARE **share);
extern int heap_delete_table(const char *name); extern int heap_delete_table(const char *name);
extern void heap_drop_table(HP_INFO *info); extern void heap_drop_table(HP_INFO *info);
extern int heap_extra(HP_INFO *info,enum ha_extra_function function); extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
......
...@@ -47,7 +47,7 @@ typedef struct st_key_cache ...@@ -47,7 +47,7 @@ typedef struct st_key_cache
my_bool in_resize; /* true during resize operation */ my_bool in_resize; /* true during resize operation */
my_bool resize_in_flush; /* true during flush of resize operation */ my_bool resize_in_flush; /* true during flush of resize operation */
my_bool can_be_used; /* usage of cache for read/write is allowed */ my_bool can_be_used; /* usage of cache for read/write is allowed */
ulong key_cache_mem_size; /* specified size of the cache memory */ size_t key_cache_mem_size; /* specified size of the cache memory */
uint key_cache_block_size; /* size of the page buffer of a cache block */ uint key_cache_block_size; /* size of the page buffer of a cache block */
ulong min_warm_blocks; /* min number of warm blocks; */ ulong min_warm_blocks; /* min number of warm blocks; */
ulong age_threshold; /* age threshold for hot blocks */ ulong age_threshold; /* age threshold for hot blocks */
...@@ -107,10 +107,10 @@ typedef struct st_key_cache ...@@ -107,10 +107,10 @@ typedef struct st_key_cache
extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache; extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache;
extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
ulong use_mem, uint division_limit, size_t use_mem, uint division_limit,
uint age_threshold); uint age_threshold);
extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
ulong use_mem, uint division_limit, size_t use_mem, uint division_limit,
uint age_threshold); uint age_threshold);
extern void change_key_cache_param(KEY_CACHE *keycache, uint division_limit, extern void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
uint age_threshold); uint age_threshold);
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */ #define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
#define HA_OPEN_FROM_SQL_LAYER 64 #define HA_OPEN_FROM_SQL_LAYER 64
#define HA_OPEN_MMAP 128 /* open memory mapped */ #define HA_OPEN_MMAP 128 /* open memory mapped */
/* Internal temp table, used for temporary results */
#define HA_OPEN_INTERNAL_TABLE 256
/* The following is parameter to ha_rkey() how to use key */ /* The following is parameter to ha_rkey() how to use key */
......
...@@ -366,10 +366,11 @@ static inline uint next_power(uint value) ...@@ -366,10 +366,11 @@ static inline uint next_power(uint value)
*/ */
int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
ulong use_mem, uint division_limit, size_t use_mem, uint division_limit,
uint age_threshold) uint age_threshold)
{ {
uint blocks, hash_links, length; ulong blocks, hash_links;
size_t length;
int error; int error;
DBUG_ENTER("init_key_cache"); DBUG_ENTER("init_key_cache");
DBUG_ASSERT(key_cache_block_size >= 512); DBUG_ASSERT(key_cache_block_size >= 512);
...@@ -405,8 +406,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ...@@ -405,8 +406,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
DBUG_PRINT("info", ("key_cache_block_size: %u", DBUG_PRINT("info", ("key_cache_block_size: %u",
key_cache_block_size)); key_cache_block_size));
blocks= (uint) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) + blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) +
sizeof(HASH_LINK*) * 5/4 + key_cache_block_size)); sizeof(HASH_LINK*) * 5/4 + key_cache_block_size));
/* It doesn't make sense to have too few blocks (less than 8) */ /* It doesn't make sense to have too few blocks (less than 8) */
if (blocks >= 8) if (blocks >= 8)
{ {
...@@ -424,18 +425,18 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ...@@ -424,18 +425,18 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) + ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) +
ALIGN_SIZE(sizeof(HASH_LINK*) * ALIGN_SIZE(sizeof(HASH_LINK*) *
keycache->hash_entries))) + keycache->hash_entries))) +
((ulong) blocks * keycache->key_cache_block_size) > use_mem) ((size_t) blocks * keycache->key_cache_block_size) > use_mem)
blocks--; blocks--;
/* Allocate memory for cache page buffers */ /* Allocate memory for cache page buffers */
if ((keycache->block_mem= if ((keycache->block_mem=
my_large_malloc((ulong) blocks * keycache->key_cache_block_size, my_large_malloc((size_t) blocks * keycache->key_cache_block_size,
MYF(MY_WME)))) MYF(MY_WME))))
{ {
/* /*
Allocate memory for blocks, hash_links and hash entries; Allocate memory for blocks, hash_links and hash entries;
For each block 2 hash links are allocated For each block 2 hash links are allocated
*/ */
if ((keycache->block_root= (BLOCK_LINK*) my_malloc((uint) length, if ((keycache->block_root= (BLOCK_LINK*) my_malloc(length,
MYF(0)))) MYF(0))))
break; break;
my_large_free(keycache->block_mem, MYF(0)); my_large_free(keycache->block_mem, MYF(0));
...@@ -448,7 +449,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ...@@ -448,7 +449,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
} }
blocks= blocks / 4*3; blocks= blocks / 4*3;
} }
keycache->blocks_unused= (ulong) blocks; keycache->blocks_unused= blocks;
keycache->disk_blocks= (int) blocks; keycache->disk_blocks= (int) blocks;
keycache->hash_links= hash_links; keycache->hash_links= hash_links;
keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root + keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root +
...@@ -556,7 +557,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ...@@ -556,7 +557,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
*/ */
int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
ulong use_mem, uint division_limit, size_t use_mem, uint division_limit,
uint age_threshold) uint age_threshold)
{ {
int blocks; int blocks;
......
...@@ -10198,7 +10198,7 @@ static bool open_tmp_table(TABLE *table) ...@@ -10198,7 +10198,7 @@ static bool open_tmp_table(TABLE *table)
{ {
int error; int error;
if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR, if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
HA_OPEN_TMP_TABLE))) HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
{ {
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
table->db_stat=0; table->db_stat=0;
...@@ -10436,8 +10436,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, ...@@ -10436,8 +10436,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
/* remove heap table and change to use myisam table */ /* remove heap table and change to use myisam table */
(void) table->file->ha_rnd_end(); (void) table->file->ha_rnd_end();
(void) table->file->close(); (void) table->file->close(); // This deletes the table !
(void) table->file->delete_table(table->s->table_name.str);
delete table->file; delete table->file;
table->file=0; table->file=0;
plugin_unlock(0, table->s->db_plugin); plugin_unlock(0, table->s->db_plugin);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include <mysql/plugin.h> #include <mysql/plugin.h>
#include "ha_heap.h" #include "ha_heap.h"
#include "heapdef.h"
static handler *heap_create_handler(handlerton *hton, static handler *heap_create_handler(handlerton *hton,
TABLE_SHARE *table, TABLE_SHARE *table,
...@@ -61,8 +61,8 @@ static handler *heap_create_handler(handlerton *hton, ...@@ -61,8 +61,8 @@ static handler *heap_create_handler(handlerton *hton,
*****************************************************************************/ *****************************************************************************/
ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg) ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), file(0), records_changed(0), :handler(hton, table_arg), file(0), records_changed(0), internal_table(0),
key_stat_version(0) key_stat_version(0)
{} {}
...@@ -90,13 +90,25 @@ const char **ha_heap::bas_ext() const ...@@ -90,13 +90,25 @@ const char **ha_heap::bas_ext() const
int ha_heap::open(const char *name, int mode, uint test_if_locked) 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; HA_CREATE_INFO create_info;
internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
bzero(&create_info, sizeof(create_info)); bzero(&create_info, sizeof(create_info));
file= 0;
if (!create(name, table, &create_info)) 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; implicit_emptied= 1;
} }
} }
...@@ -120,7 +132,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) ...@@ -120,7 +132,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
int ha_heap::close(void) 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) ...@@ -542,7 +554,7 @@ int ha_heap::delete_table(const char *name)
void ha_heap::drop_table(const char *name) void ha_heap::drop_table(const char *name)
{ {
heap_drop_table(file); file->s->delete_on_close= 1;
close(); close();
} }
...@@ -681,16 +693,16 @@ int ha_heap::create(const char *name, TABLE *table_arg, ...@@ -681,16 +693,16 @@ int ha_heap::create(const char *name, TABLE *table_arg,
create_info->auto_increment_value - 1 : 0); create_info->auto_increment_value - 1 : 0);
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; 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.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); max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row);
error= heap_create(name, error= heap_create(name,
keys, keydef, share->reclength, keys, keydef, share->reclength,
(ulong) ((share->max_rows < max_rows && (ulong) ((share->max_rows < max_rows &&
share->max_rows) ? share->max_rows) ?
share->max_rows : 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)); my_free((uchar*) keydef, MYF(0));
if (file) DBUG_ASSERT(file == 0);
info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
return (error); return (error);
} }
......
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
class ha_heap: public handler class ha_heap: public handler
{ {
HP_INFO *file; HP_INFO *file;
HP_SHARE *internal_share;
key_map btree_keys; key_map btree_keys;
/* number of records changed since last statistics update */ /* number of records changed since last statistics update */
uint records_changed; uint records_changed;
uint key_stat_version; uint key_stat_version;
my_bool internal_table;
public: public:
ha_heap(handlerton *hton, TABLE_SHARE *table); ha_heap(handlerton *hton, TABLE_SHARE *table);
~ha_heap() {} ~ha_heap() {}
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
/* This file is included in all heap-files */ /* This file is included in all heap-files */
#include <my_base.h> /* This includes global */ #include <my_base.h> /* This includes global */
C_MODE_START
#ifdef THREAD #ifdef THREAD
#include <my_pthread.h> #include <my_pthread.h>
#endif #endif
...@@ -107,3 +108,4 @@ extern pthread_mutex_t THR_LOCK_heap; ...@@ -107,3 +108,4 @@ extern pthread_mutex_t THR_LOCK_heap;
#define pthread_mutex_lock(A) #define pthread_mutex_lock(A)
#define pthread_mutex_unlock(A) #define pthread_mutex_unlock(A)
#endif #endif
C_MODE_END
...@@ -42,7 +42,8 @@ int hp_close(register HP_INFO *info) ...@@ -42,7 +42,8 @@ int hp_close(register HP_INFO *info)
} }
#endif #endif
info->s->changed=0; 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) if (!--info->s->open_count && info->s->delete_on_close)
hp_free(info->s); /* Table was deleted */ hp_free(info->s); /* Table was deleted */
my_free((uchar*) info,MYF(0)); my_free((uchar*) info,MYF(0));
......
...@@ -19,23 +19,27 @@ static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2); ...@@ -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, static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
ulong max_records); ulong max_records);
/* Create a heap table */
int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records, 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; uint i, j, key_segs, max_length, length;
HP_SHARE *share; HP_SHARE *share= 0;
HA_KEYSEG *keyseg; HA_KEYSEG *keyseg;
DBUG_ENTER("heap_create"); 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); pthread_mutex_lock(&THR_LOCK_heap);
share= NULL; if ((share= hp_find_named_heap(name)) && share->open_count == 0)
} {
hp_free(share);
share= 0;
}
}
if (!share) if (!share)
{ {
HP_KEYDEF *keyinfo; HP_KEYDEF *keyinfo;
...@@ -131,10 +135,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, ...@@ -131,10 +135,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
keys*sizeof(HP_KEYDEF)+ keys*sizeof(HP_KEYDEF)+
key_segs*sizeof(HA_KEYSEG), key_segs*sizeof(HA_KEYSEG),
MYF(MY_ZEROFILL)))) MYF(MY_ZEROFILL))))
{ goto err;
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(1);
}
share->keydef= (HP_KEYDEF*) (share + 1); share->keydef= (HP_KEYDEF*) (share + 1);
share->key_stat_version= 1; share->key_stat_version= 1;
keyseg= (HA_KEYSEG*) (share->keydef + keys); keyseg= (HA_KEYSEG*) (share->keydef + keys);
...@@ -189,20 +190,33 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, ...@@ -189,20 +190,33 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
if (!(share->name= my_strdup(name,MYF(0)))) if (!(share->name= my_strdup(name,MYF(0))))
{ {
my_free((uchar*) share,MYF(0)); my_free((uchar*) share,MYF(0));
pthread_mutex_unlock(&THR_LOCK_heap); goto err;
DBUG_RETURN(1);
} }
#ifdef THREAD #ifdef THREAD
thr_lock_init(&share->lock); thr_lock_init(&share->lock);
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST)); VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
#endif #endif
share->open_list.data= (void*) share; if (!create_info->internal_table)
heap_share_list= list_add(heap_share_list,&share->open_list); {
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); DBUG_RETURN(0);
err:
if (!create_info->internal_table)
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(1);
} /* heap_create */ } /* heap_create */
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
{ {
uint not_used[2]; uint not_used[2];
...@@ -279,7 +293,8 @@ void heap_drop_table(HP_INFO *info) ...@@ -279,7 +293,8 @@ void heap_drop_table(HP_INFO *info)
void hp_free(HP_SHARE *share) 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 */ hp_clear(share); /* Remove blocks from memory */
#ifdef THREAD #ifdef THREAD
thr_lock_delete(&share->lock); thr_lock_delete(&share->lock);
......
...@@ -22,43 +22,34 @@ ...@@ -22,43 +22,34 @@
#include "my_sys.h" #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_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) + if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO) +
2 * share->max_key_length, 2 * share->max_key_length,
MYF(MY_ZEROFILL)))) MYF(MY_ZEROFILL))))
{ {
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
share->open_count++; share->open_count++;
#ifdef THREAD #ifdef THREAD
thr_lock_data_init(&share->lock,&info->lock,NULL); thr_lock_data_init(&share->lock,&info->lock,NULL);
#endif #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->s= share;
info->lastkey= (uchar*) (info + 1); info->lastkey= (uchar*) (info + 1);
info->recbuf= (uchar*) (info->lastkey + share->max_key_length); info->recbuf= (uchar*) (info->lastkey + share->max_key_length);
info->mode= mode; info->mode= mode;
info->current_record= (ulong) ~0L; /* No current record */ info->current_record= (ulong) ~0L; /* No current record */
info->current_ptr= 0;
info->current_hash_ptr= 0;
info->lastinx= info->errkey= -1; info->lastinx= info->errkey= -1;
info->update= 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
info->opt_flag= READ_CHECK_USED; /* Check when changing */ info->opt_flag= READ_CHECK_USED; /* Check when changing */
#endif #endif
...@@ -68,7 +59,59 @@ HP_INFO *heap_open(const char *name, int mode) ...@@ -68,7 +59,59 @@ HP_INFO *heap_open(const char *name, int mode)
DBUG_RETURN(info); 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) HP_SHARE *hp_find_named_heap(const char *name)
{ {
......
...@@ -37,6 +37,7 @@ int main(int argc, char **argv) ...@@ -37,6 +37,7 @@ int main(int argc, char **argv)
HP_KEYDEF keyinfo[10]; HP_KEYDEF keyinfo[10];
HA_KEYSEG keyseg[4]; HA_KEYSEG keyseg[4];
HP_CREATE_INFO hp_create_info; HP_CREATE_INFO hp_create_info;
HP_SHARE *tmp_share;
MY_INIT(argv[0]); MY_INIT(argv[0]);
filename= "test1"; filename= "test1";
...@@ -52,6 +53,7 @@ int main(int argc, char **argv) ...@@ -52,6 +53,7 @@ int main(int argc, char **argv)
keyinfo[0].seg[0].start=1; keyinfo[0].seg[0].start=1;
keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].length=6;
keyinfo[0].seg[0].charset= &my_charset_latin1; keyinfo[0].seg[0].charset= &my_charset_latin1;
keyinfo[0].seg[0].null_bit= 0;
keyinfo[0].flag = HA_NOSAME; keyinfo[0].flag = HA_NOSAME;
deleted=0; deleted=0;
...@@ -59,7 +61,7 @@ int main(int argc, char **argv) ...@@ -59,7 +61,7 @@ int main(int argc, char **argv)
printf("- Creating heap-file\n"); printf("- Creating heap-file\n");
if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L, if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000L,10L,
&hp_create_info) || &hp_create_info, &tmp_share) ||
!(file= heap_open(filename, 2))) !(file= heap_open(filename, 2)))
goto err; goto err;
printf("- Writing records:s\n"); printf("- Writing records:s\n");
......
...@@ -59,6 +59,7 @@ int main(int argc, char *argv[]) ...@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
char record[128],record2[128],record3[128],key[10]; char record[128],record2[128],record3[128],key[10];
const char *filename,*filename2; const char *filename,*filename2;
HP_INFO *file,*file2; HP_INFO *file,*file2;
HP_SHARE *tmp_share;
HP_KEYDEF keyinfo[MAX_KEYS]; HP_KEYDEF keyinfo[MAX_KEYS];
HA_KEYSEG keyseg[MAX_KEYS*5]; HA_KEYSEG keyseg[MAX_KEYS*5];
HEAP_PTR position; HEAP_PTR position;
...@@ -126,7 +127,7 @@ int main(int argc, char *argv[]) ...@@ -126,7 +127,7 @@ int main(int argc, char *argv[])
printf("- Creating heap-file\n"); printf("- Creating heap-file\n");
if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L, 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))) !(file= heap_open(filename, 2)))
goto err; goto err;
signal(SIGINT,endprog); signal(SIGINT,endprog);
...@@ -562,8 +563,9 @@ int main(int argc, char *argv[]) ...@@ -562,8 +563,9 @@ int main(int argc, char *argv[])
heap_close(file2); heap_close(file2);
printf("- Creating output heap-file 2\n"); printf("- Creating output heap-file 2\n");
if (heap_create(filename2,1,keyinfo,reclength,0L,0L,&hp_create_info) || if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info,
!(file2= heap_open(filename2, 2))) &tmp_share) ||
!(file2= heap_open_from_share_and_register(tmp_share, 2)))
goto err; goto err;
printf("- Copying and removing records\n"); printf("- Copying and removing records\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment