~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/hp_create.cc

Finished first pass at Protocol cleanup, still some things to remove but they are a bit more involved.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "heapdef.h"
17
 
#include "libdrizzle/drizzle_com.h"
18
 
#include "drizzled/error.h"
 
17
 
 
18
#include <drizzled/common.h>
 
19
#include <drizzled/error.h>
 
20
 
 
21
#include <string.h>
19
22
 
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);
23
26
 
24
27
#define FIXED_REC_OVERHEAD (sizeof(unsigned char))
25
 
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + sizeof(unsigned char))
26
 
 
 
28
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + ALIGN_SIZE(sizeof(unsigned char)))
 
29
 
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))
51
54
      hp_free(share);
52
55
      share= 0;
53
56
    }
54
 
  }  
 
57
  }
55
58
 
56
59
  if (!share)
57
60
  {
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;
61
65
 
173
177
    chunk_length= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
174
178
 
175
179
 
176
 
    
 
180
 
177
181
    for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
178
182
    {
179
183
      memset(&keyinfo->block, 0, sizeof(keyinfo->block));
232
236
        }
233
237
      }
234
238
      keyinfo->length= length;
235
 
      length+= keyinfo->rb_tree.size_of_element + 
 
239
      length+= keyinfo->rb_tree.size_of_element +
236
240
               ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(unsigned char*) : 0);
237
241
      if (length > max_length)
238
242
        max_length= length;
248
252
          keyinfo->get_key_length= hp_rb_key_length;
249
253
      }
250
254
    }
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),
255
 
                                       MYF(MY_ZEROFILL))))
256
 
      goto err;
 
255
    share= NULL;
 
256
    if (!(share= (HP_SHARE*) malloc(sizeof(HP_SHARE))))
 
257
      goto err;
 
258
 
 
259
    memset(share, 0, sizeof(HP_SHARE));
 
260
 
 
261
    if (keys && !(share->keydef= (HP_KEYDEF*) malloc(keys*sizeof(HP_KEYDEF))))
 
262
      goto err;
 
263
 
 
264
    memset(share->keydef, 0, keys*sizeof(HP_KEYDEF));
 
265
 
 
266
    if (keys && !(share->keydef->seg= (HA_KEYSEG*) malloc(key_segs*sizeof(HA_KEYSEG))))
 
267
      goto err;
 
268
    if (!(share->column_defs= (HP_COLUMNDEF*)
 
269
          malloc(columns*sizeof(HP_COLUMNDEF))))
 
270
      goto err;
 
271
 
 
272
    memset(share->column_defs, 0, columns*sizeof(HP_COLUMNDEF));
257
273
 
258
274
    /*
259
275
       Max_records is used for estimating block sizes and for enforcement.
262
278
    */
263
279
    max_rows_for_stated_memory= (ha_rows) (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);
267
 
 
268
 
    share->column_defs= (HP_COLUMNDEF*) (share + 1);
 
283
 
269
284
    memcpy(share->column_defs, columndef, (size_t) (sizeof(columndef[0]) * columns));
270
285
 
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;
 
288
 
274
289
    init_block(&share->recordspace.block, chunk_length, min_records, max_records);
275
290
    /* Fix keys */
276
291
    memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
336
351
    }
337
352
 
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)))
340
355
    {
341
 
      free((unsigned char*) share);
342
356
      goto err;
343
357
    }
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)
347
361
    {
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);
350
363
    }
351
364
    else
352
365
      share->delete_on_close= 1;
358
371
  return(0);
359
372
 
360
373
err:
 
374
  if(share && share->keydef && share->keydef->seg)
 
375
    free(share->keydef->seg);
 
376
  if(share && share->keydef)
 
377
    free(share->keydef);
 
378
  if(share && share->column_defs)
 
379
    free(share->column_defs);
 
380
  if(share)
 
381
    free(share);
361
382
  if (!create_info->internal_table)
362
383
    pthread_mutex_unlock(&THR_LOCK_heap);
363
384
  return(1);
367
388
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2)
368
389
{
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);
372
393
}
373
394
 
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 */
382
 
  
 
403
 
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;
440
461
 
441
462
void hp_free(HP_SHARE *share)
442
463
{
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);
 
468
  if(share->keys)
 
469
    free(share->keydef->seg);
 
470
  if(share->keys)
 
471
    free(share->keydef);
 
472
  free(share->column_defs);
448
473
  free((unsigned char*) share->name);
449
474
  free((unsigned char*) share);
450
475
  return;