mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / heap / _check.c
blob46c3261c4e8ca58b9be5f032124d0b7a02dcc207
1 /* Copyright (c) 2000, 2002-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 /* Check that heap-structure is ok */
18 #include "heapdef.h"
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
29 SYNOPSIS
30 heap_check_heap()
31 info Table handler
32 print_status Prints some extra status
34 NOTES
35 Doesn't change the state of the table handler
37 RETURN VALUES
38 0 ok
39 1 error
42 int heap_check_heap(HP_INFO *info, my_bool print_status)
44 int error;
45 uint key;
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);
55 else
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++)
65 if (pos < next_block)
67 info->current_ptr+= share->block.recbuffer;
69 else
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])
82 deleted++;
83 else
84 records++;
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));
92 error= 1;
94 *info= save_info;
95 DBUG_RETURN(error);
99 static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
100 ulong blength, my_bool print_status)
102 int error;
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;
108 error=0;
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)
116 found++;
117 seek++;
118 links=1;
119 while ((hash_info=hash_info->next_key) && found < records + 1)
121 seek+= ++links;
122 if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
123 blength, records))
124 != i)
126 DBUG_PRINT("error",
127 ("Record in wrong link: Link %lu Record: 0x%lx Record-link %lu",
128 i, (long) hash_info->ptr_to_rec, rec_link));
129 error=1;
131 else
132 found++;
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));
141 error=1;
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));
147 error=1;
149 DBUG_PRINT("info",
150 ("records: %ld seeks: %lu max links: %lu hitrate: %.2f "
151 "buckets: %lu",
152 records,seek,max_links,
153 (float) seek / (float) (records ? records : 1),
154 hash_buckets_found));
155 if (print_status)
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),
160 hash_buckets_found);
161 return error;
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;
168 int error= 0;
169 ulong found= 0;
170 uchar *key, *recpos;
171 uint key_length;
172 uint not_used[2];
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))
184 error= 1;
185 DBUG_PRINT("error",("Record in wrong link: key: %u Record: 0x%lx\n",
186 keynr, (long) recpos));
188 else
189 found++;
190 key= tree_search_next(&keydef->rb_tree, &info->last_pos,
191 offsetof(TREE_ELEMENT, left),
192 offsetof(TREE_ELEMENT, right));
193 } while (key);
195 if (found != records)
197 DBUG_PRINT("error",("Found %lu of %lu records", found, records));
198 error= 1;
200 if (print_status)
201 printf("Key: %d records: %ld\n", keynr, records);
202 return error;