~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/hp_dspace.c

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

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