28
using namespace drizzled;
28
30
static HASH_INFO *hp_find_free_hash(HP_SHARE *info, HP_BLOCK *block,
31
int heap_write(HP_INFO *info, const uchar *record)
33
int heap_write(HP_INFO *info, const unsigned char *record)
33
35
HP_KEYDEF *keydef, *end;
35
HP_SHARE *share=info->s;
36
uint rec_length, chunk_count;
37
HP_SHARE *share=info->getShare();
38
39
if ((share->records >= share->max_records && share->max_records) ||
39
40
(share->recordspace.total_data_length + share->index_length >= share->max_table_size))
41
return(my_errno=HA_ERR_RECORD_FILE_FULL);
42
return(errno=HA_ERR_RECORD_FILE_FULL);
44
rec_length = hp_get_encoded_data_length(share, record, &chunk_count);
46
if (!(pos=hp_allocate_chunkset(&share->recordspace, chunk_count)))
45
if (!(pos=hp_allocate_chunkset(&share->recordspace, 1)))
50
49
for (keydef = share->keydef, end = keydef + share->keys; keydef < end;
53
if ((*keydef->write_key)(info, keydef, record, pos))
52
if (hp_write_key(info, keydef, record, pos))
70
69
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)
81
70
while (keydef >= share->keydef)
83
if ((*keydef->delete_key)(info, keydef, record, pos, 0))
72
if (hp_delete_key(info, keydef, record, pos, 0))
88
77
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 uchar *record,
100
heap_rb_param custom_arg;
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);
127
83
Write a hash-key to the hash-index
129
85
info Heap table info
131
87
record Table record to added
132
recpos Memory buffer where the table record will be stored if added
88
recpos Memory buffer where the table record will be stored if added
135
Hash index uses HP_BLOCK structure as a 'growable array' of HASH_INFO
91
Hash index uses HP_BLOCK structure as a 'growable array' of HASH_INFO
136
92
structs. Array size == number of entries in hash index.
137
93
hp_mask(hp_rec_hashnr()) maps hash entries values to hash array positions.
138
94
If there are several hash entries with the same hash array position P,
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
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
141
97
positions for which there is no record that should be located at that
142
98
position. The order of elements in the list is arbitrary.
146
102
-1 - Out of memory
147
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
103
HA_ERR_FOUND_DUPP_KEY - Duplicate record on unique key. The record was
148
104
still added and the caller must call hp_delete_key for it.
151
107
int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
152
const uchar *record, uchar *recpos)
108
const unsigned char *record, unsigned char *recpos)
154
HP_SHARE *share = info->s;
110
HP_SHARE *share = info->getShare();
156
112
uint32_t halfbuff,hashnr,first_index;
157
uchar *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
113
unsigned char *ptr_to_rec= NULL,*ptr_to_rec2= NULL;
158
114
HASH_INFO *empty, *gpos= NULL, *gpos2= NULL, *pos;
162
118
return(-1); /* No more memory */
163
119
halfbuff= (long) share->blength >> 1;
164
120
pos= hp_find_hash(&keyinfo->block,(first_index=share->records-halfbuff));
167
123
We're about to add one more hash array position, with hash_mask=#records.
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
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
171
127
guaranteed by properties of hp_mask(hp_rec_hashnr(X)) mapping function)
172
128
At #first_index position currently there may be either:
173
129
a) An entry with hashnr != first_index. We don't need to move it.
175
131
b) A list of items with hash_mask=first_index. The list contains entries
177
1) entries that should be relocated to the list that starts at new
133
1) entries that should be relocated to the list that starts at new
178
134
position we're adding ('uppper' list)
179
2) entries that should be left in the list starting at #first_index
135
2) entries that should be left in the list starting at #first_index
180
136
position ('lower' list)
182
138
if (pos != empty) /* If some records */