18 static int keys_compare(
heap_rb_param *param, uchar *key1, uchar *key2);
19 static void init_block(
HP_BLOCK *
block,uint reclength,ulong min_records,
25 HP_SHARE **res, my_bool *created_new_share)
27 uint
i, j, key_segs, max_length, length;
31 uint reclength= create_info->reclength;
32 uint keys= create_info->keys;
33 ulong min_records= create_info->min_records;
34 ulong max_records= create_info->max_records;
35 DBUG_ENTER(
"heap_create");
37 if (!create_info->internal_table)
40 share= hp_find_named_heap(name);
41 if (share && share->open_count == 0)
47 *created_new_share= (share == NULL);
52 DBUG_PRINT(
"info",(
"Initializing new table"));
58 set_if_bigger(reclength,
sizeof (uchar*));
60 for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
62 memset(&keyinfo->block, 0,
sizeof(keyinfo->block));
63 memset(&keyinfo->rb_tree, 0,
sizeof(keyinfo->rb_tree));
64 for (j= length= 0; j < keyinfo->keysegs; j++)
66 length+= keyinfo->seg[j].length;
67 if (keyinfo->seg[j].null_bit)
70 if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
71 keyinfo->flag|= HA_NULL_PART_KEY;
72 if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
73 keyinfo->rb_tree.size_of_element++;
75 switch (keyinfo->seg[j].type) {
76 case HA_KEYTYPE_SHORT_INT:
77 case HA_KEYTYPE_LONG_INT:
78 case HA_KEYTYPE_FLOAT:
79 case HA_KEYTYPE_DOUBLE:
80 case HA_KEYTYPE_USHORT_INT:
81 case HA_KEYTYPE_ULONG_INT:
82 case HA_KEYTYPE_LONGLONG:
83 case HA_KEYTYPE_ULONGLONG:
84 case HA_KEYTYPE_INT24:
85 case HA_KEYTYPE_UINT24:
87 keyinfo->seg[j].flag|= HA_SWAP_KEY;
89 case HA_KEYTYPE_VARBINARY1:
91 keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
93 case HA_KEYTYPE_VARTEXT1:
94 keyinfo->flag|= HA_VAR_LENGTH_KEY;
97 keyinfo->seg[j].bit_start= 1;
99 case HA_KEYTYPE_VARBINARY2:
102 case HA_KEYTYPE_VARTEXT2:
103 keyinfo->flag|= HA_VAR_LENGTH_KEY;
106 keyinfo->seg[j].bit_start= 2;
111 keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
117 keyinfo->length= length;
118 length+= keyinfo->rb_tree.size_of_element +
119 ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ?
sizeof(uchar*) : 0);
120 if (length > max_length)
122 key_segs+= keyinfo->keysegs;
123 if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
126 if (keyinfo->flag & HA_VAR_LENGTH_KEY)
127 keyinfo->get_key_length= hp_rb_var_key_length;
128 else if (keyinfo->flag & HA_NULL_PART_KEY)
129 keyinfo->get_key_length= hp_rb_null_key_length;
131 keyinfo->get_key_length= hp_rb_key_length;
140 share->key_stat_version= 1;
141 keyseg= (
HA_KEYSEG*) (share->keydef + keys);
142 init_block(&share->block, reclength + 1, min_records, max_records);
144 memcpy(share->keydef, keydef, (
size_t) (
sizeof(keydef[0]) * keys));
145 for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
147 keyinfo->seg= keyseg;
148 memcpy(keyseg, keydef[i].seg,
149 (
size_t) (
sizeof(keyseg[0]) * keydef[i].keysegs));
150 keyseg+= keydef[
i].keysegs;
152 if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
155 keyseg->type= HA_KEYTYPE_END;
156 keyseg->length=
sizeof(uchar*);
161 init_tree(&keyinfo->rb_tree, 0, 0,
sizeof(uchar*),
162 (qsort_cmp2)keys_compare, 1, NULL, NULL);
163 keyinfo->delete_key= hp_rb_delete_key;
164 keyinfo->write_key= hp_rb_write_key;
168 init_block(&keyinfo->block,
sizeof(
HASH_INFO), min_records,
170 keyinfo->delete_key= hp_delete_key;
171 keyinfo->write_key= hp_write_key;
172 keyinfo->hash_buckets= 0;
174 if ((keyinfo->flag & HA_AUTO_KEY) && create_info->with_auto_increment)
175 share->auto_key= i + 1;
177 share->min_records= min_records;
178 share->max_records= max_records;
179 share->max_table_size= create_info->max_table_size;
180 share->data_length= share->index_length= 0;
181 share->reclength= reclength;
184 share->max_key_length= max_length;
186 share->auto_key= create_info->auto_key;
187 share->auto_key_type= create_info->auto_key_type;
188 share->auto_increment= create_info->auto_increment;
189 share->create_time= (long) time((time_t*) 0);
191 if (!(share->name= my_strdup(name,MYF(0))))
196 thr_lock_init(&share->lock);
198 &share->intern_lock, MY_MUTEX_INIT_FAST);
199 if (!create_info->internal_table)
201 share->open_list.data= (
void*) share;
202 heap_share_list= list_add(heap_share_list,&share->open_list);
205 share->delete_on_close= 1;
207 if (!create_info->internal_table)
209 if (create_info->pin_share)
218 if (!create_info->internal_table)
224 static int keys_compare(
heap_rb_param *param, uchar *key1, uchar *key2)
227 return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
228 param->search_flag, not_used);
231 static void init_block(
HP_BLOCK *
block, uint reclength, ulong min_records,
234 uint
i,recbuffer,records_in_block;
236 max_records= MY_MAX(min_records, max_records);
239 recbuffer= (uint) (reclength +
sizeof(uchar**) - 1) & ~(
sizeof(uchar**) - 1);
240 records_in_block= max_records / 10;
241 if (records_in_block < 10 && max_records)
242 records_in_block= 10;
243 if (!records_in_block || records_in_block*recbuffer >
244 (my_default_record_cache_size-
sizeof(
HP_PTRS)*HP_MAX_LEVELS))
245 records_in_block= (my_default_record_cache_size -
sizeof(
HP_PTRS) *
246 HP_MAX_LEVELS) / recbuffer + 1;
247 block->records_in_block= records_in_block;
248 block->recbuffer= recbuffer;
249 block->last_allocated= 0L;
251 for (i= 0; i <= HP_MAX_LEVELS; i++)
252 block->level_info[i].records_under_level=
253 (!i ? 1 : i == 1 ? records_in_block :
254 HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
258 static inline void heap_try_free(
HP_SHARE *share)
260 if (share->open_count == 0)
263 share->delete_on_close= 1;
267 int heap_delete_table(
const char *name)
271 DBUG_ENTER(
"heap_delete_table");
274 if ((share= hp_find_named_heap(name)))
276 heap_try_free(share);
281 result= my_errno=ENOENT;
288 void heap_drop_table(
HP_INFO *info)
290 DBUG_ENTER(
"heap_drop_table");
292 heap_try_free(info->s);
300 if (share->open_list.data)
301 heap_share_list= list_delete(heap_share_list, &share->open_list);
303 thr_lock_delete(&share->lock);
305 my_free(share->name);