~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/hp_dspace.cc

  • Committer: Brian Aker
  • Date: 2010-01-22 00:53:13 UTC
  • Revision ID: brian@gaz-20100122005313-jmizcbcdi1lt4tcx
Revert db patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Implements various base dataspace-related functions - allocate, free, clear */
18
18
 
19
 
#include "heapdef.h"
 
19
#include "heap_priv.h"
 
20
 
 
21
#include <cassert>
20
22
 
21
23
 
22
24
/*
86
88
 
87
89
  The allocation and contents of the actual chunks varies between
88
90
  fixed and variable-size modes. Total chunk length is always
89
 
  aligned to the next sizeof(uchar*). Here is the format of
 
91
  aligned to the next sizeof(unsigned char*). Here is the format of
90
92
  fixed-size chunk:
91
 
      uchar[] - sizeof=chunk_dataspace_length, but at least
92
 
               sizeof(uchar*) bytes. Keeps actual data or pointer
 
93
      unsigned char[] - sizeof=chunk_dataspace_length, but at least
 
94
               sizeof(unsigned char*) bytes. Keeps actual data or pointer
93
95
               to the next deleted chunk.
94
96
               chunk_dataspace_length equals to full record length
95
 
      uchar   - status field (1 means "in use", 0 means "deleted")
 
97
      unsigned char   - status field (1 means "in use", 0 means "deleted")
96
98
  Variable-size uses different format:
97
 
      uchar[] - sizeof=chunk_dataspace_length, but at least
98
 
               sizeof(uchar*) bytes. Keeps actual data or pointer
 
99
      unsigned char[] - sizeof=chunk_dataspace_length, but at least
 
100
               sizeof(unsigned char*) bytes. Keeps actual data or pointer
99
101
               to the next deleted chunk.
100
102
               chunk_dataspace_length is set according to table
101
103
               setup (block_size)
102
 
      uchar*  - pointer to the next chunk in this chunkset,
 
104
      unsigned char*  - pointer to the next chunk in this chunkset,
103
105
               or NULL for the last chunk
104
 
      uchar  -  status field (1 means "first", 0 means "deleted",
 
106
      unsigned char  -  status field (1 means "first", 0 means "deleted",
105
107
               2 means "linked")
106
108
 
107
109
  When allocating a new chunkset of N chunks, Heap Engine will try
112
114
  Freeing chunks will place them at the front of free list
113
115
  referenced by del_link in HP_DATASPACE. The newly freed chunk
114
116
  will contain reference to the previously freed chunk in its first
115
 
  sizeof(uchar*) of the payload space.
 
117
  sizeof(unsigned char*) of the payload space.
116
118
 
117
119
  Here is open issues:
118
120
    1. It is not very nice to require people to keep key columns
143
145
       in indexes
144
146
    5. In variable-size format status should be moved to lower
145
147
       bits of the "next" pointer. Pointer is always aligned
146
 
       to sizeof(uchar*), which is at least 4, leaving 2 lower
 
148
       to sizeof(unsigned char*), which is at least 4, leaving 2 lower
147
149
       bits free. This will save 8 bytes per chunk
148
150
       on 64-bit platform.
149
151
    6. As we do not want to modify FRM format, BLOCK_SIZE option
151
153
       Heap Engine tables.
152
154
*/
153
155
 
154
 
static uchar *hp_allocate_one_chunk(HP_DATASPACE *info);
 
156
static unsigned char *hp_allocate_one_chunk(HP_DATASPACE *info);
155
157
 
156
158
 
157
159
/**
166
168
{
167
169
  if (info->block.levels)
168
170
  {
169
 
    VOID(hp_free_level(&info->block,info->block.levels,info->block.root,
170
 
                        (uchar*) 0));
 
171
    hp_free_level(&info->block,info->block.levels,info->block.root,
 
172
                  (unsigned char*) 0);
171
173
  }
172
174
  info->block.levels=0;
173
175
  info->del_chunk_count= info->chunk_count= 0;
189
191
  @return  Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
190
192
*/
191
193
 
192
 
static uchar *hp_allocate_variable_chunkset(HP_DATASPACE *info,
193
 
                                           uint chunk_count, uchar* existing_set)
 
194
static unsigned char *hp_allocate_variable_chunkset(HP_DATASPACE *info,
 
195
                                           uint32_t chunk_count, unsigned char* existing_set)
194
196
{
195
197
  int alloc_count= chunk_count, i;
196
 
  uchar *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
 
198
  unsigned char *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
197
199
 
198
200
  assert(alloc_count);
199
201
 
205
207
    while (curr_chunk && alloc_count)
206
208
    {
207
209
      prev_chunk= curr_chunk;
208
 
      curr_chunk= *((uchar**)(curr_chunk + info->offset_link));
 
210
      curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));
209
211
      alloc_count--;
210
212
    }
211
213
 
214
216
      if (curr_chunk)
