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