_check.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* Check that heap-structure is ok */
  14. #include "heapdef.h"
  15. static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
  16.  ulong blength, my_bool print_status);
  17. static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
  18.     my_bool print_status);
  19. /*
  20.   Check if keys and rows are ok in a heap table
  21.   SYNOPSIS
  22.     heap_check_heap()
  23.     info Table handler
  24.     print_status Prints some extra status
  25.   NOTES
  26.     Doesn't change the state of the table handler
  27.   RETURN VALUES
  28.     0 ok
  29.     1 error
  30. */
  31. int heap_check_heap(HP_INFO *info, my_bool print_status)
  32. {
  33.   int error;
  34.   uint key;
  35.   ulong records=0, deleted=0, pos, next_block;
  36.   HP_SHARE *share=info->s;
  37.   HP_INFO save_info= *info; /* Needed because scan_init */
  38.   DBUG_ENTER("heap_check_heap");
  39.   for (error=key= 0 ; key < share->keys ; key++)
  40.   {
  41.     if (share->keydef[key].algorithm == HA_KEY_ALG_BTREE)
  42.       error|= check_one_rb_key(info, key, share->records, print_status);
  43.     else
  44.       error|= check_one_key(share->keydef + key, key, share->records,
  45.     share->blength, print_status);
  46.   }
  47.   /*
  48.     This is basicly the same code as in hp_scan, but we repeat it here to
  49.     get shorter DBUG log file.
  50.   */
  51.   for (pos=next_block= 0 ; ; pos++)
  52.   {
  53.     if (pos < next_block)
  54.     {
  55.       info->current_ptr+= share->block.recbuffer;
  56.     }
  57.     else
  58.     {
  59.       next_block+= share->block.records_in_block;
  60.       if (next_block >= share->records+share->deleted)
  61.       {
  62. next_block= share->records+share->deleted;
  63. if (pos >= next_block)
  64.   break; /* End of file */
  65.       }
  66.     }
  67.     hp_find_record(info,pos);
  68.     if (!info->current_ptr[share->reclength])
  69.       deleted++;
  70.     else
  71.       records++;
  72.   }
  73.   if (records != share->records || deleted != share->deleted)
  74.   {
  75.     DBUG_PRINT("error",("Found rows: %lu (%lu)  deleted %lu (%lu)",
  76. records, share->records, deleted, share->deleted));
  77.     error= 1;
  78.   }
  79.   *info= save_info;
  80.   DBUG_RETURN(error);
  81. }
  82. static int check_one_key(HP_KEYDEF *keydef, uint keynr, ulong records,
  83.  ulong blength, my_bool print_status)
  84. {
  85.   int error;
  86.   uint i,found,max_links,seek,links;
  87.   uint rec_link; /* Only used with debugging */
  88.   uint hash_buckets_found;
  89.   HASH_INFO *hash_info;
  90.   error=0;
  91.   hash_buckets_found= 0;
  92.   for (i=found=max_links=seek=0 ; i < records ; i++)
  93.   {
  94.     hash_info=hp_find_hash(&keydef->block,i);
  95.     if (hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
  96. blength,records) == i)
  97.     {
  98.       found++;
  99.       seek++;
  100.       links=1;
  101.       while ((hash_info=hash_info->next_key) && found < records + 1)
  102.       {
  103. seek+= ++links;
  104. if ((rec_link = hp_mask(hp_rec_hashnr(keydef, hash_info->ptr_to_rec),
  105.         blength, records))
  106.     != i)
  107. {
  108.   DBUG_PRINT("error",("Record in wrong link: Link %d  Record: %lx  Record-link %d", i,hash_info->ptr_to_rec,rec_link));
  109.   error=1;
  110. }
  111. else
  112.   found++;
  113.       }
  114.       if (links > max_links) max_links=links;
  115.       hash_buckets_found++;
  116.     }
  117.   }
  118.   if (found != records)
  119.   {
  120.     DBUG_PRINT("error",("Found %ld of %ld records", found, records));
  121.     error=1;
  122.   }
  123.   if (keydef->hash_buckets != hash_buckets_found)
  124.   {
  125.     DBUG_PRINT("error",("Found %ld buckets, stats shows %ld buckets",
  126.                         hash_buckets_found, keydef->hash_buckets));
  127.     error=1;
  128.   }
  129.   DBUG_PRINT("info",
  130.      ("records: %ld   seeks: %d   max links: %d   hitrate: %.2f   "
  131.               "buckets: %d",
  132.       records,seek,max_links,
  133.       (float) seek / (float) (records ? records : 1), 
  134.               hash_buckets_found));
  135.   if (print_status)
  136.     printf("Key: %d  records: %ld   seeks: %d   max links: %d   "
  137.            "hitrate: %.2f   buckets: %dn",
  138.    keynr, records, seek, max_links,
  139.    (float) seek / (float) (records ? records : 1), 
  140.            hash_buckets_found);
  141.   return error;
  142. }
  143. static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records,
  144.     my_bool print_status)
  145. {
  146.   HP_KEYDEF *keydef= info->s->keydef + keynr;
  147.   int error= 0;
  148.   ulong found= 0;
  149.   byte *key, *recpos;
  150.   uint key_length;
  151.   uint not_used[2];
  152.   
  153.   if ((key= tree_search_edge(&keydef->rb_tree, info->parents,
  154.      &info->last_pos, offsetof(TREE_ELEMENT, left))))
  155.   {
  156.     do
  157.     {
  158.       memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(byte*));
  159.       key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0);
  160.       if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key,
  161.      key_length, SEARCH_FIND | SEARCH_SAME, not_used))
  162.       {
  163. error= 1;
  164. DBUG_PRINT("error",("Record in wrong link:  key: %d  Record: %lxn", 
  165.     keynr, recpos));
  166.       }
  167.       else
  168. found++;
  169.       key= tree_search_next(&keydef->rb_tree, &info->last_pos,
  170.     offsetof(TREE_ELEMENT, left), 
  171.     offsetof(TREE_ELEMENT, right));
  172.     } while (key);
  173.   }
  174.   if (found != records)
  175.   {
  176.     DBUG_PRINT("error",("Found %lu of %lu records", found, records));
  177.     error= 1;
  178.   }
  179.   if (print_status)
  180.     printf("Key: %d  records: %ldn", keynr, records);
  181.   return error;
  182. }