home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / isam / _key.c < prev    next >
C/C++ Source or Header  |  2000-08-31  |  6KB  |  240 lines

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