~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/hp_create.c

  • Committer: Monty Taylor
  • Date: 2009-01-30 21:02:37 UTC
  • mto: (779.7.3 devel)
  • mto: This revision was merged to the branch mainline in revision 823.
  • Revision ID: mordred@inaugust.com-20090130210237-3n6ld8a9jc084jko
Commented out a test in subselect_sj - I think it might be a regression. Jay?

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"
19
 
 
20
 
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2);
21
 
static void init_block(HP_BLOCK *block,uint chunk_length, uint32_t min_records,
 
17
 
 
18
#include <drizzled/common.h>
 
19
#include <drizzled/error.h>
 
20
 
 
21
#include <string.h>
 
22
 
 
23
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2);
 
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
 
#define FIXED_REC_OVERHEAD (sizeof(uchar))
25
 
#define VARIABLE_REC_OVERHEAD (sizeof(uchar**) + sizeof(uchar))
26
 
 
 
27
#define FIXED_REC_OVERHEAD (sizeof(unsigned char))
 
28
#define VARIABLE_REC_OVERHEAD (sizeof(unsigned char**) + 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
 
        ((sizeof(uchar**) + VARIABLE_REC_OVERHEAD + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1))
 
32
        ((sizeof(unsigned char**) + VARIABLE_REC_OVERHEAD + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1))
30
33
 
31
34
 
32
35
/* Create a heap table */
33
36
 
34
 
int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
35
 
    uint columns, HP_COLUMNDEF *columndef,
36
 
    uint max_key_fieldnr, uint key_part_size,
37
 
    uint reclength, uint keys_memory_size,
 
37
int heap_create(const char *name, uint32_t keys, HP_KEYDEF *keydef,
 
38
    uint32_t columns, HP_COLUMNDEF *columndef,
 
39
    uint32_t max_key_fieldnr, uint32_t key_part_size,
 
40
    uint32_t reclength, uint32_t keys_memory_size,
38
41
    uint32_t max_records, uint32_t min_records,
39
42
    HP_CREATE_INFO *create_info, HP_SHARE **res)
40
43
{
41
 
  uint i, j, key_segs, max_length, length;
 
44
  uint32_t i, j, key_segs, max_length, length;
42
45
  uint32_t max_rows_for_stated_memory;
43
46
  HP_SHARE *share= 0;
44
47
  HA_KEYSEG *keyseg;
51
54
      hp_free(share);
52
55
      share= 0;
53
56
    }
54
 
  }  
 
57
  }
55
58
 
56
59
  if (!share)
57
60
  {
58
 
    uint chunk_dataspace_length, chunk_length, is_variable_size;
59
 
    uint fixed_data_length, fixed_column_count;
 
61
    uint32_t chunk_dataspace_length, chunk_length, is_variable_size;
 
62
    uint32_t fixed_data_length, fixed_column_count;
60
63
    HP_KEYDEF *keyinfo;
61
64
 
62
65
    if (create_info->max_chunk_size)
63
66
    {
64
 
      uint configured_chunk_size= create_info->max_chunk_size;
 
67
      uint32_t configured_chunk_size= create_info->max_chunk_size;
65
68
 
66
69
      /* User requested variable-size records, let's see if they're possible */
67
70
 
109
112
    if (is_variable_size)
110
113
    {
111
114
      /* Check whether we have any variable size records past key data */
112
 
      uint has_variable_fields= 0;
 
115
      uint32_t has_variable_fields= 0;
113
116
 
114
117
      fixed_data_length= key_part_size;
115
118
      fixed_column_count= max_key_fieldnr;
155
158
    }
156
159
 
157
160
    /*
158
 
      We store uchar* del_link inside the data area of deleted records,
159
 
      so the data length should be at least sizeof(uchar*)
 
161
      We store unsigned char* del_link inside the data area of deleted records,
 
162
      so the data length should be at least sizeof(unsigned char*)
160
163
    */
161
 
    set_if_bigger(chunk_dataspace_length, sizeof (uchar**));
 
164
    set_if_bigger(chunk_dataspace_length, sizeof (unsigned char**));
162
165
 
163
166
    if (is_variable_size)
164
167
    {
170
173
    }
171
174
 
172
175
    /* Align chunk length to the next pointer */
173
 
    chunk_length= (uint) (chunk_length + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
174
 
 
175
 
 
176
 
    
 
176
    chunk_length= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
 
177
 
 
178
 
 
179
 
177
180
    for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
178
181
    {
179
182
      memset(&keyinfo->block, 0, sizeof(keyinfo->block));
232
235
        }
233
236
      }
234
237
      keyinfo->length= length;
235
 
      length+= keyinfo->rb_tree.size_of_element + 
236
 
               ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(uchar*) : 0);
 
238
      length+= keyinfo->rb_tree.size_of_element +
 
239
               ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(unsigned char*) : 0);
237
240
      if (length > max_length)
238
241
        max_length= length;
239
242
      key_segs+= keyinfo->keysegs;
248
251
          keyinfo->get_key_length= hp_rb_key_length;
249
252
      }
250
253
    }
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))))
 
254
    if (!(share= (HP_SHARE*) malloc(sizeof(HP_SHARE)+
 
255
                                    keys*sizeof(HP_KEYDEF)+
 
256
                                    columns*sizeof(HP_COLUMNDEF)+
 
257
                                    key_segs*sizeof(HA_KEYSEG))))
