summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorram@gw.udmsearch.izhnet.ru <>2002-06-07 16:47:36 +0500
committerram@gw.udmsearch.izhnet.ru <>2002-06-07 16:47:36 +0500
commit59537790531ff472710ccac80764908209d1d3d9 (patch)
tree563098f1aa3cf848c7c56670c3c82ebf4dd4a9d6
parentab1a2731988f73ecb6df0452768e989ef735259d (diff)
downloadmariadb-git-59537790531ff472710ccac80764908209d1d3d9.tar.gz
heap_create() <-> heap_open()
-rw-r--r--heap/hp_create.c166
-rw-r--r--heap/hp_open.c155
-rw-r--r--heap/hp_test1.c6
-rw-r--r--heap/hp_test2.c16
-rw-r--r--include/heap.h7
-rw-r--r--sql/ha_heap.cc180
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, &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;
}
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, &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);
-}
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);
}