29 static uchar *next_free_record_pos(
HP_SHARE *info);
38 DBUG_ENTER(
"heap_write");
40 if (info->mode & O_RDONLY)
42 DBUG_RETURN(my_errno=EACCES);
45 if (!(pos=next_free_record_pos(share)))
46 DBUG_RETURN(my_errno);
49 for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
52 if ((*keydef->write_key)(info, keydef, record, pos))
56 memcpy(pos,record,(
size_t) share->reclength);
57 pos[share->reclength]=1;
58 if (++share->records == share->blength)
59 share->blength+= share->blength;
60 info->current_ptr=pos;
61 info->current_hash_ptr=0;
62 info->update|=HA_STATE_AKTIV;
63 #if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
64 DBUG_EXECUTE(
"check_heap",heap_check_heap(info, 0););
67 heap_update_auto_increment(info, record);
71 if (my_errno == HA_ERR_FOUND_DUPP_KEY)
72 DBUG_PRINT(
"info",(
"Duplicate key: %d", (
int) (keydef - share->keydef)));
73 info->errkey= (int) (keydef - share->keydef);
80 if (keydef->algorithm == HA_KEY_ALG_BTREE || my_errno == ENOMEM)
84 while (keydef >= share->keydef)
86 if ((*keydef->delete_key)(info, keydef, record, pos, 0))
92 *((uchar**) pos)=share->del_link;
94 pos[share->reclength]=0;
96 DBUG_RETURN(my_errno);
109 custom_arg.keyseg= keyinfo->seg;
110 custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
111 if (keyinfo->flag & HA_NOSAME)
113 custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE;
114 keyinfo->rb_tree.flag= TREE_NO_DUPS;
118 custom_arg.search_flag= SEARCH_SAME;
119 keyinfo->rb_tree.flag= 0;
121 old_allocated= keyinfo->rb_tree.allocated;
122 if (!tree_insert(&keyinfo->rb_tree, (
void*)info->recbuf,
123 custom_arg.key_length, &custom_arg))
125 my_errno= HA_ERR_FOUND_DUPP_KEY;
128 info->s->index_length+= (keyinfo->rb_tree.allocated-old_allocated);
134 static uchar *next_free_record_pos(
HP_SHARE *info)
139 DBUG_ENTER(
"next_free_record_pos");
144 info->del_link= *((uchar**) pos);
146 DBUG_PRINT(
"exit",(
"Used old position: 0x%lx",(
long) pos));
149 if (!(block_pos=(info->records % info->block.records_in_block)))
151 if ((info->records > info->max_records && info->max_records) ||
152 (info->data_length + info->index_length >= info->max_table_size))
154 my_errno=HA_ERR_RECORD_FILE_FULL;
157 if (hp_get_new_block(&info->block,&length))
159 info->data_length+=length;
161 DBUG_PRINT(
"exit",(
"Used new position: 0x%lx",
162 (
long) ((uchar*) info->block.level_info[0].last_blocks+
163 block_pos * info->block.recbuffer)));
164 DBUG_RETURN((uchar*) info->block.level_info[0].last_blocks+
165 block_pos*info->block.recbuffer);
195 const uchar *record, uchar *recpos)
199 ulong halfbuff,hashnr,first_index;
200 uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
201 HASH_INFO *empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
202 DBUG_ENTER(
"hp_write_key");
205 if (!(empty= hp_find_free_hash(share,&keyinfo->block,share->records)))
207 halfbuff= (long) share->blength >> 1;
208 pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
230 hashnr = hp_rec_hashnr(keyinfo, pos->ptr_to_rec);
237 if (hp_mask(hashnr, share->blength, share->records) != first_index)
251 if (!(hashnr & halfbuff))
254 if (!(flag & LOWFIND))
259 flag=LOWFIND | HIGHFIND;
262 ptr_to_rec=pos->ptr_to_rec;
271 flag=LOWFIND | LOWUSED;
273 ptr_to_rec=pos->ptr_to_rec;
279 if (!(flag & LOWUSED))
282 gpos->ptr_to_rec=ptr_to_rec;
284 flag= (flag & HIGHFIND) | (LOWFIND | LOWUSED);
287 ptr_to_rec=pos->ptr_to_rec;
293 if (!(flag & HIGHFIND))
295 flag= (flag & LOWFIND) | HIGHFIND;
299 ptr_to_rec2=pos->ptr_to_rec;
303 if (!(flag & HIGHUSED))
306 gpos2->ptr_to_rec=ptr_to_rec2;
308 flag= (flag & LOWFIND) | (HIGHFIND | HIGHUSED);
311 ptr_to_rec2=pos->ptr_to_rec;
315 while ((pos=pos->next_key));
317 if ((flag & (LOWFIND | HIGHFIND)) == (LOWFIND | HIGHFIND))
323 keyinfo->hash_buckets++;
326 if ((flag & (LOWFIND | LOWUSED)) == LOWFIND)
328 gpos->ptr_to_rec=ptr_to_rec;
331 if ((flag & (HIGHFIND | HIGHUSED)) == HIGHFIND)
333 gpos2->ptr_to_rec=ptr_to_rec2;
339 pos=hp_find_hash(&keyinfo->block, hp_mask(hp_rec_hashnr(keyinfo, record),
340 share->blength, share->records + 1));
343 pos->ptr_to_rec=recpos;
345 keyinfo->hash_buckets++;
351 gpos=hp_find_hash(&keyinfo->block,
352 hp_mask(hp_rec_hashnr(keyinfo, pos->ptr_to_rec),
353 share->blength, share->records + 1));
356 pos->ptr_to_rec=recpos;
361 keyinfo->hash_buckets++;
362 pos->ptr_to_rec=recpos;
364 hp_movelink(pos, gpos, empty);
368 if ((keyinfo->flag & HA_NOSAME) && pos == gpos &&
369 (!(keyinfo->flag & HA_NULL_PART_KEY) ||
370 !hp_if_null_in_key(keyinfo, record)))
375 if (! hp_rec_key_cmp(keyinfo, record, pos->ptr_to_rec, 1))
377 DBUG_RETURN(my_errno=HA_ERR_FOUND_DUPP_KEY);
379 }
while ((pos=pos->next_key));
393 if (records < block->last_allocated)
394 return hp_find_hash(block,records);
395 if (!(block_pos=(records % block->records_in_block)))
397 if (hp_get_new_block(block,&length))
399 info->index_length+=length;
401 block->last_allocated=records+1;
402 return((
HASH_INFO*) ((uchar*) block->level_info[0].last_blocks+
403 block_pos*block->recbuffer));