215
217
      {
216
218
        /* We came through all chunks and there is more left, let's truncate the list */
217
 
        *((uchar**)(prev_chunk + info->offset_link)) = NULL;
 
219
        *((unsigned char**)(prev_chunk + info->offset_link)) = NULL;
218
220
        hp_free_chunks(info, curr_chunk);
219
221
      }
220
222
 
237
239
        {
238
240
          /* Truncate whatever was added at the end of the existing chunkset */
239
241
          prev_chunk= last_existing_chunk;
240
 
          curr_chunk= *((uchar**)(prev_chunk + info->offset_link));
241
 
          *((uchar**)(prev_chunk + info->offset_link)) = NULL;
 
242
          curr_chunk= *((unsigned char**)(prev_chunk + info->offset_link));
 
243
          *((unsigned char**)(prev_chunk + info->offset_link)) = NULL;
242
244
          hp_free_chunks(info, curr_chunk);
243
245
        }
244
246
        else if (first_chunk)
251
253
      }
252
254
 
253
255
      /* mark as if this chunk is last in the chunkset */
254
 
      *((uchar**) (curr_chunk + info->offset_link))= 0;
 
256
      *((unsigned char**) (curr_chunk + info->offset_link))= 0;
255
257
 
256
258
      if (prev_chunk)
257
259
      {
258
260
        /* tie them into a linked list */
259
 
        *((uchar**) (prev_chunk + info->offset_link))= curr_chunk;
 
261
        *((unsigned char**) (prev_chunk + info->offset_link))= curr_chunk;
260
262
        curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED;                   /* Record linked from active */
261
263
      }
262
264
      else
287
289
  @return  Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
288
290
*/
289
291
 
290
 
uchar *hp_allocate_chunkset(HP_DATASPACE *info, uint chunk_count)
 
292
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count)
291
293
{
292
 
  uchar* result;
 
294
  unsigned char* result;
293
295
 
294
296
 
295
297
  if (info->is_variable_size)
323
325
  @return  Error code or zero if successful
324
326
*/
325
327
 
326
 
int hp_reallocate_chunkset(HP_DATASPACE *info, uint chunk_count, uchar* pos)
 
328
int hp_reallocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count, unsigned char* pos)
327
329
{
328
330
 
329
331
  if (!info->is_variable_size)
330
332
  {
331
333
    /* Update should never change chunk_count in fixed-size mode */
332
 
    my_errno=HA_ERR_WRONG_COMMAND;
333
 
    return my_errno;
 
334
    errno=HA_ERR_WRONG_COMMAND;
 
335
    return errno;
334
336
  }
335
337
 
336
338
  /* Reallocate never moves the first chunk */
337
339
  if (!hp_allocate_variable_chunkset(info, chunk_count, pos))
338
 
    return(my_errno);
 
340
    return(errno);
339
341
 
340
342
  return(0);
341
343
}
351
353
  @return  Pointer to the chunk, or NULL if unsuccessful
352
354
*/
353
355
 
354
 
static uchar *hp_allocate_one_chunk(HP_DATASPACE *info)
 
356
static unsigned char *hp_allocate_one_chunk(HP_DATASPACE *info)
355
357
{
356
 
  uchar* curr_chunk;
 
358
  unsigned char* curr_chunk;
357
359
  size_t length, block_pos;
358
360
 
359
361
  if (info->del_link)
360
362
  {
361
363
    curr_chunk=info->del_link;
362
 
    info->del_link= *((uchar**) curr_chunk);
 
364
    info->del_link= *((unsigned char**) curr_chunk);
363
365
    info->del_chunk_count--;
364
366
 
365
367
    return curr_chunk;
378
380
  }
379
381
 
380
382
  info->chunk_count++;
381
 
  curr_chunk= ((uchar*) info->block.level_info[0].last_blocks +
 
383
  curr_chunk= ((unsigned char*) info->block.level_info[0].last_blocks +
382
384
    block_pos * info->block.recbuffer);
383
385
 
384
386
 
396
398
  @param  pos             pointer to the head of the chunkset
397
399
*/
398
400
 
399
 
void hp_free_chunks(HP_DATASPACE *info, uchar *pos)
 
401
void hp_free_chunks(HP_DATASPACE *info, unsigned char *pos)
400
402
{
401
 
  uchar* curr_chunk= pos;
 
403
  unsigned char* curr_chunk= pos;
402
404
 
403
405
  while (curr_chunk) {
404
406
    info->del_chunk_count++;
405
 
    *((uchar**) curr_chunk)= info->del_link;
 
407
    *((unsigned char**) curr_chunk)= info->del_link;
406
408
    info->del_link= curr_chunk;
407
409
 
408
410
    curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;
414
416
    }
415
417
 
416
418
    /* Delete next chunk in this chunkset */
417
 
    curr_chunk= *((uchar**)(curr_chunk + info->offset_link));
 
419
    curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));
418
420
  }
419
421
}