14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
#include "heapdef.h"
17
#include "libdrizzle/drizzle_com.h"
18
#include "drizzled/error.h"
18
#include <drizzled/common.h>
19
#include <drizzled/error.h>
20
23
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2);
21
24
static void init_block(HP_BLOCK *block,uint32_t chunk_length, uint32_t min_records,
22
25
uint32_t max_records);
24
27
#define FIXED_REC_OVERHEAD (sizeof(unsigned char))
25
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + sizeof(unsigned char))
28
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + ALIGN_SIZE(sizeof(unsigned char)))
27
30
/* Minimum size that a chunk can take, 12 bytes on 32bit, 24 bytes on 64bit */
28
31
#define VARIABLE_MIN_CHUNK_SIZE \
29
32
((sizeof(unsigned char**) + VARIABLE_REC_OVERHEAD + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1))
58
uint32_t chunk_dataspace_length, chunk_length, is_variable_size;
61
size_t chunk_dataspace_length;
62
uint32_t chunk_length, is_variable_size;
59
63
uint32_t fixed_data_length, fixed_column_count;
60
64
HP_KEYDEF *keyinfo;
173
177
chunk_length= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
177
181
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
179
183
memset(&keyinfo->block, 0, sizeof(keyinfo->block));
248
252
keyinfo->get_key_length= hp_rb_key_length;
251
if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
252
keys*sizeof(HP_KEYDEF)+
253
columns*sizeof(HP_COLUMNDEF)+
254
key_segs*sizeof(HA_KEYSEG),
256
if (!(share= (HP_SHARE*) malloc(sizeof(HP_SHARE))))
259
memset(share, 0, sizeof(HP_SHARE));
261
if (keys && !(share->keydef= (HP_KEYDEF*) malloc(keys*sizeof(HP_KEYDEF))))
264
memset(share->keydef, 0, keys*sizeof(HP_KEYDEF));
266
if (keys && !(share->keydef->seg= (HA_KEYSEG*) malloc(key_segs*sizeof(HA_KEYSEG))))
268
if (!(share->column_defs= (HP_COLUMNDEF*)
269
malloc(columns*sizeof(HP_COLUMNDEF))))
272
memset(share->column_defs, 0, columns*sizeof(HP_COLUMNDEF));
259
275
Max_records is used for estimating block sizes and for enforcement.
260
276
Calculate the very maximum number of rows (if everything was one chunk) and
261
277
then take either that value or configured max_records (pick smallest one)
263
max_rows_for_stated_memory= (ha_rows) (create_info->max_table_size /
279
max_rows_for_stated_memory= (uint32_t)(create_info->max_table_size /
264
280
(keys_memory_size + chunk_length));
265
max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
281
max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
266
282
max_records : max_rows_for_stated_memory);
268
share->column_defs= (HP_COLUMNDEF*) (share + 1);
269
284
memcpy(share->column_defs, columndef, (size_t) (sizeof(columndef[0]) * columns));
271
share->keydef= (HP_KEYDEF*) (share->column_defs + columns);
272
286
share->key_stat_version= 1;
273
keyseg= (HA_KEYSEG*) (share->keydef + keys);
287
keyseg= keys ? share->keydef->seg : NULL;
274
289
init_block(&share->recordspace.block, chunk_length, min_records, max_records);
276
291
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
338
353
/* Must be allocated separately for rename to work */
339
if (!(share->name= my_strdup(name,MYF(0))))
354
if (!(share->name= strdup(name)))
341
free((unsigned char*) share);
344
358
thr_lock_init(&share->lock);
345
359
pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
346
360
if (!create_info->internal_table)
348
share->open_list.data= (void*) share;
349
heap_share_list= list_add(heap_share_list,&share->open_list);
362
heap_share_list.push_front(share);
352
365
share->delete_on_close= 1;
374
if(share && share->keydef && share->keydef->seg)
375
free(share->keydef->seg);
376
if(share && share->keydef)
378
if(share && share->column_defs)
379
free(share->column_defs);
361
382
if (!create_info->internal_table)
362
383
pthread_mutex_unlock(&THR_LOCK_heap);
367
388
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2)
369
390
uint32_t not_used[2];
370
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
391
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
371
392
param->search_flag, not_used);
379
400
max_records= cmax(min_records,max_records);
380
401
if (!max_records)
381
402
max_records= 1000; /* As good as quess as anything */
383
404
/* we want to start each chunk at 8 bytes boundary, round recbuffer to the next 8 */
384
recbuffer= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
405
recbuffer= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
385
406
records_in_block= max_records / 10;
386
407
if (records_in_block < 10 && max_records)
387
408
records_in_block= 10;
441
462
void hp_free(HP_SHARE *share)
443
if (share->open_list.data) /* If not internal table */
444
heap_share_list= list_delete(heap_share_list, &share->open_list);
464
heap_share_list.remove(share); /* If not internal table */
445
465
hp_clear(share); /* Remove blocks from memory */
446
466
thr_lock_delete(&share->lock);
447
467
pthread_mutex_destroy(&share->intern_lock);
469
free(share->keydef->seg);
472
free(share->column_defs);
448
473
free((unsigned char*) share->name);
449
474
free((unsigned char*) share);