~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/heap/_check.c

  • Committer: Jay Pipes
  • Date: 2008-07-16 16:14:22 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080716161422-fy1bl8o5q7m8kglq
Removed all DBUG symbols from heap storage engine

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
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.
6
 
 
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.
11
 
 
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 */
15
 
 
16
 
/* Check that heap-structure is ok */
17
 
 
18
 
#include "heapdef.h"
19
 
 
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);
24
 
 
25
 
 
26
 
/*
27
 
  Check if keys and rows are ok in a heap table
28
 
 
29
 
  SYNOPSIS
30
 
    heap_check_heap()
31
 
    info                Table handler
32
 
    print_status        Prints some extra status
33
 
 
34
 
  NOTES
35
 
    Doesn't change the state of the table handler
36
 
 
37
 
  RETURN VALUES
38
 
    0   ok
39
 
    1 error
40
 
*/
41
 
 
42
 
int heap_check_heap(HP_INFO *info, my_bool print_status)
43
 
{
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");
50
 
 
51
 
  for (error=key= 0 ; key < share->keys ; key++)
52
 
  {
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);
58
 
  }
59
 
  /*
60
 
    This is basicly the same code as in hp_scan, but we repeat it here to
61
 
    get shorter DBUG log file.
62
 
  */
63
 
  for (pos=next_block= 0 ; ; pos++)
64
 
  {
65
 
    if (pos < next_block)
66
 
    {
67
 
      info->current_ptr+= share->block.recbuffer;
68
 
    }
69
 
    else
70
 
    {
71
 
      next_block+= share->block.records_in_block;
72
 
      if (next_block >= share->records+share->deleted)
73
 
      {
74
 
        next_block= share->records+share->deleted;
75
 
        if (pos >= next_block)
76
 
          break;                                /* End of file */
77
 
      }
78
 
    }
79
 
    hp_find_record(info,pos);
80
 
 
81
 
    if (!info->current_ptr[share->reclength])
82
 
      deleted++;
83
 
    else
84
 
      records++;
85
 
  }
86
 
 
87
 
  if (records != share->records || deleted != share->deleted)
88
 
  {
89
 
    DBUG_PRINT("error",("Found rows: %lu (%lu)  deleted %lu (%lu)",
90
 
                        records, (ulong) share->records,
91
 
                        deleted, (ulong) share->deleted));
92
 
    error= 1;
93
 
  }
94
 
  *info= save_info;
95
 
  DBUG_RETURN(error);
96
 
}
97
 
 
98
 
 
99
 
static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
100
 
                         ulong blength, my_bool print_status)
101
 
{
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;
107
 
 
108
 
  error=0;
109
 
  hash_buckets_found= 0;
110
 
  for (i=found=max_links=seek=0 ; i < records ; i++)
111
 
  {
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)
115
 
    {
116
 
      found++;
117
 
      seek++;
118
 
      links=1;
119
 
      while ((hash_info=hash_info->next_key) && found < records + 1)
120
 
      {
121
 
        seek+= ++links;
122
 
        if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
123
 
                                blength, records))
124
 
            != i)
125
 
        {
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;
130
 
        }
131
 
        else
132
 
          found++;
133
 
      }
134
 
      if (links > max_links) max_links=links;
135
 
      hash_buckets_found++;
136
 
    }
137
 
  }
138
 
  if (found != records)
139
 
  {
140
 
    DBUG_PRINT("error",("Found %ld of %ld records", found, records));
141
 
    error=1;
142
 
  }
143
 
  if (keydef->hash_buckets != hash_buckets_found)
144
 
  {
145
 
    DBUG_PRINT("error",("Found %ld buckets, stats shows %ld buckets",
146
 
                        hash_buckets_found, (long) keydef->hash_buckets));
147
 
    error=1;
148
 
  }
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;
162
 
}
163
 
 
164
 
static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
165
 
                            my_bool print_status)
166
 
{
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];
173
 
  
174
 
  if ((key= tree_search_edge(&keydef->rb_tree, info->parents,
175
 
                             &info->last_pos, offsetof(TREE_ELEMENT, left))))
176
 
  {
177
 
    do
178
 
    {
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))
183
 
      {
184
 
        error= 1;
185
 
        DBUG_PRINT("error",("Record in wrong link:  key: %u  Record: 0x%lx\n", 
186
 
                            keynr, (long) recpos));
187
 
      }
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);
194
 
  }
195
 
  if (found != records)
196
 
  {
197
 
    DBUG_PRINT("error",("Found %lu of %lu records", found, records));
198
 
    error= 1;
199
 
  }
200
 
  if (print_status)
201
 
    printf("Key: %d  records: %ld\n", keynr, records);
202
 
  return error;
203
 
}