~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
1130.3.28 by Monty Taylor
Moved heapdef.h and myisamdef.h to *_priv.h for easier filtering for include guard check.
16
#include "heap_priv.h"
2241.4.5 by Stewart Smith
remove two #includes from heap_priv.h - include error_t.h only where needed
17
#include <drizzled/internal/my_sys.h>
612.2.13 by Monty Taylor
Work on removing global.h from headers that should be installed.
18
#include <drizzled/common.h>
19
#include <drizzled/error.h>
20
21
#include <string.h>
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
22
#include <algorithm>
23
24
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
25
using namespace drizzled;
1 by brian
clean slate
26
482 by Brian Aker
Remove uint.
27
static void init_block(HP_BLOCK *block,uint32_t chunk_length, uint32_t min_records,
291 by Brian Aker
Head ulong conversion.
28
                        uint32_t max_records);
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
29
2151.2.8 by Olaf van der Spek
Replace macros by const vars
30
static const int FIXED_REC_OVERHEAD = (sizeof(unsigned char));
31
static const int VARIABLE_REC_OVERHEAD = (sizeof(unsigned char**) + ALIGN_SIZE(sizeof(unsigned char)));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
32
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
33
/* Minimum size that a chunk can take, 12 bytes on 32bit, 24 bytes on 64bit */
2151.2.8 by Olaf van der Spek
Replace macros by const vars
34
static const int VARIABLE_MIN_CHUNK_SIZE =
35
        ((sizeof(unsigned char**) + VARIABLE_REC_OVERHEAD + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1));
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
36
1 by brian
clean slate
37
38
/* Create a heap table */
39
482 by Brian Aker
Remove uint.
40
int heap_create(const char *name, uint32_t keys, HP_KEYDEF *keydef,
1749.3.5 by Brian Aker
Remove columndef (special case to build columndef (which is no longer
41
                uint32_t columns,
42
                uint32_t key_part_size,
43
                uint32_t reclength, uint32_t keys_memory_size,
44
                uint32_t max_records, uint32_t min_records,
45
                HP_CREATE_INFO *create_info, HP_SHARE **res)
1 by brian
clean slate
46
{
1707.1.5 by Brian Aker
cpp cleanup.
47
  uint32_t i, key_segs, max_length, length;
291 by Brian Aker
Head ulong conversion.
48
  uint32_t max_rows_for_stated_memory;
1 by brian
clean slate
49
  HP_SHARE *share= 0;
50
  HA_KEYSEG *keyseg;
51
1749.3.7 by Brian Aker
Remove recbuf (not used in our design)
52
  if (not create_info->internal_table)
1 by brian
clean slate
53
  {
1689.3.6 by Brian Aker
Update for HEAP to convert its lock to boost.
54
    THR_LOCK_heap.lock();
1 by brian
clean slate
55
    if ((share= hp_find_named_heap(name)) && share->open_count == 0)
56
    {
57
      hp_free(share);
58
      share= 0;
59
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
60
  }
1 by brian
clean slate
61
62
  if (!share)
63
  {
942.1.11 by Monty Taylor
Fixed a coupla build things.
64
    size_t chunk_dataspace_length;
1749.3.4 by Brian Aker
Next pass through heap.
65
    uint32_t chunk_length;
482 by Brian Aker
Remove uint.
66
    uint32_t fixed_data_length, fixed_column_count;
1 by brian
clean slate
67
    HP_KEYDEF *keyinfo;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
68
69
    if (create_info->max_chunk_size)
70
    {
482 by Brian Aker
Remove uint.
71
      uint32_t configured_chunk_size= create_info->max_chunk_size;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
72
73
      /* User requested variable-size records, let's see if they're possible */
74
75
      if (configured_chunk_size < key_part_size)
76
      {
77
        /* Eventual chunk_size cannot be smaller than key data,
1749.3.4 by Brian Aker
Next pass through heap.
78
          which allows all keys to fit into the first chunk */
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
79
        my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "block_size");
1689.3.6 by Brian Aker
Update for HEAP to convert its lock to boost.
80
        THR_LOCK_heap.unlock();
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
81
        return(ER_CANT_USE_OPTION_HERE);
82
      }
83
1749.3.4 by Brian Aker
Next pass through heap.
84
      /* max_chunk_size is near the full reclength, let's use fixed size */
85
      chunk_dataspace_length= reclength;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
86
    }
87
    else
88
    {
89
      /* if max_chunk_size is not specified, put the whole record in one chunk */
90
      chunk_dataspace_length= reclength;
91
    }
92
93
    {
94
      fixed_data_length= reclength;
95
      fixed_column_count= columns;
96
    }
97
1 by brian
clean slate
98
    /*
481 by Brian Aker
Remove all of uchar.
99
      We store unsigned char* del_link inside the data area of deleted records,
100
      so the data length should be at least sizeof(unsigned char*)
1 by brian
clean slate
101
    */
481 by Brian Aker
Remove all of uchar.
102
    set_if_bigger(chunk_dataspace_length, sizeof (unsigned char**));
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
103
104
    {
105
      chunk_length= chunk_dataspace_length + FIXED_REC_OVERHEAD;
106
    }
107
108
    /* Align chunk length to the next pointer */
481 by Brian Aker
Remove all of uchar.
109
    chunk_length= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
110
111
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
112
1 by brian
clean slate
113
    for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
114
    {
212.6.8 by Mats Kindahl
Removing extreneous explicit casts for the heap storage engine.
115
      memset(&keyinfo->block, 0, sizeof(keyinfo->block));
1707.1.5 by Brian Aker
cpp cleanup.
116
      for (uint32_t j= length= 0; j < keyinfo->keysegs; j++)
1 by brian
clean slate
117
      {
118
	length+= keyinfo->seg[j].length;
119
	if (keyinfo->seg[j].null_bit)
120
	{
121
	  length++;
122
	  if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
123
	    keyinfo->flag|= HA_NULL_PART_KEY;
124
	}
125
	switch (keyinfo->seg[j].type) {
126
	case HA_KEYTYPE_LONG_INT:
127
	case HA_KEYTYPE_DOUBLE:
128
	case HA_KEYTYPE_ULONG_INT:
129
	case HA_KEYTYPE_LONGLONG:
130
	case HA_KEYTYPE_ULONGLONG:
131
	  keyinfo->seg[j].flag|= HA_SWAP_KEY;
132
          break;
133
        case HA_KEYTYPE_VARBINARY1:
134
          /* Case-insensitiveness is handled in coll->hash_sort */
135
          keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
136
          /* fall_through */
137
        case HA_KEYTYPE_VARTEXT1:
138
          keyinfo->flag|= HA_VAR_LENGTH_KEY;
139
          length+= 2;
140
          /* Save number of bytes used to store length */
141
          keyinfo->seg[j].bit_start= 1;
142
          break;
143
        case HA_KEYTYPE_VARBINARY2:
144
          /* Case-insensitiveness is handled in coll->hash_sort */
145
          /* fall_through */
146
        case HA_KEYTYPE_VARTEXT2:
147
          keyinfo->flag|= HA_VAR_LENGTH_KEY;
148
          length+= 2;
149
          /* Save number of bytes used to store length */
150
          keyinfo->seg[j].bit_start= 2;
151
          /*
152
            Make future comparison simpler by only having to check for
153
            one type
154
          */
155
          keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
156
          break;
157
	default:
158
	  break;
159
	}
160
      }
161
      keyinfo->length= length;
162
      if (length > max_length)
163
	max_length= length;
164
      key_segs+= keyinfo->keysegs;
165
    }
1697.2.2 by Brian Aker
Encapsulate some of heap.
166
    share= new HP_SHARE;
910.4.1 by Stewart Smith
fix memory alignment issues in hp_create for sparc.
167
1697.2.3 by Brian Aker
Merge in malloc to new for Heap.
168
    if (keys && !(share->keydef= new HP_KEYDEF[keys]))
169
      goto err;
170
    if (keys && !(share->keydef->seg= new HA_KEYSEG[key_segs]))
171
      goto err;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
172
173
    /*
174
       Max_records is used for estimating block sizes and for enforcement.
175
       Calculate the very maximum number of rows (if everything was one chunk) and
176
       then take either that value or configured max_records (pick smallest one)
177
    */
988.2.2 by Trond Norbye
size_t and uint64_t is not the same in 32 bit builds. Add explicit casting
178
    max_rows_for_stated_memory= (uint32_t)(create_info->max_table_size /
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
179
      (keys_memory_size + chunk_length));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
180
    max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
181
                      max_records : max_rows_for_stated_memory);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
182
1 by brian
clean slate
183
    share->key_stat_version= 1;
908.4.1 by Stewart Smith
valgrind warnings in hp_create: around memory allocation fixes for alignment done for sparc
184
    keyseg= keys ? share->keydef->seg : NULL;
910.4.1 by Stewart Smith
fix memory alignment issues in hp_create for sparc.
185
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
186
    init_block(&share->recordspace.block, chunk_length, min_records, max_records);
187
    /* Fix keys */
1 by brian
clean slate
188
    memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
189
    for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
190
    {
191
      keyinfo->seg= keyseg;
192
      memcpy(keyseg, keydef[i].seg,
193
	     (size_t) (sizeof(keyseg[0]) * keydef[i].keysegs));
194
      keyseg+= keydef[i].keysegs;
195
      {
196
	init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
197
		   max_records);
198
        keyinfo->hash_buckets= 0;
199
      }
200
      if ((keyinfo->flag & HA_AUTO_KEY) && create_info->with_auto_increment)
201
        share->auto_key= i + 1;
202
    }
203
    share->min_records= min_records;
204
    share->max_records= max_records;
205
    share->max_table_size= create_info->max_table_size;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
206
    share->index_length= 0;
1 by brian
clean slate
207
    share->blength= 1;
208
    share->keys= keys;
209
    share->max_key_length= max_length;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
210
    share->column_count= columns;
1 by brian
clean slate
211
    share->changed= 0;
212
    share->auto_key= create_info->auto_key;
213
    share->auto_key_type= create_info->auto_key_type;
214
    share->auto_increment= create_info->auto_increment;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
215
216
    share->fixed_data_length= fixed_data_length;
217
    share->fixed_column_count= fixed_column_count;
218
219
    share->recordspace.chunk_length= chunk_length;
220
    share->recordspace.chunk_dataspace_length= chunk_dataspace_length;
221
    share->recordspace.total_data_length= 0;
222
1749.3.4 by Brian Aker
Next pass through heap.
223
    {
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
224
      share->recordspace.offset_link= 1<<22; /* Make it likely to fail if anyone uses this offset */
225
      share->recordspace.offset_status= chunk_dataspace_length;
226
    }
227
1 by brian
clean slate
228
    /* Must be allocated separately for rename to work */
1707.1.2 by Brian Aker
std::string usage for name, remove strdup.
229
    share->name.append(name);
1 by brian
clean slate
230
    if (!create_info->internal_table)
231
    {
916.1.26 by Padraig O'Sullivan
Initial work on removing LIST from the heap storage engine.
232
      heap_share_list.push_front(share);
1 by brian
clean slate
233
    }
234
    else
235
      share->delete_on_close= 1;
236
  }
237
  if (!create_info->internal_table)
1689.3.6 by Brian Aker
Update for HEAP to convert its lock to boost.
238
    THR_LOCK_heap.unlock();
1 by brian
clean slate
239
240
  *res= share;
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
241
  return(0);
1 by brian
clean slate
242
243
err:
1697.2.3 by Brian Aker
Merge in malloc to new for Heap.
244
  if (share && share->keydef)
2385.1.10 by Olaf van der Spek
Update .yy
245
    delete[] share->keydef->seg;
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
246
  if (share)
2385.1.10 by Olaf van der Spek
Update .yy
247
    delete[] share->keydef;
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
248
  delete share;
1697.2.3 by Brian Aker
Merge in malloc to new for Heap.
249
  if (not create_info->internal_table)
1689.3.6 by Brian Aker
Update for HEAP to convert its lock to boost.
250
    THR_LOCK_heap.unlock();
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
251
  return(1);
1 by brian
clean slate
252
} /* heap_create */
253
254
482 by Brian Aker
Remove uint.
255
static void init_block(HP_BLOCK *block, uint32_t chunk_length, uint32_t min_records,
291 by Brian Aker
Head ulong conversion.
256
		       uint32_t max_records)
