~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/hp_dspace.c

  • Committer: Monty Taylor
  • Date: 2008-10-30 19:42:06 UTC
  • mto: (520.4.38 devel)
  • mto: This revision was merged to the branch mainline in revision 572.
  • Revision ID: monty@inaugust.com-20081030194206-fzus6yqlw1ekru65
Removed handler from common_includes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 
13
13
   You should have received a copy of the GNU General Public License
14
14
   along with this program; if not, write to the Free Software
15
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
16
16
 
17
17
/* Implements various base dataspace-related functions - allocate, free, clear */
18
18
 
19
 
#include "heap_priv.h"
20
 
 
21
 
#include <cassert>
 
19
#include "heapdef.h"
22
20
 
23
21
 
24
22
/*
179
177
 
180
178
 
181
179
/**
 
180
  Allocate or reallocate a chunkset in the dataspace
 
181
 
 
182
  Attempts to allocate a new chunkset or change the size of an existing chunkset
 
183
 
 
184
  @param  info            the hosting dataspace
 
185
  @param  chunk_count     the number of chunks that we expect as the result
 
186
  @param  existing_set    non-null value asks function to resize existing chunkset,
 
187
                          return value would point to this set
 
188
 
 
189
  @return  Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
 
190
*/
 
191
 
 
192
static unsigned char *hp_allocate_variable_chunkset(HP_DATASPACE *info,
 
193
                                           uint32_t chunk_count, unsigned char* existing_set)
 
194
{
 
195
  int alloc_count= chunk_count, i;
 
196
  unsigned char *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
 
197
 
 
198
  assert(alloc_count);
 
199
 
 
200
  if (existing_set)
 
201
  {
 
202
    first_chunk= existing_set;
 
203
 
 
204
    curr_chunk= existing_set;
 
205
    while (curr_chunk && alloc_count)
 
206
    {
 
207
      prev_chunk= curr_chunk;
 
208
      curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));
 
209
      alloc_count--;
 
210
    }
 
211
 
 
212
    if (!alloc_count)
 
213
    {
 
214
      if (curr_chunk)
 
215
      {
 
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;
 
218
        hp_free_chunks(info, curr_chunk);
 
219
      }
 
220
 
 
221
      return first_chunk;
 
222
    }
 
223
 
 
224
    last_existing_chunk = prev_chunk;
 
225
  }
 
226
 
 
227
  /* We can reach this point only if we're allocating new chunkset or more chunks in existing set */
 
228
 
 
229
  for (i=0; i<alloc_count; i++)
 
230
  {
 
231
      curr_chunk= hp_allocate_one_chunk(info);
 
232
      if (!curr_chunk)
 
233
      {
 
234
        /* no space in the current block */
 
235
 
 
236
        if (last_existing_chunk)
 
237
        {
 
238
          /* Truncate whatever was added at the end of the existing chunkset */
 
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;
 
242
          hp_free_chunks(info, curr_chunk);
 
243
        }
 
244
        else if (first_chunk)
 
245
        {
 
246
          /* free any chunks previously allocated */
 
247
          hp_free_chunks(info, first_chunk);
 
248
        }
 
249
 
 
250
        return NULL;
 
251
      }
 
252
 
 
253
      /* mark as if this chunk is last in the chunkset */
 
254
      *((unsigned char**) (curr_chunk + info->offset_link))= 0;
 
255
 
 
256
      if (prev_chunk)
 
257
      {
 
258
        /* tie them into a linked list */
 
259
        *((unsigned char**) (prev_chunk + info->offset_link))= curr_chunk;
 
260
        curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED;                   /* Record linked from active */
 
261
      }
 
262
      else
 
263
      {
 
264
        curr_chunk[info->offset_status]= CHUNK_STATUS_ACTIVE;                     /* Record active */
 
265
      }
 
266
 
 
267
      if (!first_chunk)
 
268
      {
 
269
        first_chunk= curr_chunk;
 
270
      }
 
271
 
 
272
      prev_chunk= curr_chunk;
 
273
  }
 
274
 
 
275
  return first_chunk;
 
276
}
 
277
 
 
278
 
 
279
/**
182
280
  Allocate a new chunkset in the dataspace
183
281
 
184
282
  Attempts to allocate a new chunkset
189
287
  @return  Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
190
288
*/
191
289
 
192
 
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t )
 
290
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count)
193
291
{
194
292
  unsigned char* result;
195
293
 
196
 
  result= hp_allocate_one_chunk(info);
197
 
  if (result)
198
 
  {
199
 
    result[info->offset_status]= CHUNK_STATUS_ACTIVE;
 
294
 
 
295
  if (info->is_variable_size)
 
296
  {
 
297
    result = hp_allocate_variable_chunkset(info, chunk_count, NULL);
 
298
  }
 
299
  else
 
300
  {
 
301
    result= hp_allocate_one_chunk(info);
 
302
    if (result)
 
303
    {
 
304
      result[info->offset_status]= CHUNK_STATUS_ACTIVE;
 
305
    }
 
306
 
 
307
    return(result);
200
308
  }
201
309
 
202
310
  return(result);
204
312
 
205
313
 
206
314
/**
 
315
  Reallocate an existing chunkset in the dataspace
 
316
 
 
317
  Attempts to change the size of an existing chunkset
 
318
 
 
319
  @param  info            the hosting dataspace
 
320
  @param  chunk_count     the number of chunks that we expect as the result
 
321
  @param  pos             pointer to the existing chunkset
 
322
 
 
323
  @return  Error code or zero if successful
 
324
*/
 
325
 
 
326
int hp_reallocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count, unsigned char* pos)
 
327
{
 
328
 
 
329
  if (!info->is_variable_size)
 
330
  {
 
331
    /* Update should never change chunk_count in fixed-size mode */
 
332
    my_errno=HA_ERR_WRONG_COMMAND;
 
333
    return my_errno;
 
334
  }
 
335
 
 
336
  /* Reallocate never moves the first chunk */
 
337
  if (!hp_allocate_variable_chunkset(info, chunk_count, pos))
 
338
    return(my_errno);
 
339
 
 
340
  return(0);
 
341
}
 
342
 
 
343
 
 
344
/**
207
345
  Allocate a single chunk in the dataspace
208
346
 
209
347
  Attempts to allocate a new chunk or reuse one from deleted list
241
379
 
242
380
  info->chunk_count++;
243
381
  curr_chunk= ((unsigned char*) info->block.level_info[0].last_blocks +
244
 
               block_pos * info->block.recbuffer);
 
382
    block_pos * info->block.recbuffer);
245
383
 
246
384
 
247
385
  return curr_chunk;
262
400
{
263
401
  unsigned char* curr_chunk= pos;
264
402
 
265
 
  if (curr_chunk) 
266
 
  {
 
403
  while (curr_chunk) {
267
404
    info->del_chunk_count++;
268
405
    *((unsigned char**) curr_chunk)= info->del_link;
269
406
    info->del_link= curr_chunk;
270
407
 
271
408
    curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;
 
409
 
 
410
 
 
411
    if (!info->is_variable_size)
 
412
    {
 
413
      break;
 
414
    }
 
415
 
 
416
    /* Delete next chunk in this chunkset */
 
417
    curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));
272
418
  }
273
419
}