13
13
along with this program; if not, write to the Free Software
14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "heap_priv.h"
18
#include <drizzled/common.h>
19
#include <drizzled/error.h>
25
using namespace drizzled;
17
#include "drizzled/common.h"
18
#include "drizzled/error.h"
27
20
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2);
28
21
static void init_block(HP_BLOCK *block,uint32_t chunk_length, uint32_t min_records,
29
22
uint32_t max_records);
31
24
#define FIXED_REC_OVERHEAD (sizeof(unsigned char))
32
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + ALIGN_SIZE(sizeof(unsigned char)))
25
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + sizeof(unsigned char))
34
27
/* Minimum size that a chunk can take, 12 bytes on 32bit, 24 bytes on 64bit */
35
28
#define VARIABLE_MIN_CHUNK_SIZE \
36
29
((sizeof(unsigned char**) + VARIABLE_REC_OVERHEAD + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1))
65
size_t chunk_dataspace_length;
66
uint32_t chunk_length, is_variable_size;
58
uint32_t chunk_dataspace_length, chunk_length, is_variable_size;
67
59
uint32_t fixed_data_length, fixed_column_count;
68
60
HP_KEYDEF *keyinfo;
181
173
chunk_length= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
185
177
for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
187
179
memset(&keyinfo->block, 0, sizeof(keyinfo->block));
198
190
keyinfo->rb_tree.size_of_element++;
200
192
switch (keyinfo->seg[j].type) {
193
case HA_KEYTYPE_SHORT_INT:
201
194
case HA_KEYTYPE_LONG_INT:
195
case HA_KEYTYPE_FLOAT:
202
196
case HA_KEYTYPE_DOUBLE:
197
case HA_KEYTYPE_USHORT_INT:
203
198
case HA_KEYTYPE_ULONG_INT:
204
199
case HA_KEYTYPE_LONGLONG:
205
200
case HA_KEYTYPE_ULONGLONG:
201
case HA_KEYTYPE_INT24:
206
202
case HA_KEYTYPE_UINT24:
203
case HA_KEYTYPE_INT8:
207
204
keyinfo->seg[j].flag|= HA_SWAP_KEY;
209
206
case HA_KEYTYPE_VARBINARY1:
251
248
keyinfo->get_key_length= hp_rb_key_length;
255
if (!(share= (HP_SHARE*) malloc(sizeof(HP_SHARE))))
258
memset(share, 0, sizeof(HP_SHARE));
260
if (keys && !(share->keydef= (HP_KEYDEF*) malloc(keys*sizeof(HP_KEYDEF))))
263
memset(share->keydef, 0, keys*sizeof(HP_KEYDEF));
265
if (keys && !(share->keydef->seg= (HA_KEYSEG*) malloc(key_segs*sizeof(HA_KEYSEG))))
267
if (!(share->column_defs= (HP_COLUMNDEF*)
268
malloc(columns*sizeof(HP_COLUMNDEF))))
271
memset(share->column_defs, 0, columns*sizeof(HP_COLUMNDEF));
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),
274
259
Max_records is used for estimating block sizes and for enforcement.
275
260
Calculate the very maximum number of rows (if everything was one chunk) and
276
261
then take either that value or configured max_records (pick smallest one)
278
max_rows_for_stated_memory= (uint32_t)(create_info->max_table_size /
263
max_rows_for_stated_memory= (ha_rows) (create_info->max_table_size /
279
264
(keys_memory_size + chunk_length));
280
max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
265
max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
281
266
max_records : max_rows_for_stated_memory);
268
share->column_defs= (HP_COLUMNDEF*) (share + 1);
283
269
memcpy(share->column_defs, columndef, (size_t) (sizeof(columndef[0]) * columns));
271
share->keydef= (HP_KEYDEF*) (share->column_defs + columns);
285
272
share->key_stat_version= 1;
286
keyseg= keys ? share->keydef->seg : NULL;
273
keyseg= (HA_KEYSEG*) (share->keydef + keys);
288
274
init_block(&share->recordspace.block, chunk_length, min_records, max_records);
290
276
memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
307
293
init_tree(&keyinfo->rb_tree, 0, 0, sizeof(unsigned char*),
308
(qsort_cmp2)keys_compare, true, NULL, NULL);
294
(qsort_cmp2)keys_compare, 1, NULL, NULL);
309
295
keyinfo->delete_key= hp_rb_delete_key;
310
296
keyinfo->write_key= hp_rb_write_key;
352
338
/* Must be allocated separately for rename to work */
353
if (!(share->name= strdup(name)))
339
if (!(share->name= my_strdup(name,MYF(0))))
341
free((unsigned char*) share);
357
344
thr_lock_init(&share->lock);
358
345
pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
359
346
if (!create_info->internal_table)
361
heap_share_list.push_front(share);
348
share->open_list.data= (void*) share;
349
heap_share_list= list_add(heap_share_list,&share->open_list);
364
352
share->delete_on_close= 1;
373
if(share && share->keydef && share->keydef->seg)
374
free(share->keydef->seg);
375
if(share && share->keydef)
377
if(share && share->column_defs)
378
free(share->column_defs);
381
361
if (!create_info->internal_table)
382
362
pthread_mutex_unlock(&THR_LOCK_heap);
387
367
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2)
389
369
uint32_t not_used[2];
390
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
370
return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
391
371
param->search_flag, not_used);
397
377
uint32_t i,recbuffer,records_in_block;
399
max_records= max(min_records,max_records);
379
max_records= cmax(min_records,max_records);
400
380
if (!max_records)
401
381
max_records= 1000; /* As good as quess as anything */
403
383
/* we want to start each chunk at 8 bytes boundary, round recbuffer to the next 8 */
404
recbuffer= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
384
recbuffer= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
405
385
records_in_block= max_records / 10;
406
386
if (records_in_block < 10 && max_records)
407
387
records_in_block= 10;
408
388
if (!records_in_block || records_in_block*recbuffer >
409
(internal::my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
410
records_in_block= (internal::my_default_record_cache_size - sizeof(HP_PTRS) *
389
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
390
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
411
391
HP_MAX_LEVELS) / recbuffer + 1;
412
392
block->records_in_block= records_in_block;
413
393
block->recbuffer= recbuffer;
461
441
void hp_free(HP_SHARE *share)
463
heap_share_list.remove(share); /* If not internal table */
443
if (share->open_list.data) /* If not internal table */
444
heap_share_list= list_delete(heap_share_list, &share->open_list);
464
445
hp_clear(share); /* Remove blocks from memory */
465
446
thr_lock_delete(&share->lock);
466
447
pthread_mutex_destroy(&share->intern_lock);
467
if (share->keydef && share->keydef->seg)
468
free(share->keydef->seg);
471
free(share->column_defs);
472
448
free((unsigned char*) share->name);
473
449
free((unsigned char*) share);