Commit 6192996d authored by unknown's avatar unknown

heap_create() <-> heap_open()

parent fa86b948
...@@ -14,29 +14,156 @@ ...@@ -14,29 +14,156 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Create is done by simply remove the database from memory if it exists.
Open creates the database when neaded
*/
#include "heapdef.h" #include "heapdef.h"
int heap_create(const char *name) 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);
int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records)
{ {
reg1 HP_SHARE *share; uint i, j, key_segs, max_length, length;
HP_SHARE *share;
HA_KEYSEG *keyseg;
DBUG_ENTER("heap_create"); DBUG_ENTER("heap_create");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if ((share=hp_find_named_heap(name)))
if ((share= hp_find_named_heap(name)) && share->open_count == 0)
{ {
if (share->open_count == 0) hp_free(share);
hp_free(share); share= NULL;
} }
else
if (!share)
{ {
my_errno=ENOENT; HP_KEYDEF *keyinfo;
DBUG_PRINT("info",("Initializing new table"));
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
{
bzero((char*) &keyinfo->block,sizeof(keyinfo->block));
bzero((char*) &keyinfo->rb_tree ,sizeof(keyinfo->rb_tree));
for (j= length= 0; j < keyinfo->keysegs; j++)
{
length+= keyinfo->seg[j].length;
if (keyinfo->seg[j].null_bit)
{
if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
keyinfo->flag|= HA_NULL_PART_KEY;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
keyinfo->rb_tree.size_of_element++;
}
}
keyinfo->length= length;
length+= keyinfo->rb_tree.size_of_element +
((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(byte*) : 0);
if (length > max_length)
max_length= length;
key_segs+= keyinfo->keysegs;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{
key_segs++; /* additional HA_KEYTYPE_END segment */
if (keyinfo->flag & HA_NULL_PART_KEY)
keyinfo->get_key_length= hp_rb_null_key_length;
else
keyinfo->get_key_length= hp_rb_key_length;
}
}
if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
keys*sizeof(HP_KEYDEF)+
key_segs*sizeof(HA_KEYSEG),
MYF(MY_ZEROFILL))))
{
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(1);
}
share->keydef= (HP_KEYDEF*) (share + 1);
keyseg= (HA_KEYSEG*) (share->keydef + keys);
init_block(&share->block, reclength + 1, min_records, max_records);
/* Fix keys */
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
{
uint nsegs= keydef[i].keysegs;
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
{
init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*),
(qsort_cmp2)keys_compare, 1, NULL, NULL);
keyinfo->delete_key= hp_rb_delete_key;
keyinfo->write_key= hp_rb_write_key;
nsegs++;
}
else
{
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
max_records);
keyinfo->delete_key= hp_delete_key;
keyinfo->write_key= hp_write_key;
}
keyinfo->seg= keyseg;
memcpy(keyseg, keydef[i].seg,
(size_t) (sizeof(keyseg[0]) * nsegs));
keyseg+= nsegs;
}
share->min_records= min_records;
share->max_records= max_records;
share->data_length= share->index_length= 0;
share->reclength= reclength;
share->blength= 1;
share->keys= keys;
share->max_key_length= max_length;
share->changed= 0;
if (!(share->name= my_strdup(name,MYF(0))))
{
my_free((gptr) share,MYF(0));
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(1);
}
#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);
} }
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0); DBUG_RETURN(0);
} /* heap_create */
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
{
uint not_used;
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
param->search_flag, &not_used);
}
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
ulong max_records)
{
uint i,recbuffer,records_in_block;
max_records= max(min_records,max_records);
if (!max_records)
max_records= 1000; /* As good as quess as anything */
recbuffer= (uint) (reclength + sizeof(byte**) - 1) & ~(sizeof(byte**) - 1);
records_in_block= max_records / 10;
if (records_in_block < 10 && max_records)
records_in_block= 10;
if (!records_in_block || records_in_block*recbuffer >
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
HP_MAX_LEVELS) / recbuffer + 1;
block->records_in_block= records_in_block;
block->recbuffer= recbuffer;
block->last_allocated= 0L;
for (i= 0; i <= HP_MAX_LEVELS; i++)
block->level_info[i].records_under_level=
(!i ? 1 : i == 1 ? records_in_block :
HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
} }
int heap_delete_table(const char *name) int heap_delete_table(const char *name)
...@@ -46,32 +173,31 @@ int heap_delete_table(const char *name) ...@@ -46,32 +173,31 @@ int heap_delete_table(const char *name)
DBUG_ENTER("heap_delete_table"); DBUG_ENTER("heap_delete_table");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if ((share = hp_find_named_heap(name))) if ((share= hp_find_named_heap(name)))
{ {
if (share->open_count == 0) if (share->open_count == 0)
hp_free(share); hp_free(share);
else else
share->delete_on_close=1; share->delete_on_close= 1;
result=0; result= 0;
} }
else else
{ {
result=my_errno=ENOENT; result= my_errno=ENOENT;
} }
pthread_mutex_unlock(&THR_LOCK_heap); pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(result); DBUG_RETURN(result);
} }
void hp_free(HP_SHARE *share) void hp_free(HP_SHARE *share)
{ {
heap_share_list=list_delete(heap_share_list,&share->open_list); 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);
VOID(pthread_mutex_destroy(&share->intern_lock)); VOID(pthread_mutex_destroy(&share->intern_lock));
#endif #endif
my_free((gptr) share->name,MYF(0)); my_free((gptr) share->name, MYF(0));
my_free((gptr) share,MYF(0)); my_free((gptr) share, MYF(0));
return; return;
} }
...@@ -23,130 +23,27 @@ ...@@ -23,130 +23,27 @@
#include "my_sys.h" #include "my_sys.h"
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) HP_INFO *heap_open(const char *name, int mode)
{ {
uint not_used;
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
param->search_flag, &not_used);
}
static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
ulong max_records);
/* open a heap database. */
HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records)
{
uint i,j,key_segs,max_length,length;
HP_INFO *info; HP_INFO *info;
HP_SHARE *share; HP_SHARE *share;
HA_KEYSEG *keyseg;
DBUG_ENTER("heap_open"); DBUG_ENTER("heap_open");
pthread_mutex_lock(&THR_LOCK_heap); pthread_mutex_lock(&THR_LOCK_heap);
if (!(share = hp_find_named_heap(name))) if (!(share= hp_find_named_heap(name)))
{ {
HP_KEYDEF *keyinfo; my_errno= ENOENT;
DBUG_PRINT("info",("Initializing new table")); pthread_mutex_unlock(&THR_LOCK_heap);
for (i=key_segs=max_length=0, keyinfo= keydef; i < keys; i++, keyinfo++) DBUG_RETURN(0);
{
bzero((char*) &keyinfo->block,sizeof(keyinfo->block));
bzero((char*) &keyinfo->rb_tree ,sizeof(keyinfo->rb_tree));
for (j=length=0 ; j < keyinfo->keysegs; j++)
{
length+=keyinfo->seg[j].length;
if (keyinfo->seg[j].null_bit)
{
if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
keyinfo->flag |= HA_NULL_PART_KEY;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
keyinfo->rb_tree.size_of_element++;
}
}
keyinfo->length= length;
length+= keyinfo->rb_tree.size_of_element +
((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(byte*) : 0);
if (length > max_length)
max_length= length;
key_segs+= keyinfo->keysegs;
if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
{
key_segs++; /* additional HA_KEYTYPE_END segment */
if (keyinfo->flag & HA_NULL_PART_KEY)
keyinfo->get_key_length = hp_rb_null_key_length;
else
keyinfo->get_key_length = hp_rb_key_length;
}
}
if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
keys*sizeof(HP_KEYDEF)+
key_segs*sizeof(HA_KEYSEG),
MYF(MY_ZEROFILL))))
{
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
share->keydef= (HP_KEYDEF*) (share + 1);
keyseg= (HA_KEYSEG*) (share->keydef + keys);
init_block(&share->block, reclength + 1, min_records, max_records);
/* Fix keys */
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
{
uint nsegs= keydef[i].keysegs;
if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
{
init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*),
(qsort_cmp2)keys_compare, 1, NULL, NULL);
keyinfo->delete_key= hp_rb_delete_key;
keyinfo->write_key= hp_rb_write_key;
nsegs++;
}
else
{
init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
max_records);
keyinfo->delete_key= hp_delete_key;
keyinfo->write_key= hp_write_key;
}
keyinfo->seg= keyseg;
memcpy(keyseg, keydef[i].seg,
(size_t) (sizeof(keyseg[0]) * nsegs));
keyseg+= nsegs;
}
share->min_records= min_records;
share->max_records= max_records;
share->data_length= share->index_length= 0;
share->reclength= reclength;
share->blength= 1;
share->keys= keys;
share->max_key_length= max_length;
share->changed= 0;
if (!(share->name= my_strdup(name,MYF(0))))
{
my_free((gptr) share,MYF(0));
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
#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 (!(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); 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
...@@ -169,8 +66,7 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef, ...@@ -169,8 +66,7 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d", DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d",
info,share->reclength,share->block.records_in_block)); info,share->reclength,share->block.records_in_block));
DBUG_RETURN(info); DBUG_RETURN(info);
} /* heap_open */ }
/* map name to a heap-nr. If name isn't found return 0 */ /* map name to a heap-nr. If name isn't found return 0 */
...@@ -181,41 +77,16 @@ HP_SHARE *hp_find_named_heap(const char *name) ...@@ -181,41 +77,16 @@ HP_SHARE *hp_find_named_heap(const char *name)
DBUG_ENTER("heap_find"); DBUG_ENTER("heap_find");
DBUG_PRINT("enter",("name: %s",name)); DBUG_PRINT("enter",("name: %s",name));
for (pos=heap_share_list ; pos ; pos=pos->next) for (pos= heap_share_list; pos; pos= pos->next)
{ {
info=(HP_SHARE*) pos->data; info= (HP_SHARE*) pos->data;
if (!strcmp(name,info->name)) if (!strcmp(name, info->name))
{ {
DBUG_PRINT("exit",("Old heap_database: %lx",info)); DBUG_PRINT("exit", ("Old heap_database: %lx",info));
DBUG_RETURN(info); DBUG_RETURN(info);
} }
} }
DBUG_RETURN((HP_SHARE *)0); DBUG_RETURN((HP_SHARE *) 0);
} }
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
ulong max_records)
{
uint i,recbuffer,records_in_block;
max_records=max(min_records,max_records);
if (!max_records)
max_records=1000; /* As good as quess as anything */
recbuffer=(uint) (reclength+sizeof(byte**)-1) & ~(sizeof(byte**)-1);
records_in_block=max_records/10;
if (records_in_block < 10 && max_records)
records_in_block=10;
if (!records_in_block || records_in_block*recbuffer >
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block=(my_default_record_cache_size-sizeof(HP_PTRS)*
HP_MAX_LEVELS)/recbuffer+1;
block->records_in_block=records_in_block;
block->recbuffer=recbuffer;
block->last_allocated= 0L;
for (i=0 ; i <= HP_MAX_LEVELS ; i++)
block->level_info[i].records_under_level=
(!i ? 1 : i == 1 ? records_in_block :
HP_PTRS_IN_NOD * block->level_info[i-1].records_under_level);
}
...@@ -53,8 +53,8 @@ int main(int argc, char **argv) ...@@ -53,8 +53,8 @@ int main(int argc, char **argv)
bzero((gptr) flags,sizeof(flags)); bzero((gptr) flags,sizeof(flags));
printf("- Creating heap-file\n"); printf("- Creating heap-file\n");
heap_create(filename); if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l) ||
if (!(file=heap_open(filename,2,1,keyinfo,30,(ulong) flag*100000l,10l))) !(file= heap_open(filename, 2)))
goto err; goto err;
printf("- Writing records:s\n"); printf("- Writing records:s\n");
strmov(record," ..... key "); strmov(record," ..... key ");
...@@ -77,7 +77,7 @@ int main(int argc, char **argv) ...@@ -77,7 +77,7 @@ int main(int argc, char **argv)
if (heap_close(file)) if (heap_close(file))
goto err; goto err;
printf("- Reopening file\n"); printf("- Reopening file\n");
if (!(file=heap_open(filename,2,1,keyinfo,30,(ulong) flag*100000l,10l))) if (!(file=heap_open(filename, 2)))
goto err; goto err;
printf("- Removing records\n"); printf("- Removing records\n");
......
...@@ -81,6 +81,7 @@ int main(int argc, char *argv[]) ...@@ -81,6 +81,7 @@ int main(int argc, char *argv[])
keyinfo[0].seg[0].start=0; keyinfo[0].seg[0].start=0;
keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].length=6;
keyinfo[0].seg[0].null_bit=0; keyinfo[0].seg[0].null_bit=0;
keyinfo[0].seg[0].charset=default_charset_info;
keyinfo[1].seg=keyseg+1; keyinfo[1].seg=keyseg+1;
keyinfo[1].keysegs=2; keyinfo[1].keysegs=2;
keyinfo[1].flag=0; keyinfo[1].flag=0;
...@@ -88,10 +89,12 @@ int main(int argc, char *argv[]) ...@@ -88,10 +89,12 @@ int main(int argc, char *argv[])
keyinfo[1].seg[0].start=7; keyinfo[1].seg[0].start=7;
keyinfo[1].seg[0].length=6; keyinfo[1].seg[0].length=6;
keyinfo[1].seg[0].null_bit=0; keyinfo[1].seg[0].null_bit=0;
keyinfo[1].seg[0].charset=default_charset_info;
keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT; keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT;
keyinfo[1].seg[1].start=0; /* key in two parts */ keyinfo[1].seg[1].start=0; /* key in two parts */
keyinfo[1].seg[1].length=6; keyinfo[1].seg[1].length=6;
keyinfo[1].seg[1].null_bit=0; keyinfo[1].seg[1].null_bit=0;
keyinfo[1].seg[1].charset=default_charset_info;
keyinfo[2].seg=keyseg+3; keyinfo[2].seg=keyseg+3;
keyinfo[2].keysegs=1; keyinfo[2].keysegs=1;
keyinfo[2].flag=HA_NOSAME; keyinfo[2].flag=HA_NOSAME;
...@@ -99,6 +102,7 @@ int main(int argc, char *argv[]) ...@@ -99,6 +102,7 @@ int main(int argc, char *argv[])
keyinfo[2].seg[0].start=12; keyinfo[2].seg[0].start=12;
keyinfo[2].seg[0].length=8; keyinfo[2].seg[0].length=8;
keyinfo[2].seg[0].null_bit=0; keyinfo[2].seg[0].null_bit=0;
keyinfo[2].seg[0].charset=default_charset_info;
keyinfo[3].keysegs=1; keyinfo[3].keysegs=1;
keyinfo[3].flag=HA_NOSAME; keyinfo[3].flag=HA_NOSAME;
keyinfo[3].seg=keyseg+4; keyinfo[3].seg=keyseg+4;
...@@ -107,15 +111,15 @@ int main(int argc, char *argv[]) ...@@ -107,15 +111,15 @@ int main(int argc, char *argv[])
keyinfo[3].seg[0].length=1; keyinfo[3].seg[0].length=1;
keyinfo[3].seg[0].null_bit=1; keyinfo[3].seg[0].null_bit=1;
keyinfo[3].seg[0].null_pos=38; keyinfo[3].seg[0].null_pos=38;
keyinfo[3].seg[0].charset=default_charset_info;
bzero((char*) key1,sizeof(key1)); bzero((char*) key1,sizeof(key1));
bzero((char*) key3,sizeof(key3)); bzero((char*) key3,sizeof(key3));
printf("- Creating heap-file\n"); printf("- Creating heap-file\n");
if (heap_create(filename)) if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
goto err; (ulong) recant/2) ||
if (!(file=heap_open(filename,2,keys,keyinfo,reclength,(ulong) flag*100000L, !(file= heap_open(filename, 2)))
(ulong) recant/2)))
goto err; goto err;
signal(SIGINT,endprog); signal(SIGINT,endprog);
...@@ -530,7 +534,7 @@ int main(int argc, char *argv[]) ...@@ -530,7 +534,7 @@ int main(int argc, char *argv[])
if (testflag == 4) goto end; if (testflag == 4) goto end;
printf("- Reading through all rows through keys\n"); printf("- Reading through all rows through keys\n");
if (!(file2=heap_open(filename,2,0,0,0,0,0))) if (!(file2=heap_open(filename, 2)))
goto err; goto err;
if (heap_scan_init(file)) if (heap_scan_init(file))
goto err; goto err;
...@@ -549,7 +553,7 @@ int main(int argc, char *argv[]) ...@@ -549,7 +553,7 @@ 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 (!(file2=heap_open(filename2,2,1,keyinfo,reclength,0L,0L))) if (!(file2=heap_open(filename2, 2)))
goto err; goto err;
printf("- Copying and removing records\n"); printf("- Copying and removing records\n");
......
...@@ -142,9 +142,7 @@ typedef struct st_heap_info ...@@ -142,9 +142,7 @@ typedef struct st_heap_info
/* Prototypes for heap-functions */ /* Prototypes for heap-functions */
extern HP_INFO* heap_open(const char *name,int mode,uint keys, extern HP_INFO *heap_open(const char *name, int mode);
HP_KEYDEF *keydef,uint reclength,
ulong max_records,ulong min_reloc);
extern int heap_close(HP_INFO *info); extern int heap_close(HP_INFO *info);
extern int heap_write(HP_INFO *info,const byte *buff); extern int heap_write(HP_INFO *info,const byte *buff);
extern int heap_update(HP_INFO *info,const byte *old,const byte *newdata); extern int heap_update(HP_INFO *info,const byte *old,const byte *newdata);
...@@ -153,7 +151,8 @@ extern int heap_scan_init(HP_INFO *info); ...@@ -153,7 +151,8 @@ extern int heap_scan_init(HP_INFO *info);
extern int heap_scan(register HP_INFO *info, byte *record); extern int heap_scan(register HP_INFO *info, byte *record);
extern int heap_delete(HP_INFO *info,const byte *buff); extern int heap_delete(HP_INFO *info,const byte *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); extern int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
uint reclength, ulong max_records, ulong min_records);
extern int heap_delete_table(const char *name); extern int heap_delete_table(const char *name);
extern int heap_extra(HP_INFO *info,enum ha_extra_function function); extern int heap_extra(HP_INFO *info,enum ha_extra_function function);
extern int heap_rename(const char *old_name,const char *new_name); extern int heap_rename(const char *old_name,const char *new_name);
......
...@@ -33,92 +33,12 @@ const char **ha_heap::bas_ext() const ...@@ -33,92 +33,12 @@ 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)
{ {
uint key,parts,mem_per_row=0; if (!(file= heap_open(name, mode)) && my_errno == ENOENT)
ulong max_rows;
HP_KEYDEF *keydef;
HA_KEYSEG *seg;
for (key=parts=0 ; key < table->keys ; key++)
{ {
parts+=table->key_info[key].key_parts; if (!create(name, table, NULL))
if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) file= heap_open(name, mode);
parts++; /* additional HA_KEYTYPE_END keyseg */
} }
return (file ? 0 : 1);
if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+
parts*sizeof(HA_KEYSEG),MYF(MY_WME))))
return my_errno;
seg=my_reinterpret_cast(HA_KEYSEG*) (keydef+table->keys);
for (key=0 ; key < table->keys ; key++)
{
KEY *pos=table->key_info+key;
KEY_PART_INFO *key_part= pos->key_part;
KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
mem_per_row+= (pos->key_length + (sizeof(char*) * 2));
keydef[key].keysegs= (uint) pos->key_parts;
keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
keydef[key].seg= seg;
keydef[key].algorithm= pos->algorithm == HA_KEY_ALG_UNDEF ?
HA_KEY_ALG_HASH : pos->algorithm;
for (; key_part != key_part_end ; key_part++, seg++)
{
uint flag= key_part->key_type;
Field *field= key_part->field;
if (pos->algorithm == HA_KEY_ALG_BTREE)
{
seg->type= field->key_type();
}
else
{
if (!f_is_packed(flag) &&
f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
!(flag & FIELDFLAG_BINARY))
seg->type= (int) HA_KEYTYPE_TEXT;
else
seg->type= (int) HA_KEYTYPE_BINARY;
}
seg->start= (uint) key_part->offset;
seg->length= (uint) key_part->length;
seg->flag = 0;
seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset();
if (field->null_ptr)
{
seg->null_bit= field->null_bit;
seg->null_pos= (uint) (field->null_ptr-
(uchar*) table->record[0]);
}
else
{
seg->null_bit= 0;
seg->null_pos= 0;
}
}
if (pos->algorithm == HA_KEY_ALG_BTREE)
{
/* additional HA_KEYTYPE_END keyseg */
seg->type= HA_KEYTYPE_END;
seg->length= sizeof(byte*);
seg->flag= 0;
seg->null_bit= 0;
seg++;
}
}
mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
max_rows = (ulong) (max_heap_table_size / mem_per_row);
file=heap_open(name,mode,
table->keys,keydef,
table->reclength,
((table->max_rows < max_rows && table->max_rows) ?
table->max_rows : max_rows),
table->min_rows);
my_free((gptr) keydef,MYF(0));
if (file)
info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
ref_length=sizeof(HEAP_PTR);
return (!file ? errno : 0);
} }
int ha_heap::close(void) int ha_heap::close(void)
...@@ -274,7 +194,6 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd, ...@@ -274,7 +194,6 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
return to; return to;
} }
/* /*
We have to ignore ENOENT entries as the HEAP table is created on open and We have to ignore ENOENT entries as the HEAP table is created on open and
not when doing a CREATE on the table. not when doing a CREATE on the table.
...@@ -291,7 +210,6 @@ int ha_heap::rename_table(const char * from, const char * to) ...@@ -291,7 +210,6 @@ int ha_heap::rename_table(const char * from, const char * to)
return heap_rename(from,to); return heap_rename(from,to);
} }
ha_rows ha_heap::records_in_range(int inx, ha_rows ha_heap::records_in_range(int inx,
const byte *start_key,uint start_key_len, const byte *start_key,uint start_key_len,
enum ha_rkey_function start_search_flag, enum ha_rkey_function start_search_flag,
...@@ -315,10 +233,92 @@ ha_rows ha_heap::records_in_range(int inx, ...@@ -315,10 +233,92 @@ ha_rows ha_heap::records_in_range(int inx,
} }
} }
int ha_heap::create(const char *name, TABLE *table, HA_CREATE_INFO *create_info)
int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
{ {
uint key, parts, mem_per_row= 0;
ulong max_rows;
HP_KEYDEF *keydef;
HA_KEYSEG *seg;
char buff[FN_REFLEN]; char buff[FN_REFLEN];
return heap_create(fn_format(buff,name,"","",4+2)); int error;
for (key= parts= 0; key < table->keys; key++)
{
parts+= table->key_info[key].key_parts;
if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE)
parts++; /* additional HA_KEYTYPE_END keyseg */
}
if (!(keydef= (HP_KEYDEF*) my_malloc(table->keys * sizeof(HP_KEYDEF) +
parts * sizeof(HA_KEYSEG), MYF(MY_WME))))
return my_errno;
seg= my_reinterpret_cast(HA_KEYSEG*) (keydef + table->keys);
for (key= 0; key < table->keys; key++)
{
KEY *pos= table->key_info+key;
KEY_PART_INFO *key_part= pos->key_part;
KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
mem_per_row+= (pos->key_length + (sizeof(char*) * 2));
keydef[key].keysegs= (uint) pos->key_parts;
keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
keydef[key].seg= seg;
keydef[key].algorithm= pos->algorithm == HA_KEY_ALG_UNDEF ?
HA_KEY_ALG_HASH : pos->algorithm;
for (; key_part != key_part_end; key_part++, seg++)
{
uint flag= key_part->key_type;
Field *field= key_part->field;
if (pos->algorithm == HA_KEY_ALG_BTREE)
{
seg->type= field->key_type();
}
else
{
if (!f_is_packed(flag) &&
f_packtype(flag) == (int) FIELD_TYPE_DECIMAL &&
!(flag & FIELDFLAG_BINARY))
seg->type= (int) HA_KEYTYPE_TEXT;
else
seg->type= (int) HA_KEYTYPE_BINARY;
}
seg->start= (uint) key_part->offset;
seg->length= (uint) key_part->length;
seg->flag = 0;
seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset();
if (field->null_ptr)
{
seg->null_bit= field->null_bit;
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
}
else
{
seg->null_bit= 0;
seg->null_pos= 0;
}
}
if (pos->algorithm == HA_KEY_ALG_BTREE)
{
/* additional HA_KEYTYPE_END keyseg */
seg->type= HA_KEYTYPE_END;
seg->length= sizeof(byte*);
seg->flag= 0;
seg->null_bit= 0;
seg++;
}
}
mem_per_row+= MY_ALIGN(table->reclength + 1, sizeof(char*));
max_rows= (ulong) (max_heap_table_size / mem_per_row);
error= heap_create(fn_format(buff,name,"","",4+2),
table->keys,keydef, table->reclength,
((table->max_rows < max_rows && table->max_rows) ?
table->max_rows : max_rows),
table->min_rows);
my_free((gptr) keydef, MYF(0));
if (file)
info(HA_STATUS_NO_LOCK | HA_STATUS_CONST | HA_STATUS_VARIABLE);
ref_length= sizeof(HEAP_PTR);
return (error);
} }
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