_key.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. /* Functions to handle keys */
  17. #include "isamdef.h"
  18. #include "m_ctype.h"
  19. static void _nisam_put_key_in_record(N_INFO *info,uint keynr,byte *record);
  20. /* Make a intern key from a record */
  21. /* If ascii key convert according to sortorder */
  22. /* Ret: Length of key */
  23. uint _nisam_make_key(register N_INFO *info, uint keynr, uchar *key, const char *record, ulong filepos)
  24. {
  25.   uint length;
  26.   byte *pos,*end;
  27.   uchar *start;
  28.   reg1 N_KEYSEG *keyseg;
  29.   enum ha_base_keytype type;
  30.   DBUG_ENTER("_nisam_make_key");
  31.   start=key;
  32.   for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->base.type ;keyseg++)
  33.   {
  34.     type=(enum ha_base_keytype) keyseg->base.type;
  35.     if (keyseg->base.flag & HA_SPACE_PACK)
  36.     {
  37.       pos= (byte*) record+keyseg->base.start; end=pos+keyseg->base.length;
  38.       if (type != HA_KEYTYPE_NUM)
  39.       {
  40. while (end > pos && end[-1] == ' ')
  41.   end--;
  42.       }
  43.       else
  44.       {
  45. while (pos < end && pos[0] == ' ')
  46.   pos++;
  47.       }
  48.       *key++= (uchar) (length=(uint) (end-pos));
  49.       memcpy((byte*) key,(byte*) pos,(size_t) length);
  50. #ifdef USE_STRCOLL
  51.       if (!use_strcoll(default_charset_info))
  52. #endif
  53.       {
  54. if (type == HA_KEYTYPE_TEXT)
  55.   case_sort((byte*) key,length);
  56.       }
  57.       key+=length;
  58.     }
  59.     else
  60.     {
  61.       memcpy((byte*) key,(byte*) record+keyseg->base.start,
  62.      (size_t) keyseg->base.length);
  63. #ifdef USE_STRCOLL
  64.       if (!use_strcoll(default_charset_info))
  65. #endif
  66.       {
  67. if (type == HA_KEYTYPE_TEXT)
  68.   case_sort((byte*) key,(uint) keyseg->base.length);
  69.       }
  70. #ifdef NAN_TEST
  71.       else if (type == HA_KEYTYPE_FLOAT)
  72.       {
  73. float nr;
  74. bmove((byte*) &nr,(byte*) key,sizeof(float));
  75. if (nr == (float) FLT_MAX)
  76. {
  77.   nr= (float) FLT_MAX;
  78.   bmove((byte*) key,(byte*) &nr,sizeof(float));
  79. }
  80.       }
  81.       else if (type == HA_KEYTYPE_DOUBLE)
  82.       {
  83. double nr;
  84. bmove((byte*) &nr,(byte*) key,sizeof(double));
  85. if (nr == DBL_MAX)
  86. {
  87.   nr=DBL_MAX;
  88.   bmove((byte*) key,(byte*) &nr,sizeof(double));
  89. }
  90.       }
  91. #endif
  92.       key+= keyseg->base.length;
  93.     }
  94.   }
  95.   _nisam_dpointer(info,key,filepos);
  96.   DBUG_PRINT("exit",("keynr: %d",keynr));
  97.   DBUG_DUMP("key",(byte*) start,(uint) (key-start)+keyseg->base.length);
  98.   DBUG_EXECUTE("key",_nisam_print_key(DBUG_FILE,info->s->keyinfo[keynr].seg,start););
  99.   DBUG_RETURN((uint) (key-start)); /* Return keylength */
  100. } /* _nisam_make_key */
  101. /* Pack a key to intern format from given format (c_rkey) */
  102. /* if key_length is set returns new length of key */
  103. uint _nisam_pack_key(register N_INFO *info, uint keynr, uchar *key, uchar *old, uint key_length)
  104. /* Length of used key */
  105. {
  106.   int k_length;
  107.   uint length;
  108.   uchar *pos,*end;
  109.   reg1 N_KEYSEG *keyseg;
  110.   enum ha_base_keytype type;
  111.   DBUG_ENTER("_nisam_pack_key");
  112.   if ((k_length=(int) key_length) <= 0)
  113.     k_length=N_MAX_KEY_BUFF;
  114.   for (keyseg=info->s->keyinfo[keynr].seg ;
  115.        keyseg->base.type && k_length >0;
  116.        k_length-=keyseg->base.length, old+=keyseg->base.length, keyseg++)
  117.   {
  118.     length=min((uint) keyseg->base.length,(uint) k_length);
  119.     type=(enum ha_base_keytype) keyseg->base.type;
  120.     if (keyseg->base.flag & HA_SPACE_PACK)
  121.     {
  122.       pos=old; end=pos+length;
  123.       if (type != HA_KEYTYPE_NUM)
  124.       {
  125. while (end > pos && end[-1] == ' ')
  126.   end--;
  127.       }
  128.       else
  129.       {
  130. while (pos < end && pos[0] == ' ')
  131.   pos++;
  132.       }
  133.       *key++ = (uchar) (length=(uint) (end-pos));
  134.       memcpy((byte*) key,pos,(size_t) length);
  135.     }
  136.     else
  137.       memcpy((byte*) key,old,(size_t) length);
  138. #ifdef USE_STRCOLL
  139.       if (!use_strcoll(default_charset_info))
  140. #endif
  141.       {
  142. if (type == HA_KEYTYPE_TEXT)
  143.   case_sort((byte*) key,length);
  144.       }
  145.       key+= length;
  146.   }
  147.   if (!keyseg->base.type)
  148.   {
  149.     if (k_length >= 0) /* Hole key */
  150.       key_length=0;
  151.   }
  152.   else
  153.   { /* Part-key ; fill with null */
  154.     length= (uint) -k_length; /* unused part of last key */
  155.     do
  156.     {
  157.       length+= (keyseg->base.flag & HA_SPACE_PACK) ? 1 :
  158. keyseg->base.length;
  159.       keyseg++;
  160.     } while (keyseg->base.type);
  161.     bzero((byte*) key,length);
  162.   }
  163.   DBUG_RETURN(key_length); /* Return part-keylength */
  164. } /* _nisam_pack_key */
  165. /* Put a key in record */
  166. /* Used when only-keyread is wanted */
  167. static void _nisam_put_key_in_record(register N_INFO *info, uint keynr, byte *record)
  168. {
  169.   uint length;
  170.   reg2 byte *key;
  171.   byte *pos;
  172.   reg1 N_KEYSEG *keyseg;
  173.   DBUG_ENTER("_nisam_put_key_in_record");
  174.   key=(byte*) info->lastkey;
  175.   for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->base.type ;keyseg++)
  176.   {
  177.     if (keyseg->base.flag & HA_SPACE_PACK)
  178.     {
  179.       length= (uint) (uchar) *key++;
  180.       pos= record+keyseg->base.start;
  181.       if (keyseg->base.type != (int) HA_KEYTYPE_NUM)
  182.       {
  183. memcpy(pos,key,(size_t) length);
  184. bfill(pos+length,keyseg->base.length-length,' ');
  185.       }
  186.       else
  187.       {
  188. bfill(pos,keyseg->base.length-length,' ');
  189. memcpy(pos+keyseg->base.length-length,key,(size_t) length);
  190.       }
  191.       key+=length;
  192.     }
  193.     else
  194.     {
  195.       memcpy(record+keyseg->base.start,(byte*) key,
  196.      (size_t) keyseg->base.length);
  197.       key+= keyseg->base.length;
  198.     }
  199.   }
  200.   DBUG_VOID_RETURN;
  201. } /* _nisam_put_key_in_record */
  202. /* Here when key reads are used */
  203. int _nisam_read_key_record(N_INFO *info, ulong filepos, byte *buf)
  204. {
  205.   VOID(_nisam_writeinfo(info,0));
  206.   if (filepos != NI_POS_ERROR)
  207.   {
  208.     if (info->lastinx >= 0)
  209.     { /* Read only key */
  210.       _nisam_put_key_in_record(info,(uint) info->lastinx,buf);
  211.       info->update|= HA_STATE_AKTIV; /* We should find a record */
  212.       return 0;
  213.     }
  214.     my_errno=HA_ERR_WRONG_INDEX;
  215.     return(-1);
  216.   }
  217.   return(-1); /* Wrong data to read */
  218. }