extra.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

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