mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
heap_create() <-> heap_open()
This commit is contained in:
166
heap/hp_create.c
166
heap/hp_create.c
@ -14,29 +14,156 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
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"
|
||||
|
||||
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");
|
||||
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);
|
||||
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, ¬_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)
|
||||
@ -46,32 +173,31 @@ int heap_delete_table(const char *name)
|
||||
DBUG_ENTER("heap_delete_table");
|
||||
|
||||
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)
|
||||
hp_free(share);
|
||||
else
|
||||
share->delete_on_close=1;
|
||||
result=0;
|
||||
share->delete_on_close= 1;
|
||||
result= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result=my_errno=ENOENT;
|
||||
result= my_errno=ENOENT;
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_heap);
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
#ifdef THREAD
|
||||
thr_lock_delete(&share->lock);
|
||||
VOID(pthread_mutex_destroy(&share->intern_lock));
|
||||
#endif
|
||||
my_free((gptr) share->name,MYF(0));
|
||||
my_free((gptr) share,MYF(0));
|
||||
my_free((gptr) share->name, MYF(0));
|
||||
my_free((gptr) share, MYF(0));
|
||||
return;
|
||||
}
|
||||
|
153
heap/hp_open.c
153
heap/hp_open.c
@ -23,123 +23,20 @@
|
||||
|
||||
#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, ¬_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_SHARE *share;
|
||||
HA_KEYSEG *keyseg;
|
||||
|
||||
DBUG_ENTER("heap_open");
|
||||
|
||||
pthread_mutex_lock(&THR_LOCK_heap);
|
||||
if (!(share = hp_find_named_heap(name)))
|
||||
if (!(share= hp_find_named_heap(name)))
|
||||
{
|
||||
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(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);
|
||||
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,
|
||||
MYF(MY_ZEROFILL))))
|
||||
{
|
||||
@ -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",
|
||||
info,share->reclength,share->block.records_in_block));
|
||||
DBUG_RETURN(info);
|
||||
} /* heap_open */
|
||||
|
||||
}
|
||||
|
||||
/* 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)
|
||||
DBUG_ENTER("heap_find");
|
||||
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;
|
||||
if (!strcmp(name,info->name))
|
||||
info= (HP_SHARE*) pos->data;
|
||||
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((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)
|
||||
bzero((gptr) flags,sizeof(flags));
|
||||
|
||||
printf("- Creating heap-file\n");
|
||||
heap_create(filename);
|
||||
if (!(file=heap_open(filename,2,1,keyinfo,30,(ulong) flag*100000l,10l)))
|
||||
if (heap_create(filename,1,keyinfo,30,(ulong) flag*100000l,10l) ||
|
||||
!(file= heap_open(filename, 2)))
|
||||
goto err;
|
||||
printf("- Writing records:s\n");
|
||||
strmov(record," ..... key ");
|
||||
@ -77,7 +77,7 @@ int main(int argc, char **argv)
|
||||
if (heap_close(file))
|
||||
goto err;
|
||||
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;
|
||||
|
||||
printf("- Removing records\n");
|
||||
|
@ -81,6 +81,7 @@ int main(int argc, char *argv[])
|
||||
keyinfo[0].seg[0].start=0;
|
||||
keyinfo[0].seg[0].length=6;
|
||||
keyinfo[0].seg[0].null_bit=0;
|
||||
keyinfo[0].seg[0].charset=default_charset_info;
|
||||
keyinfo[1].seg=keyseg+1;
|
||||
keyinfo[1].keysegs=2;
|
||||
keyinfo[1].flag=0;
|
||||
@ -88,10 +89,12 @@ int main(int argc, char *argv[])
|
||||
keyinfo[1].seg[0].start=7;
|
||||
keyinfo[1].seg[0].length=6;
|
||||
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].start=0; /* key in two parts */
|
||||
keyinfo[1].seg[1].length=6;
|
||||
keyinfo[1].seg[1].null_bit=0;
|
||||
keyinfo[1].seg[1].charset=default_charset_info;
|
||||
keyinfo[2].seg=keyseg+3;
|
||||
keyinfo[2].keysegs=1;
|
||||
keyinfo[2].flag=HA_NOSAME;
|
||||
@ -99,6 +102,7 @@ int main(int argc, char *argv[])
|
||||
keyinfo[2].seg[0].start=12;
|
||||
keyinfo[2].seg[0].length=8;
|
||||
keyinfo[2].seg[0].null_bit=0;
|
||||
keyinfo[2].seg[0].charset=default_charset_info;
|
||||
keyinfo[3].keysegs=1;
|
||||
keyinfo[3].flag=HA_NOSAME;
|
||||
keyinfo[3].seg=keyseg+4;
|
||||
@ -107,15 +111,15 @@ int main(int argc, char *argv[])
|
||||
keyinfo[3].seg[0].length=1;
|
||||
keyinfo[3].seg[0].null_bit=1;
|
||||
keyinfo[3].seg[0].null_pos=38;
|
||||
keyinfo[3].seg[0].charset=default_charset_info;
|
||||
|
||||
bzero((char*) key1,sizeof(key1));
|
||||
bzero((char*) key3,sizeof(key3));
|
||||
|
||||
printf("- Creating heap-file\n");
|
||||
if (heap_create(filename))
|
||||
goto err;
|
||||
if (!(file=heap_open(filename,2,keys,keyinfo,reclength,(ulong) flag*100000L,
|
||||
(ulong) recant/2)))
|
||||
if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
|
||||
(ulong) recant/2) ||
|
||||
!(file= heap_open(filename, 2)))
|
||||
goto err;
|
||||
signal(SIGINT,endprog);
|
||||
|
||||
@ -530,7 +534,7 @@ int main(int argc, char *argv[])
|
||||
if (testflag == 4) goto end;
|
||||
|
||||
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;
|
||||
if (heap_scan_init(file))
|
||||
goto err;
|
||||
@ -549,7 +553,7 @@ int main(int argc, char *argv[])
|
||||
heap_close(file2);
|
||||
|
||||
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;
|
||||
|
||||
printf("- Copying and removing records\n");
|
||||
|
@ -142,9 +142,7 @@ typedef struct st_heap_info
|
||||
|
||||
/* Prototypes for heap-functions */
|
||||
|
||||
extern HP_INFO* heap_open(const char *name,int mode,uint keys,
|
||||
HP_KEYDEF *keydef,uint reclength,
|
||||
ulong max_records,ulong min_reloc);
|
||||
extern HP_INFO *heap_open(const char *name, int mode);
|
||||
extern int heap_close(HP_INFO *info);
|
||||
extern int heap_write(HP_INFO *info,const byte *buff);
|
||||
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);
|
||||
extern int heap_scan(register HP_INFO *info, byte *record);
|
||||
extern int heap_delete(HP_INFO *info,const byte *buff);
|
||||
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_extra(HP_INFO *info,enum ha_extra_function function);
|
||||
extern int heap_rename(const char *old_name,const char *new_name);
|
||||
|
180
sql/ha_heap.cc
180
sql/ha_heap.cc
@ -33,92 +33,12 @@ const char **ha_heap::bas_ext() const
|
||||
|
||||
int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
uint key,parts,mem_per_row=0;
|
||||
ulong max_rows;
|
||||
HP_KEYDEF *keydef;
|
||||
HA_KEYSEG *seg;
|
||||
|
||||
for (key=parts=0 ; key < table->keys ; key++)
|
||||
if (!(file= heap_open(name, mode)) && my_errno == ENOENT)
|
||||
{
|
||||
parts+=table->key_info[key].key_parts;
|
||||
if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE)
|
||||
parts++; /* additional HA_KEYTYPE_END keyseg */
|
||||
if (!create(name, table, NULL))
|
||||
file= heap_open(name, mode);
|
||||
}
|
||||
|
||||
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);
|
||||
return (file ? 0 : 1);
|
||||
}
|
||||
|
||||
int ha_heap::close(void)
|
||||
@ -274,7 +194,6 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd,
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
We have to ignore ENOENT entries as the HEAP table is created on open and
|
||||
not when doing a CREATE on the table.
|
||||
@ -291,7 +210,6 @@ int ha_heap::rename_table(const char * from, const char * to)
|
||||
return heap_rename(from,to);
|
||||
}
|
||||
|
||||
|
||||
ha_rows ha_heap::records_in_range(int inx,
|
||||
const byte *start_key,uint start_key_len,
|
||||
enum ha_rkey_function start_search_flag,
|
||||
@ -315,10 +233,92 @@ ha_rows ha_heap::records_in_range(int inx,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
|
||||
|
||||
int ha_heap::create(const char *name, TABLE *table, 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];
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user