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