home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / myisam / mi_page.c < prev    next >
C/C++ Source or Header  |  2000-10-17  |  4KB  |  148 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. /* Read and write key blocks */
  18.  
  19. #include "myisamdef.h"
  20. #ifdef    __WIN__
  21. #include <errno.h>
  22. #endif
  23.  
  24.     /* Fetch a key-page in memory */
  25.  
  26. uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
  27.              my_off_t page, uchar *buff, int return_buffer)
  28. {
  29.   uchar *tmp;
  30.   uint page_size;
  31.   tmp=(uchar*) key_cache_read(info->s->kfile,page,(byte*) buff,
  32.                  (uint) keyinfo->block_length,
  33.                  (uint) keyinfo->block_length,
  34.                  return_buffer);
  35.   if (tmp == info->buff)
  36.     info->buff_used=1;
  37.   else if (!tmp)
  38.   {
  39.     DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno));
  40.     info->last_keypage=HA_OFFSET_ERROR;
  41.     my_errno=HA_ERR_CRASHED;
  42.     return 0;
  43.   }
  44.   info->last_keypage=page;
  45.   page_size=mi_getint(tmp);
  46.   if (page_size < 4 || page_size > keyinfo->block_length)
  47.   {
  48.     DBUG_PRINT("error",("page %lu had wrong page length: %u",
  49.             (ulong) page, page_size));
  50.     info->last_keypage = HA_OFFSET_ERROR;
  51.     my_errno = HA_ERR_CRASHED;
  52.     tmp = 0;
  53.   }
  54.   return tmp;
  55. } /* _mi_fetch_keypage */
  56.  
  57.  
  58.     /* Write a key-page on disk */
  59.  
  60. int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
  61.               my_off_t page, uchar *buff)
  62. {
  63.   reg3 uint length;
  64. #ifndef FAST                    /* Safety check */
  65.   if (page < info->s->base.keystart ||
  66.       page+keyinfo->block_length > info->state->key_file_length ||
  67.       page & (myisam_block_size-1))
  68.   {
  69.     DBUG_PRINT("error",("Trying to write outside key region: %lu",
  70.             (long) page));
  71.     my_errno=EINVAL;
  72.     return(-1);
  73.   }
  74.   DBUG_PRINT("page",("write page at: %lu",(long) page,buff));
  75.   DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
  76. #endif
  77.  
  78.   if ((length=keyinfo->block_length) > IO_SIZE*2 &&
  79.       info->state->key_file_length != page+length)
  80.     length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1));
  81. #ifdef HAVE_purify
  82.   {
  83.     length=mi_getint(buff);
  84.     bzero((byte*) buff+length,keyinfo->block_length-length);
  85.     length=keyinfo->block_length;
  86.   }
  87. #endif
  88.   return (key_cache_write(info->s->kfile,page,(byte*) buff,length,
  89.              (uint) keyinfo->block_length,
  90.              (int) ((info->lock_type != F_UNLCK) ||
  91.                 info->s->delay_key_write)));
  92. } /* mi_write_keypage */
  93.  
  94.  
  95.     /* Remove page from disk */
  96.  
  97. int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
  98. {
  99.   my_off_t old_link;
  100.   char buff[8];
  101.   DBUG_ENTER("_mi_dispose");
  102.   DBUG_PRINT("enter",("pos: %ld", (long) pos));
  103.  
  104.   old_link=info->s->state.key_del[keyinfo->block_size];
  105.   info->s->state.key_del[keyinfo->block_size]=pos;
  106.   mi_sizestore(buff,old_link);
  107.   info->s->state.changed|= STATE_NOT_SORTED_PAGES;
  108.   DBUG_RETURN(key_cache_write(info->s->kfile,pos,buff,
  109.                   sizeof(buff),
  110.                   (uint) keyinfo->block_length,
  111.                   (int) (info->lock_type != F_UNLCK)));
  112. } /* _mi_dispose */
  113.  
  114.  
  115.     /* Make new page on disk */
  116.  
  117. my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
  118. {
  119.   my_off_t pos;
  120.   char buff[8];
  121.   DBUG_ENTER("_mi_new");
  122.  
  123.   if ((pos=info->s->state.key_del[keyinfo->block_size]) == HA_OFFSET_ERROR)
  124.   {
  125.     if (info->state->key_file_length >=
  126.     info->s->base.max_key_file_length - keyinfo->block_length)
  127.     {
  128.       my_errno=HA_ERR_INDEX_FILE_FULL;
  129.       DBUG_RETURN(HA_OFFSET_ERROR);
  130.     }
  131.     pos=info->state->key_file_length;
  132.     info->state->key_file_length+= keyinfo->block_length;
  133.   }
  134.   else
  135.   {
  136.     if (!key_cache_read(info->s->kfile,pos,
  137.             buff,
  138.             (uint) sizeof(buff),
  139.             (uint) keyinfo->block_length,0))
  140.       pos= HA_OFFSET_ERROR;
  141.     else
  142.       info->s->state.key_del[keyinfo->block_size]=mi_sizekorr(buff);
  143.   }
  144.   info->s->state.changed|= STATE_NOT_SORTED_PAGES;
  145.   DBUG_PRINT("exit",("Pos: %ld",(long) pos));
  146.   DBUG_RETURN(pos);
  147. } /* _mi_new */
  148.