~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/hp_write.c

  • Committer: Brian Aker
  • Date: 2008-07-07 14:25:25 UTC
  • mto: (77.1.25 codestyle)
  • mto: This revision was merged to the branch mainline in revision 82.
  • Revision ID: brian@tangent.org-20080707142525-xzy2nl3ie2ebwfln
LL() cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#define HIGHFIND 4
26
26
#define HIGHUSED 8
27
27
 
 
28
static uchar *next_free_record_pos(HP_SHARE *info);
28
29
static HASH_INFO *hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block,
29
 
                                     uint32_t records);
 
30
                                     ulong records);
30
31
 
31
 
int heap_write(HP_INFO *info, const unsigned char *record)
 
32
int heap_write(HP_INFO *info, const uchar *record)
32
33
{
33
34
  HP_KEYDEF *keydef, *end;
34
 
  unsigned char *pos;
 
35
  uchar *pos;
35
36
  HP_SHARE *share=info->s;
36
 
  uint32_t rec_length, chunk_count;
37
 
 
38
 
  if ((share->records >= share->max_records && share->max_records) ||
39
 
    (share->recordspace.total_data_length + share->index_length >= share->max_table_size))
 
37
  DBUG_ENTER("heap_write");
 
38
#ifndef DBUG_OFF
 
39
  if (info->mode & O_RDONLY)
40
40
  {
41
 
    return(my_errno=HA_ERR_RECORD_FILE_FULL);
 
41
    DBUG_RETURN(my_errno=EACCES);
42
42
  }
43
 
 
44
 
  rec_length = hp_get_encoded_data_length(share, record, &chunk_count);
45
 
 
46
 
  if (!(pos=hp_allocate_chunkset(&share->recordspace, chunk_count)))
47
 
    return(my_errno);
 
43
#endif
 
44
  if (!(pos=next_free_record_pos(share)))
 
45
    DBUG_RETURN(my_errno);
48
46
  share->changed=1;
49
47
 
50
48
  for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
54
52
      goto err;
55
53
  }
56
54
 
57
 
  hp_copy_record_data_to_chunkset(share, record, pos);
58
 
 
 
55
  memcpy(pos,record,(size_t) share->reclength);
 
56
  pos[share->reclength]=1;              /* Mark record as not deleted */
59
57
  if (++share->records == share->blength)
60
58
    share->blength+= share->blength;
61
 
 
62
59
  info->current_ptr=pos;
63
60
  info->current_hash_ptr=0;
64
61
  info->update|=HA_STATE_AKTIV;
 
62
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
 
63
  DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
 
64
#endif
65
65
  if (share->auto_key)
66
66
    heap_update_auto_increment(info, record);
67
 
  return(0);
 
67
  DBUG_RETURN(0);
68
68
 
69
69
err:
 
70
  if (my_errno == HA_ERR_FOUND_DUPP_KEY)
 
71
    DBUG_PRINT("info",("Duplicate key: %d", (int) (keydef - share->keydef)));
70
72
  info->errkey= keydef - share->keydef;
71
73
  /*
72
74
    We don't need to delete non-inserted key from rb-tree.  Also, if
85
87
    keydef--;
86
88
  } 
87
89
 
88
 
  hp_free_chunks(&share->recordspace, pos);
 
90
  share->deleted++;
 
91
  *((uchar**) pos)=share->del_link;
 
92
  share->del_link=pos;
 
93
  pos[share->reclength]=0;                      /* Record deleted */
89
94
 
90
 
  return(my_errno);
 
95
  DBUG_RETURN(my_errno);
91
96
} /* heap_write */
92
97
 
93
98
/* 
94
99
  Write a key to rb_tree-index 
95
100
*/
96
101
 
97
 
int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const unsigned char *record, 
98
 
                    unsigned char *recpos)
 
102
int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *record, 
 
103
                    uchar *recpos)
99
104
{
100
105
  heap_rb_param custom_arg;
101
 
  uint32_t old_allocated;
 
106
  uint old_allocated;
102
107
 
103
108
  custom_arg.keyseg= keyinfo->seg;
104
109
  custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
123
128
  return 0;
124
129
}
125
130
 
 
131
        /* Find where to place new record */
 
