35
33
HP_KEYDEF *keydef, *end;
36
34
unsigned char *pos;
37
HP_SHARE *share=info->getShare();
35
HP_SHARE *share=info->s;
36
uint32_t rec_length, chunk_count;
39
38
if ((share->records >= share->max_records && share->max_records) ||
40
39
(share->recordspace.total_data_length + share->index_length >= share->max_table_size))
42
return(errno=HA_ERR_RECORD_FILE_FULL);
41
return(my_errno=HA_ERR_RECORD_FILE_FULL);
45
if (!(pos=hp_allocate_chunkset(&share->recordspace, 1)))
44
rec_length = hp_get_encoded_data_length(share, record, &chunk_count);
46
if (!(pos=hp_allocate_chunkset(&share->recordspace, chunk_count)))
49
50
for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
52
if (hp_write_key(info, keydef, record, pos))
53
if ((*keydef->write_key)(info, keydef, record, pos))
69
70
info->errkey= keydef - share->keydef;
72
We don't need to delete non-inserted key from rb-tree. Also, if
73
we got ENOMEM, the key wasn't inserted, so don't try to delete it
74
either. Otherwise for HASH index on HA_ERR_FOUND_DUPP_KEY the key
75
was inserted and we have to delete it.
77
if (keydef->algorithm == HA_KEY_ALG_BTREE || my_errno == ENOMEM)
70
81
while (keydef >= share->keydef)
72
if (hp_delete_key(info, keydef, record, pos, 0))
83
if ((*keydef->delete_key)(info, keydef, record, pos, 0))
77
88
hp_free_chunks(&share->recordspace, pos);
94
Write a key to rb_tree-index
97
int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const unsigned char *record,
98
unsigned char *recpos)
100
heap_rb_param custom_arg;
101
uint32_t old_allocated;
103
custom_arg.keyseg= keyinfo->seg;
104
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
105
if (keyinfo->flag & HA_NOSAME)
107
custom_arg.search_flag= SEARCH_FIND | SEARCH_UPDATE;
108
keyinfo->rb_tree.flag= TREE_NO_DUPS;
112
custom_arg.search_flag= SEARCH_SAME;
113
keyinfo->rb_tree.flag= 0;
115
old_allocated= keyinfo->rb_tree.allocated;
116
if (!tree_insert(&keyinfo->rb_tree, (void*)info->recbuf,
117
custom_arg.key_length, &custom_arg))
119
my_errno= HA_ERR_FOUND_DUPP_KEY;
122
info->s->index_length+= (keyinfo->rb_tree.allocated-old_allocated);
83
127
Write a hash-key to the hash-index
85
129
info Heap table info
87
131
record Table record to added
88
recpos Memory buffer where the table record will be stored if added
132
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
135
Hash index uses HP_BLOCK structure as a 'growable array' of HASH_INFO
92
136
structs. Array size == number of entries in hash index.
93
137
hp_mask(hp_rec_hashnr()) maps hash entries values to hash array positions.
94
138
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
139
they are connected in a linked list via HASH_INFO::next_key. The first
140
list element is located at position P, next elements are located at
97
141
positions for which there is no record that should be located at that
98
142
position. The order of elements in the list is arbitrary.
102
146
-1 - Out of memory
103
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
147
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
104
148
still added and the caller must call hp_delete_key for it.
107
151
int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
108
152
const unsigned char *record, unsigned char *recpos)
110
HP_SHARE *share = info->getShare();
154
HP_SHARE *share = info->s;
112
156
uint32_t halfbuff,hashnr,first_index;
113
157
unsigned char *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
118
162
return(-1); /* No more memory */
119
163
halfbuff= (long) share->blength >> 1;
120
164
pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
123
167
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
168
The number of hash positions will change and some entries might need to
169
be relocated to the newly added position. Those entries are currently
170
members of the list that starts at #first_index position (this is
127
171
guaranteed by properties of hp_mask(hp_rec_hashnr(X)) mapping function)
128
172
At #first_index position currently there may be either:
129
173
a) An entry with hashnr != first_index. We don't need to move it.
131
175
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
177
1) entries that should be relocated to the list that starts at new
134
178
position we're adding ('uppper' list)
135
2) entries that should be left in the list starting at #first_index
179
2) entries that should be left in the list starting at #first_index
136
180
position ('lower' list)
138
182
if (pos != empty) /* If some records */