heap_create() <-> heap_open()

parent ab1a2731
......@@ -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, &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)
......@@ -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;
}
......@@ -23,130 +23,27 @@
#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_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))))
{
pthread_mutex_unlock(&THR_LOCK_heap);
DBUG_RETURN(0);
}
share->open_count++;
share->open_count++;
#ifdef THREAD
thr_lock_data_init(&share->lock,&info->lock,NULL);
#endif
......@@ -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);
......
......@@ -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);
}
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