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

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. /* Written by Sergei A. Golubchik, who has a shared copyright to this code
  14.    added support for long options (my_getopt) 22.5.2002 by Jani Tolonen */
  15. #include "ftdefs.h"
  16. #include <my_getopt.h>
  17. static void usage();
  18. static void complain(int val);
  19. static my_bool get_one_option(int, const struct my_option *, char *);
  20. static int count=0, stats=0, dump=0, lstats=0;
  21. static my_bool verbose;
  22. static char *query=NULL;
  23. static uint lengths[256];
  24. #define MAX_LEN (HA_FT_MAXBYTELEN+10)
  25. #define HOW_OFTEN_TO_WRITE 10000
  26. static struct my_option my_long_options[] =
  27. {
  28.   {"dump", 'd', "Dump index (incl. data offsets and word weights).",
  29.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  30.   {"stats", 's', "Report global stats.",
  31.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  32.   {"verbose", 'v', "Be verbose.",
  33.    (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
  34.   {"count", 'c', "Calculate per-word stats (counts and global weights).",
  35.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  36.   {"length", 'l', "Report length distribution.",
  37.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  38.   {"help", 'h', "Display help and exit.",
  39.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  40.   {"help", '?', "Synonym for -h.",
  41.    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
  42.   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
  43. };
  44. int main(int argc,char *argv[])
  45. {
  46.   int error=0, subkeys;
  47.   uint keylen, keylen2=0, inx, doc_cnt=0;
  48.   float weight= 1.0;
  49.   double gws, min_gws=0, avg_gws=0;
  50.   MI_INFO *info;
  51.   char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN];
  52.   ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0;
  53.   struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */
  54.   MY_INIT(argv[0]);
  55.   if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
  56.     exit(error);
  57.   if (count || dump)
  58.     verbose=0;
  59.   if (!count && !dump && !lstats && !query)
  60.     stats=1;
  61.   if (verbose)
  62.     setbuf(stdout,NULL);
  63.   if (argc < 2)
  64.     usage();
  65.   {
  66.     char *end;
  67.     inx= (uint) strtoll(argv[1], &end, 10);
  68.     if (*end)
  69.       usage();
  70.   }
  71.   init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0);
  72.   if (!(info=mi_open(argv[0],2,HA_OPEN_ABORT_IF_LOCKED)))
  73.   {
  74.     error=my_errno;
  75.     goto err;
  76.   }
  77.   *buf2=0;
  78.   aio->info=info;
  79.   if ((inx >= info->s->base.keys) ||
  80.       !(info->s->keyinfo[inx].flag & HA_FULLTEXT))
  81.   {
  82.     printf("Key %d in table %s is not a FULLTEXT keyn", inx, info->filename);
  83.     goto err;
  84.   }
  85.   mi_lock_database(info, F_EXTRA_LCK);
  86.   info->lastpos= HA_OFFSET_ERROR;
  87.   info->update|= HA_STATE_PREV_FOUND;
  88.   while (!(error=mi_rnext(info,NULL,inx)))
  89.   {
  90.     keylen=*(info->lastkey);
  91.     subkeys=ft_sintXkorr(info->lastkey+keylen+1);
  92.     if (subkeys >= 0)
  93.       weight=*(float*)&subkeys;
  94. #ifdef HAVE_SNPRINTF
  95.     snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1);
  96. #else
  97.     sprintf(buf,"%.*s",(int) keylen,info->lastkey+1);
  98. #endif
  99.     my_casedn_str(default_charset_info,buf);
  100.     total++;
  101.     lengths[keylen]++;
  102.     if (count || stats)
  103.     {
  104.       doc_cnt++;
  105.       if (strcmp(buf, buf2))
  106.       {
  107.         if (*buf2)
  108.         {
  109.           uniq++;
  110.           avg_gws+=gws=GWS_IN_USE;
  111.           if (count)
  112.             printf("%9u %20.7f %sn",doc_cnt,gws,buf2);
  113.           if (maxlen<keylen2)
  114.           {
  115.             maxlen=keylen2;
  116.             strmov(buf_maxlen, buf2);
  117.           }
  118.           if (max_doc_cnt < doc_cnt)
  119.           {
  120.             max_doc_cnt=doc_cnt;
  121.             strmov(buf_min_gws, buf2);
  122.             min_gws=gws;
  123.           }
  124.         }
  125.         strmov(buf2, buf);
  126.         keylen2=keylen;
  127.         doc_cnt=0;
  128.       }
  129.     }
  130.     if (dump)
  131.     {
  132.       if (subkeys>=0)
  133.         printf("%9lx %20.7f %sn", (long) info->lastpos,weight,buf);
  134.       else
  135.         printf("%9lx => %17d %sn",(long) info->lastpos,-subkeys,buf);
  136.     }
  137.     if (verbose && (total%HOW_OFTEN_TO_WRITE)==0)
  138.       printf("%10ldr",total);
  139.   }
  140.   mi_lock_database(info, F_UNLCK);
  141.   if (count || stats)
  142.   {
  143.     doc_cnt++;
  144.     if (*buf2)
  145.     {
  146.       uniq++;
  147.       avg_gws+=gws=GWS_IN_USE;
  148.       if (count)
  149.         printf("%9u %20.7f %sn",doc_cnt,gws,buf2);
  150.       if (maxlen<keylen2)
  151.       {
  152.         maxlen=keylen2;
  153.         strmov(buf_maxlen, buf2);
  154.       }
  155.       if (max_doc_cnt < doc_cnt)
  156.       {
  157.         max_doc_cnt=doc_cnt;
  158.         strmov(buf_min_gws, buf2);
  159.         min_gws=gws;
  160.       }
  161.     }
  162.   }
  163.   if (stats)
  164.   {
  165.     count=0;
  166.     for (inx=0;inx<256;inx++)
  167.     {
  168.       count+=lengths[inx];
  169.       if ((ulong) count >= total/2)
  170.         break;
  171.     }
  172.     printf("Total rows: %lunTotal words: %lun"
  173.            "Unique words: %lunLongest word: %lu chars (%s)n"
  174.            "Median length: %un"
  175.            "Average global weight: %fn"
  176.            "Most common word: %lu times, weight: %f (%s)n",
  177.            (long) info->state->records, total, uniq, maxlen, buf_maxlen,
  178.            inx, avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws);
  179.   }
  180.   if (lstats)
  181.   {
  182.     count=0;
  183.     for (inx=0; inx<256; inx++)
  184.     {
  185.       count+=lengths[inx];
  186.       if (count && lengths[inx])
  187.         printf("%3u: %10lu %5.2f%% %20lu %4.1f%%n", inx,
  188.                (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count,
  189.                100.0*count/total);
  190.     }
  191.   }
  192. err:
  193.   if (error && error != HA_ERR_END_OF_FILE)
  194.     printf("got error %dn",my_errno);
  195.   if (info)
  196.     mi_close(info);
  197.   return 0;
  198. }
  199. static my_bool
  200. get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
  201.        char *argument __attribute__((unused)))
  202. {
  203.   switch(optid) {
  204.   case 'd':
  205.     dump=1;
  206.     complain(count || query);
  207.     break;
  208.   case 's':
  209.     stats=1;
  210.     complain(query!=0);
  211.     break;
  212.   case 'c':
  213.     count= 1;
  214.     complain(dump || query);
  215.     break;
  216.   case 'l':
  217.     lstats=1;
  218.     complain(query!=0);
  219.     break;
  220.   case '?':
  221.   case 'h':
  222.     usage();
  223.   }
  224.   return 0;
  225. }
  226. #include <help_start.h>
  227. static void usage()
  228. {
  229.   printf("Use: myisam_ftdump <table_name> <index_num>n");
  230.   my_print_help(my_long_options);
  231.   my_print_variables(my_long_options);
  232.   NETWARE_SET_SCREEN_MODE(1);
  233.   exit(1);
  234. }
  235. #include <help_end.h>
  236. static void complain(int val) /* Kinda assert :-)  */
  237. {
  238.   if (val)
  239.   {
  240.     printf("You cannot use these options together!n");
  241.     exit(1);
  242.   }
  243. }