1 by brian
clean slate
257
{
1707.1.5 by Brian Aker
cpp cleanup.
258
  uint32_t recbuffer,records_in_block;
1 by brian
clean slate
259
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
260
  max_records= max(min_records,max_records);
1 by brian
clean slate
261
  if (!max_records)
262
    max_records= 1000;			/* As good as quess as anything */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
263
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
264
  /* we want to start each chunk at 8 bytes boundary, round recbuffer to the next 8 */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
265
  recbuffer= (uint) (chunk_length + sizeof(unsigned char**) - 1) & ~(sizeof(unsigned char**) - 1);
1 by brian
clean slate
266
  records_in_block= max_records / 10;
267
  if (records_in_block < 10 && max_records)
268
    records_in_block= 10;
269
  if (!records_in_block || records_in_block*recbuffer >
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
270
      (internal::my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
271
    records_in_block= (internal::my_default_record_cache_size - sizeof(HP_PTRS) *
1 by brian
clean slate
272
		      HP_MAX_LEVELS) / recbuffer + 1;
273
  block->records_in_block= records_in_block;
274
  block->recbuffer= recbuffer;
275
  block->last_allocated= 0L;
276
1707.1.5 by Brian Aker
cpp cleanup.
277
  for (uint32_t i= 0; i <= HP_MAX_LEVELS; i++)
278
  {
1 by brian
clean slate
279
    block->level_info[i].records_under_level=
280
      (!i ? 1 : i == 1 ? records_in_block :
281
       HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
1707.1.5 by Brian Aker
cpp cleanup.
282
  }
1 by brian
clean slate
283
}
284
285
286
static inline void heap_try_free(HP_SHARE *share)
287
{
288
  if (share->open_count == 0)
289
    hp_free(share);
290
  else
291
    share->delete_on_close= 1;
292
}
293
294
295
int heap_delete_table(const char *name)
296
{
297
  int result;
298
  register HP_SHARE *share;
299
1689.3.6 by Brian Aker
Update for HEAP to convert its lock to boost.
300
  THR_LOCK_heap.lock();
1 by brian
clean slate
301
  if ((share= hp_find_named_heap(name)))
302
  {
303
    heap_try_free(share);
304
    result= 0;
305
  }
306
  else
307
  {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
308
    result= errno=ENOENT;
1 by brian
clean slate
309
  }
1689.3.6 by Brian Aker
Update for HEAP to convert its lock to boost.
310
  THR_LOCK_heap.unlock();
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
311
  return(result);
1 by brian
clean slate
312
}
313
314
315
void hp_free(HP_SHARE *share)
316
{
916.1.26 by Padraig O'Sullivan
Initial work on removing LIST from the heap storage engine.
317
  heap_share_list.remove(share);        /* If not internal table */
1 by brian
clean slate
318
  hp_clear(share);			/* Remove blocks from memory */
1106.2.1 by Stewart Smith
correct conditional free() on parts of HEAP share. fixes valgrind leak warnings
319
  if (share->keydef)
2385.1.10 by Olaf van der Spek
Update .yy
320
    delete[] share->keydef->seg;
321
  delete[] share->keydef;
1697.2.2 by Brian Aker
Encapsulate some of heap.
322
  delete share;
1 by brian
clean slate
323
}