28
using namespace drizzled;
28
static uchar *next_free_record_pos(HP_SHARE *info);
30
29
static HASH_INFO *hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block,
33
int heap_write(HP_INFO *info, const unsigned char *record)
32
int heap_write(HP_INFO *info, const uchar *record)
35
34
HP_KEYDEF *keydef, *end;
37
HP_SHARE *share=info->getShare();
39
if ((share->records >= share->max_records && share->max_records) ||
40
(share->recordspace.total_data_length + share->index_length >= share->max_table_size))
42
return(errno=HA_ERR_RECORD_FILE_FULL);
45
if (!(pos=hp_allocate_chunkset(&share->recordspace, 1)))
36
HP_SHARE *share=info->s;
37
if (!(pos=next_free_record_pos(share)))
49
41
for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
52
if (hp_write_key(info, keydef, record, pos))
44
if ((*keydef->write_key)(info, keydef, record, pos))
56
hp_copy_record_data_to_chunkset(share, record, pos);
48
memcpy(pos,record,(size_t) share->reclength);
49
pos[share->reclength]=1; /* Mark record as not deleted */
58
50
if (++share->records == share->blength)
59
51
share->blength+= share->blength;
61
52
info->current_ptr=pos;
62
53
info->current_hash_ptr=0;
63
54
info->update|=HA_STATE_AKTIV;
69
60
info->errkey= keydef - share->keydef;
62
We don't need to delete non-inserted key from rb-tree. Also, if
63
we got ENOMEM, the key wasn't inserted, so don't try to delete it
64
either. Otherwise for HASH index on HA_ERR_FOUND_DUPP_KEY the key
65
was inserted and we have to delete it.
67
if (keydef->algorithm == HA_KEY_ALG_BTREE || my_errno == ENOMEM)
70
71
while (keydef >= share->keydef)
72
if (hp_delete_key(info, keydef, record, pos, 0))
73
if ((*keydef->delete_key)(info, keydef, record, pos, 0))
77
hp_free_chunks(&share->recordspace, pos);
79
*((uchar**) pos)=share->del_link;
81
pos[share->reclength]=0; /* Record deleted */
87
Write a key to rb_tree-index
90
int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const uchar *record,
93
heap_rb_param custom_arg;
96
custom_arg.keyseg= keyinfo->seg;
97
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
98
if (keyinfo->flag & HA_NOSAME)
100
custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE;
101
keyinfo->rb_tree.flag= TREE_NO_DUPS;
105
custom_arg.search_flag= SEARCH_SAME;
106
keyinfo->rb_tree.flag= 0;
108
old_allocated= keyinfo->rb_tree.allocated;
109
if (!tree_insert(&keyinfo->rb_tree, (void*)info->recbuf,
110
custom_arg.key_length, &custom_arg))
112
my_errno= HA_ERR_FOUND_DUPP_KEY;
115
info->s->index_length+= (keyinfo->rb_tree.allocated-old_allocated);
119
/* Find where to place new record */
121
static uchar *next_free_record_pos(HP_SHARE *info)
130
info->del_link= *((uchar**) pos);
134
if (!(block_pos=(info->records % info->block.records_in_block)))
136
if ((info->records > info->max_records && info->max_records) ||
137
(info->data_length + info->index_length >= info->max_table_size))
139
my_errno=HA_ERR_RECORD_FILE_FULL;
142
if (hp_get_new_block(&info->block,&length))
144
info->data_length+=length;
146
return((uchar*) info->block.level_info[0].last_blocks+
147
block_pos*info->block.recbuffer);
83
152
Write a hash-key to the hash-index
85
154
info Heap table info
87
156
record Table record to added
88
recpos Memory buffer where the table record will be stored if added
157
recpos Memory buffer where the table record will be stored if added
91
Hash index uses HP_BLOCK structure as a 'growable array' of HASH_INFO
160
Hash index uses HP_BLOCK structure as a 'growable array' of HASH_INFO
92
161
structs. Array size == number of entries in hash index.
93
162
hp_mask(hp_rec_hashnr()) maps hash entries values to hash array positions.
94
163
If there are several hash entries with the same hash array position P,
95
they are connected in a linked list via HASH_INFO::next_key. The first
96
list element is located at position P, next elements are located at
164
they are connected in a linked list via HASH_INFO::next_key. The first
165
list element is located at position P, next elements are located at
97
166
positions for which there is no record that should be located at that
98
167
position. The order of elements in the list is arbitrary.
102
171
-1 - Out of memory
103
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
172
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
104
173
still added and the caller must call hp_delete_key for it.
107
176
int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
108
const unsigned char *record, unsigned char *recpos)
177
const uchar *record, uchar *recpos)
110
HP_SHARE *share = info->getShare();
179
HP_SHARE *share = info->s;
112
uint32_t halfbuff,hashnr,first_index;
113
unsigned char *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
181
ulong halfbuff,hashnr,first_index;
182
uchar *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
114
183
HASH_INFO *empty, *gpos= NULL, *gpos2= NULL, *pos;
118
187
return(-1); /* No more memory */
119
188
halfbuff= (long) share->blength >> 1;
120
189
pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
123
192
We're about to add one more hash array position, with hash_mask=#records.
124
The number of hash positions will change and some entries might need to
125
be relocated to the newly added position. Those entries are currently
126
members of the list that starts at #first_index position (this is
193
The number of hash positions will change and some entries might need to
194
be relocated to the newly added position. Those entries are currently
195
members of the list that starts at #first_index position (this is
127
196
guaranteed by properties of hp_mask(hp_rec_hashnr(X)) mapping function)
128
197
At #first_index position currently there may be either:
129
198
a) An entry with hashnr != first_index. We don't need to move it.
131
200
b) A list of items with hash_mask=first_index. The list contains entries
133
1) entries that should be relocated to the list that starts at new
202
1) entries that should be relocated to the list that starts at new
134
203
position we're adding ('uppper' list)
135
2) entries that should be left in the list starting at #first_index
204
2) entries that should be left in the list starting at #first_index
136
205
position ('lower' list)
138
207
if (pos != empty) /* If some records */