1
/* Copyright (C) 2000-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* Check that heap-structure is ok */
20
static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
21
ulong blength, my_bool print_status);
22
static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
23
my_bool print_status);
27
Check if keys and rows are ok in a heap table
32
print_status Prints some extra status
35
Doesn't change the state of the table handler
42
int heap_check_heap(HP_INFO *info, my_bool print_status)
46
ulong records=0, deleted=0, pos, next_block;
47
HP_SHARE *share=info->s;
48
HP_INFO save_info= *info; /* Needed because scan_init */
49
DBUG_ENTER("heap_check_heap");
51
for (error=key= 0 ; key < share->keys ; key++)
53
if (share->keydef[key].algorithm == HA_KEY_ALG_BTREE)
54
error|= check_one_rb_key(info, key, share->records, print_status);
56
error|= check_one_key(share->keydef + key, key, share->records,
57
share->blength, print_status);
60
This is basicly the same code as in hp_scan, but we repeat it here to
61
get shorter DBUG log file.
63
for (pos=next_block= 0 ; ; pos++)
67
info->current_ptr+= share->block.recbuffer;
71
next_block+= share->block.records_in_block;
72
if (next_block >= share->records+share->deleted)
74
next_block= share->records+share->deleted;
75
if (pos >= next_block)
76
break; /* End of file */
79
hp_find_record(info,pos);
81
if (!info->current_ptr[share->reclength])
87
if (records != share->records || deleted != share->deleted)
89
DBUG_PRINT("error",("Found rows: %lu (%lu) deleted %lu (%lu)",
90
records, (ulong) share->records,
91
deleted, (ulong) share->deleted));
99
static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
100
ulong blength, my_bool print_status)
103
ulong i,found,max_links,seek,links;
104
ulong rec_link; /* Only used with debugging */
105
ulong hash_buckets_found;
106
HASH_INFO *hash_info;
109
hash_buckets_found= 0;
110
for (i=found=max_links=seek=0 ; i < records ; i++)
112
hash_info=hp_find_hash(&keydef->block,i);
113
if (hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
114
blength,records) == i)
119
while ((hash_info=hash_info->next_key) && found < records + 1)
122
if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
127
("Record in wrong link: Link %lu Record: 0x%lx Record-link %lu",
128
i, (long) hash_info->ptr_to_rec, rec_link));
134
if (links > max_links) max_links=links;
135
hash_buckets_found++;
138
if (found != records)
140
DBUG_PRINT("error",("Found %ld of %ld records", found, records));
143
if (keydef->hash_buckets != hash_buckets_found)
145
DBUG_PRINT("error",("Found %ld buckets, stats shows %ld buckets",
146
hash_buckets_found, (long) keydef->hash_buckets));
150
("records: %ld seeks: %lu max links: %lu hitrate: %.2f "
152
records,seek,max_links,
153
(float) seek / (float) (records ? records : 1),
154
hash_buckets_found));
156
printf("Key: %d records: %ld seeks: %lu max links: %lu "
157
"hitrate: %.2f buckets: %lu\n",
158
keynr, records, seek, max_links,
159
(float) seek / (float) (records ? records : 1),
164
static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
165
my_bool print_status)
167
HP_KEYDEF *keydef= info->s->keydef + keynr;
174
if ((key= tree_search_edge(&keydef->rb_tree, info->parents,
175
&info->last_pos, offsetof(TREE_ELEMENT, left))))
179
memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(uchar*));
180
key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0);
181
if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key,
182
key_length, SEARCH_FIND | SEARCH_SAME, not_used))
185
DBUG_PRINT("error",("Record in wrong link: key: %u Record: 0x%lx\n",
186
keynr, (long) recpos));
190
key= tree_search_next(&keydef->rb_tree, &info->last_pos,
191
offsetof(TREE_ELEMENT, left),
192
offsetof(TREE_ELEMENT, right));
195
if (found != records)
197
DBUG_PRINT("error",("Found %lu of %lu records", found, records));
201
printf("Key: %d records: %ld\n", keynr, records);