132
 
 
133
static uchar *next_free_record_pos(HP_SHARE *info)
 
134
{
 
135
  int block_pos;
 
136
  uchar *pos;
 
137
  size_t length;
 
138
  DBUG_ENTER("next_free_record_pos");
 
139
 
 
140
  if (info->del_link)
 
141
  {
 
142
    pos=info->del_link;
 
143
    info->del_link= *((uchar**) pos);
 
144
    info->deleted--;
 
145
    DBUG_PRINT("exit",("Used old position: 0x%lx",(long) pos));
 
146
    DBUG_RETURN(pos);
 
147
  }
 
148
  if (!(block_pos=(info->records % info->block.records_in_block)))
 
149
  {
 
150
    if ((info->records > info->max_records && info->max_records) ||
 
151
        (info->data_length + info->index_length >= info->max_table_size))
 
152
    {
 
153
      my_errno=HA_ERR_RECORD_FILE_FULL;
 
154
      DBUG_RETURN(NULL);
 
155
    }
 
156
    if (hp_get_new_block(&info->block,&length))
 
157
      DBUG_RETURN(NULL);
 
158
    info->data_length+=length;
 
159
  }
 
160
  DBUG_PRINT("exit",("Used new position: 0x%lx",
 
161
                     (long) ((uchar*) info->block.level_info[0].last_blocks+
 
162
                             block_pos * info->block.recbuffer)));
 
163
  DBUG_RETURN((uchar*) info->block.level_info[0].last_blocks+
 
164
              block_pos*info->block.recbuffer);
 
165
}
 
166
 
 
167
 
126
168
/*
127
169
  Write a hash-key to the hash-index
128
170
  SYNOPSIS
149
191
*/
150
192
 
151
193
int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
152
 
                 const unsigned char *record, unsigned char *recpos)
 
194
                 const uchar *record, uchar *recpos)
153
195
{
154
196
  HP_SHARE *share = info->s;
155
197
  int flag;
156
 
  uint32_t halfbuff,hashnr,first_index;
157
 
  unsigned char *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
158
 
  HASH_INFO *empty, *gpos= NULL, *gpos2= NULL, *pos;
 
198
  ulong halfbuff,hashnr,first_index;
 
199
  uchar *ptr_to_rec,*ptr_to_rec2;
 
200
  HASH_INFO *empty, *gpos, *gpos2= NULL, *pos;
 
201
  DBUG_ENTER("hp_write_key");
159
202
 
160
203
  flag=0;
161
204
  if (!(empty= hp_find_free_hash(share,&keyinfo->block,share->records)))
162
 
    return(-1);                         /* No more memory */
 
205
    DBUG_RETURN(-1);                            /* No more memory */
163
206
  halfbuff= (long) share->blength >> 1;
164
207
  pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
165
208
  
330
373
      {
331
374
        if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 1))
332
375
        {
333
 
          return(my_errno=HA_ERR_FOUND_DUPP_KEY);
 
376
          DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY);
334
377
        }
335
378
      } while ((pos=pos->next_key));
336
379
    }
337
380
  }
338
 
  return(0);
 
381
  DBUG_RETURN(0);
339
382
}
340
383
 
341
384
        /* Returns ptr to block, and allocates block if neaded */
342
385
 
343
386
static HASH_INFO *hp_find_free_hash(HP_SHARE *info,
344
 
                                     HP_BLOCK *block, uint32_t records)
 
387
                                     HP_BLOCK *block, ulong records)
345
388
{
346
 
  uint32_t block_pos;
 
389
  uint block_pos;
347
390
  size_t length;
348
391
 
349
392
  if (records < block->last_allocated)
355
398
    info->index_length+=length;
356
399
  }
357
400
  block->last_allocated=records+1;
358
 
  return((HASH_INFO*) ((unsigned char*) block->level_info[0].last_blocks+
 
401
  return((HASH_INFO*) ((uchar*) block->level_info[0].last_blocks+
359
402
                       block_pos*block->recbuffer));
360
403
}