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

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. /* Extra functions we want to do with a database */
  17. /* - Set flags for quicker databasehandler */
  18. /* - Set databasehandler to normal */
  19. /* - Reset recordpointers as after open database */
  20. #include "isamdef.h"
  21. #ifdef HAVE_MMAP
  22. #include <sys/mman.h>
  23. #endif
  24. #ifdef __WIN__
  25. #include <errno.h>
  26. #endif
  27. /* set extra flags for database */
  28. int nisam_extra(N_INFO *info, enum ha_extra_function function)
  29. {
  30.   int error=0;
  31.   DBUG_ENTER("nisam_extra");
  32.   switch (function) {
  33.   case HA_EXTRA_RESET:
  34.     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
  35.     {
  36.       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
  37.       error=end_io_cache(&info->rec_cache);
  38.     }
  39.     info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
  40.   case HA_EXTRA_RESET_STATE:
  41.     info->lastinx= 0; /* Use first index as def */
  42.     info->int_pos=info->lastpos= NI_POS_ERROR;
  43.     info->page_changed=1;
  44. /* Next/prev gives first/last */
  45.     if (info->opt_flag & READ_CACHE_USED)
  46.     {
  47.       VOID(flush_io_cache(&info->rec_cache));
  48.       reinit_io_cache(&info->rec_cache,READ_CACHE,0,
  49.       (pbool) (info->lock_type != F_UNLCK),
  50.       (pbool) test(info->update & HA_STATE_ROW_CHANGED));
  51.     }
  52.     info->update=((info->update & HA_STATE_CHANGED) |
  53.   HA_STATE_NEXT_FOUND | HA_STATE_PREV_FOUND);
  54.     break;
  55.   case HA_EXTRA_CACHE:
  56. #ifndef NO_LOCKING
  57.     if (info->lock_type == F_UNLCK && (info->options & HA_OPTION_PACK_RECORD))
  58.     {
  59.       error=1; /* Not possibly if not locked */
  60.       my_errno=EACCES;
  61.       break;
  62.     }
  63. #endif
  64. #if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
  65.     if ((info->options & HA_OPTION_COMPRESS_RECORD))
  66.     {
  67.       pthread_mutex_lock(&info->s->intern_lock);
  68.       if (_nisam_memmap_file(info))
  69.       {
  70. /* We don't nead MADV_SEQUENTIAL if small file */
  71. madvise(info->s->file_map,info->s->state.data_file_length,
  72. info->s->state.data_file_length <= RECORD_CACHE_SIZE*16 ?
  73. MADV_RANDOM : MADV_SEQUENTIAL);
  74. pthread_mutex_unlock(&info->s->intern_lock);
  75. break;
  76.       }
  77.       pthread_mutex_unlock(&info->s->intern_lock);
  78.     }
  79. #endif
  80.     if (info->opt_flag & WRITE_CACHE_USED)
  81.     {
  82.       info->opt_flag&= ~WRITE_CACHE_USED;
  83.       if ((error=end_io_cache(&info->rec_cache)))
  84. break;
  85.     }
  86.     if (!(info->opt_flag &
  87.   (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
  88.     {
  89.       if (!(init_io_cache(&info->rec_cache,info->dfile,
  90.  (uint) min(info->s->state.data_file_length+1,
  91.     my_default_record_cache_size),
  92.  READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
  93.  MYF(MY_WAIT_IF_FULL))))
  94.       {
  95. info->opt_flag|=READ_CACHE_USED;
  96. info->update&= ~HA_STATE_ROW_CHANGED;
  97.       }
  98.       /* info->rec_cache.end_of_file=info->s->state.data_file_length; */
  99.     }
  100.     break;
  101.   case HA_EXTRA_REINIT_CACHE:
  102.     if (info->opt_flag & READ_CACHE_USED)
  103.     {
  104.       reinit_io_cache(&info->rec_cache,READ_CACHE,info->nextpos,
  105.       (pbool) (info->lock_type != F_UNLCK),
  106.       (pbool) test(info->update & HA_STATE_ROW_CHANGED));
  107.       info->update&= ~HA_STATE_ROW_CHANGED;
  108.       /* info->rec_cache.end_of_file=info->s->state.data_file_length; */
  109.     }
  110.     break;
  111.   case HA_EXTRA_WRITE_CACHE:
  112. #ifndef NO_LOCKING
  113.     if (info->lock_type == F_UNLCK)
  114.     {
  115.       error=1; /* Not possibly if not locked */
  116.       break;
  117.     }
  118. #endif
  119.     if (!(info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED)))
  120.       if (!(init_io_cache(&info->rec_cache,info->dfile,0,
  121.  WRITE_CACHE,info->s->state.data_file_length,
  122.  (pbool) (info->lock_type != F_UNLCK),
  123.  MYF(MY_WAIT_IF_FULL))))
  124.       {
  125. info->opt_flag|=WRITE_CACHE_USED;
  126. info->update&= ~HA_STATE_ROW_CHANGED;
  127.       }
  128.     break;
  129.   case HA_EXTRA_NO_CACHE:
  130.     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
  131.     {
  132.       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
  133.       error=end_io_cache(&info->rec_cache);
  134.     }
  135. #if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
  136.     if (info->opt_flag & MEMMAP_USED)
  137.       madvise(info->s->file_map,info->s->state.data_file_length,MADV_RANDOM);
  138. #endif
  139.     break;
  140.   case HA_EXTRA_FLUSH_CACHE:
  141.     if (info->opt_flag & WRITE_CACHE_USED)
  142.       error=flush_io_cache(&info->rec_cache);
  143.     break;
  144.   case HA_EXTRA_NO_READCHECK:
  145.     info->opt_flag&= ~READ_CHECK_USED; /* No readcheck */
  146.     break;
  147.   case HA_EXTRA_READCHECK:
  148.     info->opt_flag|= READ_CHECK_USED;
  149.     break;
  150.   case HA_EXTRA_KEYREAD: /* Read only keys to record */
  151.   case HA_EXTRA_REMEMBER_POS:
  152.     info->opt_flag |= REMEMBER_OLD_POS;
  153.     bmove((byte*) info->lastkey+info->s->base.max_key_length*2,
  154.   (byte*) info->lastkey,info->s->base.max_key_length);
  155.     info->save_update= info->update;
  156.     info->save_lastinx= info->lastinx;
  157.     info->save_lastpos= info->lastpos;
  158.     if (function == HA_EXTRA_REMEMBER_POS)
  159.       break;
  160.     /* fall through */
  161.   case HA_EXTRA_KEYREAD_CHANGE_POS:
  162.     info->opt_flag |= KEY_READ_USED;
  163.     info->read_record=_nisam_read_key_record;
  164.     break;
  165.   case HA_EXTRA_NO_KEYREAD:
  166.   case HA_EXTRA_RESTORE_POS:
  167.     if (info->opt_flag & REMEMBER_OLD_POS)
  168.     {
  169.       bmove((byte*) info->lastkey,
  170.     (byte*) info->lastkey+info->s->base.max_key_length*2,
  171.     info->s->base.max_key_length);
  172.       info->update= info->save_update | HA_STATE_WRITTEN;
  173.       info->lastinx= info->save_lastinx;
  174.       info->lastpos= info->save_lastpos;
  175.     }
  176.     info->read_record= info->s->read_record;
  177.     info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
  178.     break;
  179.   case HA_EXTRA_NO_USER_CHANGE: /* Database is somehow locked agains changes */
  180.     info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
  181.     break;
  182.   case HA_EXTRA_WAIT_LOCK:
  183.     info->lock_wait=0;
  184.     break;
  185.   case HA_EXTRA_NO_WAIT_LOCK:
  186.     info->lock_wait=MY_DONT_WAIT;
  187.     break;
  188.   case HA_EXTRA_NO_KEYS:
  189. #ifndef NO_LOCKING
  190.     if (info->lock_type == F_UNLCK)
  191.     {
  192.       error=1; /* Not possibly if not lock */
  193.       break;
  194.     }
  195. #endif
  196.     info->s->state.keys=0;
  197.     info->s->state.key_file_length=info->s->base.keystart;
  198.     info->s->changed=1; /* Update on close */
  199.     break;
  200.   case HA_EXTRA_FORCE_REOPEN:
  201.     pthread_mutex_lock(&THR_LOCK_isam);
  202.     info->s->last_version= 0L; /* Impossible version */
  203. #ifdef __WIN__
  204.     /* Close the isam and data files as Win32 can't drop an open table */
  205.     if (flush_key_blocks(info->s->kfile,FLUSH_RELEASE))
  206.       error=my_errno;
  207.     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
  208.     {
  209.       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
  210.       error=end_io_cache(&info->rec_cache);
  211.     }
  212.     if (info->lock_type != F_UNLCK && ! info->was_locked)
  213.     {
  214.       info->was_locked=info->lock_type;
  215.       if (nisam_lock_database(info,F_UNLCK))
  216. error=my_errno;
  217.     }
  218.     if (info->s->kfile >= 0 && my_close(info->s->kfile,MYF(0)))
  219.       error=my_errno;
  220.     {
  221.       LIST *list_element ;
  222.       for (list_element=nisam_open_list ;
  223.    list_element ;
  224.    list_element=list_element->next)
  225.       {
  226. N_INFO *tmpinfo=(N_INFO*) list_element->data;
  227. if (tmpinfo->s == info->s)
  228. {
  229.   if (tmpinfo->dfile >= 0 && my_close(tmpinfo->dfile,MYF(0)))
  230.     error = my_errno;
  231.   tmpinfo->dfile=-1;
  232. }
  233.       }
  234.     }
  235.     info->s->kfile=-1; /* Files aren't open anymore */
  236. #endif
  237.     pthread_mutex_unlock(&THR_LOCK_isam);
  238.     break;
  239.   case HA_EXTRA_FLUSH:
  240. #ifdef __WIN__
  241.     if (info->s->not_flushed)
  242.     {
  243.       info->s->not_flushed=0;
  244.       if (_commit(info->s->kfile))
  245. error=errno;
  246.       if (_commit(info->dfile))
  247. error=errno;
  248.     }
  249.     break;
  250. #endif
  251.   case HA_EXTRA_NORMAL: /* Theese isn't in use */
  252.   case HA_EXTRA_QUICK:
  253.   case HA_EXTRA_KEY_CACHE:
  254.   case HA_EXTRA_NO_KEY_CACHE:
  255.   default:
  256.     break;
  257.   }
  258.   nisam_log_command(LOG_EXTRA,info,(byte*) &function,sizeof(function),error);
  259.   DBUG_RETURN(error);
  260. } /* nisam_extra */