diff options
author | ram@gw.udmsearch.izhnet.ru <> | 2002-06-07 16:47:36 +0500 |
---|---|---|
committer | ram@gw.udmsearch.izhnet.ru <> | 2002-06-07 16:47:36 +0500 |
commit | 59537790531ff472710ccac80764908209d1d3d9 (patch) | |
tree | 563098f1aa3cf848c7c56670c3c82ebf4dd4a9d6 | |
parent | ab1a2731988f73ecb6df0452768e989ef735259d (diff) | |
download | mariadb-git-59537790531ff472710ccac80764908209d1d3d9.tar.gz |
heap_create() <-> heap_open()
-rw-r--r-- | heap/hp_create.c | 166 | ||||
-rw-r--r-- | heap/hp_open.c | 155 | ||||
-rw-r--r-- | heap/hp_test1.c | 6 | ||||
-rw-r--r-- | heap/hp_test2.c | 16 | ||||
-rw-r--r-- | include/heap.h | 7 | ||||
-rw-r--r-- | sql/ha_heap.cc | 180 |
6 files changed, 265 insertions, 265 deletions
diff --git a/heap/hp_create.c b/heap/hp_create.c index 99f4cb0146d..4163f5b0217 100644 --- a/heap/hp_create.c +++ b/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; } diff --git a/heap/hp_open.c b/heap/hp_open.c index d48423c506a..1fa832208fb 100644 --- a/heap/hp_open.c +++ b/heap/hp_open.c @@ -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, ¬_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); -} diff --git a/heap/hp_test1.c b/heap/hp_test1.c index 79edfe2effc..f619ac2e8db 100644 --- a/heap/hp_test1.c +++ b/heap/hp_test1.c @@ -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"); diff --git a/heap/hp_test2.c b/heap/hp_test2.c index a972e7073e0..e687bdab127 100644 --- a/heap/hp_test2.c +++ b/heap/hp_test2.c @@ -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"); diff --git a/include/heap.h b/include/heap.h index 53757f51e73..359c4346a5d 100644 --- a/include/heap.h +++ b/include/heap.h @@ -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); diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 70409be4e42..f56bfe74265 100644 --- a/sql/ha_heap.cc +++ b/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); } |