256
258
      goto err;
 
259
    memset(share, 0, sizeof(HP_SHARE)+
 
260
                     keys*sizeof(HP_KEYDEF)+
 
261
                     columns*sizeof(HP_COLUMNDEF)+
 
262
                     key_segs*sizeof(HA_KEYSEG));
257
263
 
258
264
    /*
259
265
       Max_records is used for estimating block sizes and for enforcement.
262
268
    */
263
269
    max_rows_for_stated_memory= (ha_rows) (create_info->max_table_size /
264
270
      (keys_memory_size + chunk_length));
265
 
    max_records = ((max_records && max_records < max_rows_for_stated_memory) ? 
 
271
    max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
266
272
                      max_records : max_rows_for_stated_memory);
267
 
 
 
273
 
268
274
    share->column_defs= (HP_COLUMNDEF*) (share + 1);
269
275
    memcpy(share->column_defs, columndef, (size_t) (sizeof(columndef[0]) * columns));
270
276
 
271
 
    share->keydef= (HP_KEYDEF*) (share->column_defs + columns);    
 
277
    share->keydef= (HP_KEYDEF*) (share->column_defs + columns);
272
278
    share->key_stat_version= 1;
273
279
    keyseg= (HA_KEYSEG*) (share->keydef + keys);
274
280
    init_block(&share->recordspace.block, chunk_length, min_records, max_records);
285
291
      {
286
292
        /* additional HA_KEYTYPE_END keyseg */
287
293
        keyseg->type=     HA_KEYTYPE_END;
288
 
        keyseg->length=   sizeof(uchar*);
 
294
        keyseg->length=   sizeof(unsigned char*);
289
295
        keyseg->flag=     0;
290
296
        keyseg->null_bit= 0;
291
297
        keyseg++;
292
298
 
293
 
        init_tree(&keyinfo->rb_tree, 0, 0, sizeof(uchar*),
 
299
        init_tree(&keyinfo->rb_tree, 0, 0, sizeof(unsigned char*),
294
300
                  (qsort_cmp2)keys_compare, 1, NULL, NULL);
295
301
        keyinfo->delete_key= hp_rb_delete_key;
296
302
        keyinfo->write_key= hp_rb_write_key;
329
335
 
330
336
    if (is_variable_size) {
331
337
      share->recordspace.offset_link= chunk_dataspace_length;
332
 
      share->recordspace.offset_status= share->recordspace.offset_link + sizeof(uchar**);
 
338
      share->recordspace.offset_status= share->recordspace.offset_link + sizeof(unsigned char**);
333
339
    } else {
334
340
      share->recordspace.offset_link= 1<<22; /* Make it likely to fail if anyone uses this offset */
335
341
      share->recordspace.offset_status= chunk_dataspace_length;
336
342
    }
337
343
 
338
344
    /* Must be allocated separately for rename to work */
339
 
    if (!(share->name= my_strdup(name,MYF(0))))
 
345
    if (!(share->name= strdup(name)))
340
346
    {
341
 
      my_free((uchar*) share,MYF(0));
 
347
      free((unsigned char*) share);
342
348
      goto err;
343
349
    }
344
350
    thr_lock_init(&share->lock);
345
 
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
 
351
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
346
352
    if (!create_info->internal_table)
347
353
    {
348
354
      share->open_list.data= (void*) share;
364
370
} /* heap_create */
365
371
 
366
372
 
367
 
static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2)
 
373
static int keys_compare(heap_rb_param *param, unsigned char *key1, unsigned char *key2)
368
374
{
369
 
  uint not_used[2];
370
 
  return ha_key_cmp(param->keyseg, key1, key2, param->key_length, 
 
375
  uint32_t not_used[2];
 
376
  return ha_key_cmp(param->keyseg, key1, key2, param->key_length,
371
377
                    param->search_flag, not_used);
372
378
}
373
379
 
374
 
static void init_block(HP_BLOCK *block, uint chunk_length, uint32_t min_records,
 
380
static void init_block(HP_BLOCK *block, uint32_t chunk_length, uint32_t min_records,
375
381
                       uint32_t max_records)
376
382
{
377
 
  uint i,recbuffer,records_in_block;
 
383
  uint32_t i,recbuffer,records_in_block;
378
384
 
379
 
  max_records= max(min_records,max_records);
 
385
  max_records= cmax(min_records,max_records);
380
386
  if (!max_records)
381
387
    max_records= 1000;                  /* As good as quess as anything */
382
 
  
 
388
 
383
389
  /* we want to start each chunk at 8 bytes boundary, round recbuffer to the next 8 */
384
 
  recbuffer= (uint) (chunk_length + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);  
 
390
  recbuffer= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
385
391
  records_in_block= max_records / 10;
386
392
  if (records_in_block < 10 && max_records)
387
393
    records_in_block= 10;
444
450
    heap_share_list= list_delete(heap_share_list, &share->open_list);
445
451
  hp_clear(share);                      /* Remove blocks from memory */
446
452
  thr_lock_delete(&share->lock);
447
 
  VOID(pthread_mutex_destroy(&share->intern_lock));
448
 
  my_free((uchar*) share->name, MYF(0));
449
 
  my_free((uchar*) share, MYF(0));
 
453
  pthread_mutex_destroy(&share->intern_lock);
 
454
  free((unsigned char*) share->name);
 
455
  free((unsigned char*) share);
450
456
  return;
451
457
}