Drizzled Public API Documentation

mi_preload.cc
00001 /* Copyright (C) 2003, 2005 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 /*
00017   Preload indexes into key cache
00018 */
00019 
00020 #include "myisam_priv.h"
00021 #include <stdlib.h>
00022 #include <drizzled/util/test.h>
00023 
00024 using namespace drizzled;
00025 
00026 /*
00027   Preload pages of the index file for a table into the key cache
00028 
00029   SYNOPSIS
00030     mi_preload()
00031       info          open table
00032       map           map of indexes to preload into key cache
00033       ignore_leaves only non-leaves pages are to be preloaded
00034 
00035   RETURN VALUE
00036     0 if a success. error code - otherwise.
00037 
00038   NOTES.
00039     At present pages for all indexes are preloaded.
00040     In future only pages for indexes specified in the key_map parameter
00041     of the table will be preloaded.
00042 */
00043 
00044 int mi_preload(MI_INFO *info, uint64_t key_map, bool ignore_leaves)
00045 {
00046   uint32_t i;
00047   uint32_t length, block_length= 0;
00048   unsigned char *buff= NULL;
00049   MYISAM_SHARE* share= info->s;
00050   uint32_t keys= share->state.header.keys;
00051   MI_KEYDEF *keyinfo= share->keyinfo;
00052   internal::my_off_t key_file_length= share->state.state.key_file_length;
00053   internal::my_off_t pos= share->base.keystart;
00054 
00055   if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos)
00056     return(0);
00057 
00058   block_length= keyinfo[0].block_length;
00059 
00060   if (ignore_leaves)
00061   {
00062     /* Check whether all indexes use the same block size */
00063     for (i= 1 ; i < keys ; i++)
00064     {
00065       if (keyinfo[i].block_length != block_length)
00066         return(errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
00067     }
00068   }
00069   else
00070     block_length= share->getKeyCache()->key_cache_block_size;
00071 
00072   length= info->preload_buff_size/block_length * block_length;
00073   set_if_bigger(length, block_length);
00074 
00075   if (!(buff= (unsigned char *) malloc(length)))
00076     return(errno= HA_ERR_OUT_OF_MEM);
00077 
00078   if (flush_key_blocks(share->getKeyCache(), share->kfile, FLUSH_RELEASE))
00079     goto err;
00080 
00081   do
00082   {
00083     /* Read the next block of index file into the preload buffer */
00084     if ((internal::my_off_t) length > (key_file_length-pos))
00085       length= (uint32_t) (key_file_length-pos);
00086     if (my_pread(share->kfile, (unsigned char*) buff, length, pos, MYF(MY_FAE|MY_FNABP)))
00087       goto err;
00088 
00089     if (ignore_leaves)
00090     {
00091       unsigned char *end= buff+length;
00092       do
00093       {
00094         if (mi_test_if_nod(buff))
00095         {
00096           if (key_cache_insert(share->getKeyCache(),
00097                                share->kfile, pos, DFLT_INIT_HITS,
00098                               (unsigned char*) buff, block_length))
00099       goto err;
00100   }
00101         pos+= block_length;
00102       }
00103       while ((buff+= block_length) != end);
00104       buff= end-length;
00105     }
00106     else
00107     {
00108       if (key_cache_insert(share->getKeyCache(),
00109                            share->kfile, pos, DFLT_INIT_HITS,
00110                            (unsigned char*) buff, length))
00111   goto err;
00112       pos+= length;
00113     }
00114   }
00115   while (pos != key_file_length);
00116 
00117   free((char*) buff);
00118   return(0);
00119 
00120 err:
00121   free((char*) buff);
00122   return(errno= errno);
00123 }
00124