Drizzled Public API Documentation

mi_statrec.cc
00001 /* Copyright (C) 2000-2002, 2004-2006 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   /* Functions to handle fixed-length-records */
00017 
00018 #include "myisam_priv.h"
00019 
00020 using namespace drizzled;
00021 
00022 int _mi_write_static_record(MI_INFO *info, const unsigned char *record)
00023 {
00024   unsigned char temp[8];        /* max pointer length */
00025   if (info->s->state.dellink != HA_OFFSET_ERROR &&
00026       !info->append_insert_at_end)
00027   {
00028     internal::my_off_t filepos=info->s->state.dellink;
00029     info->rec_cache.seek_not_done=1;    /* We have done a seek */
00030     if (info->s->file_read(info, &temp[0],info->s->base.rec_reflength,
00031     info->s->state.dellink+1,
00032      MYF(MY_NABP)))
00033       goto err;
00034     info->s->state.dellink= _mi_rec_pos(info->s,temp);
00035     info->state->del--;
00036     info->state->empty-=info->s->base.pack_reclength;
00037     if (info->s->file_write(info, record, info->s->base.reclength,
00038       filepos,
00039       MYF(MY_NABP)))
00040       goto err;
00041   }
00042   else
00043   {
00044     if (info->state->data_file_length > info->s->base.max_data_file_length-
00045   info->s->base.pack_reclength)
00046     {
00047       errno=HA_ERR_RECORD_FILE_FULL;
00048       return(2);
00049     }
00050     if (info->opt_flag & WRITE_CACHE_USED)
00051     {       /* Cash in use */
00052       if (info->rec_cache.write(record, info->s->base.reclength))
00053   goto err;
00054       if (info->s->base.pack_reclength != info->s->base.reclength)
00055       {
00056   uint32_t length=info->s->base.pack_reclength - info->s->base.reclength;
00057   memset(temp, 0, length);
00058   if (info->rec_cache.write(temp,length))
00059     goto err;
00060       }
00061     }
00062     else
00063     {
00064       info->rec_cache.seek_not_done=1;    /* We have done a seek */
00065       if (info->s->file_write(info, record, info->s->base.reclength,
00066         info->state->data_file_length,
00067         info->s->write_flag))
00068         goto err;
00069       if (info->s->base.pack_reclength != info->s->base.reclength)
00070       {
00071   uint32_t length=info->s->base.pack_reclength - info->s->base.reclength;
00072   memset(temp, 0, length);
00073   if (info->s->file_write(info, temp,length,
00074           info->state->data_file_length+
00075           info->s->base.reclength,
00076           info->s->write_flag))
00077     goto err;
00078       }
00079     }
00080     info->state->data_file_length+=info->s->base.pack_reclength;
00081     info->s->state.split++;
00082   }
00083   return 0;
00084  err:
00085   return 1;
00086 }
00087 
00088 int _mi_update_static_record(MI_INFO *info, internal::my_off_t pos, const unsigned char *record)
00089 {
00090   info->rec_cache.seek_not_done=1;    /* We have done a seek */
00091   return (info->s->file_write(info,
00092                               record, info->s->base.reclength,
00093                               pos,
00094                               MYF(MY_NABP)) != 0);
00095 }
00096 
00097 
00098 int _mi_delete_static_record(MI_INFO *info)
00099 {
00100   unsigned char temp[9];        /* 1+sizeof(uint32) */
00101 
00102   info->state->del++;
00103   info->state->empty+=info->s->base.pack_reclength;
00104   temp[0]= '\0';      /* Mark that record is deleted */
00105   _mi_dpointer(info,temp+1,info->s->state.dellink);
00106   info->s->state.dellink = info->lastpos;
00107   info->rec_cache.seek_not_done=1;
00108   return (info->s->file_write(info,(unsigned char*) temp, 1+info->s->rec_reflength,
00109         info->lastpos, MYF(MY_NABP)) != 0);
00110 }
00111 
00112 
00113 int _mi_cmp_static_record(register MI_INFO *info, register const unsigned char *old)
00114 {
00115   if (info->opt_flag & WRITE_CACHE_USED)
00116   {
00117     if (info->rec_cache.flush())
00118     {
00119       return(-1);
00120     }
00121     info->rec_cache.seek_not_done=1;    /* We have done a seek */
00122   }
00123 
00124   if ((info->opt_flag & READ_CHECK_USED))
00125   {           /* If check isn't disabled  */
00126     info->rec_cache.seek_not_done=1;    /* We have done a seek */
00127     if (info->s->file_read(info, info->rec_buff, info->s->base.reclength,
00128      info->lastpos,
00129      MYF(MY_NABP)))
00130       return(-1);
00131     if (memcmp(info->rec_buff, old,
00132          (uint) info->s->base.reclength))
00133     {
00134       errno=HA_ERR_RECORD_CHANGED;    /* Record have changed */
00135       return(1);
00136     }
00137   }
00138   return(0);
00139 }
00140 
00141 
00142 int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
00143         const unsigned char *record, internal::my_off_t pos)
00144 {
00145   info->rec_cache.seek_not_done=1;    /* We have done a seek */
00146   if (info->s->file_read(info, info->rec_buff, info->s->base.reclength,
00147          pos, MYF(MY_NABP)))
00148     return(-1);
00149   return(mi_unique_comp(def, record, info->rec_buff,
00150            def->null_are_equal));
00151 }
00152 
00153 
00154   /* Read a fixed-length-record */
00155   /* Returns 0 if Ok. */
00156   /*     1 if record is deleted */
00157   /*    MY_FILE_ERROR on read-error or locking-error */
00158 
00159 int _mi_read_static_record(register MI_INFO *info, register internal::my_off_t pos,
00160          register unsigned char *record)
00161 {
00162   if (pos != HA_OFFSET_ERROR)
00163   {
00164     if (info->opt_flag & WRITE_CACHE_USED &&
00165   info->rec_cache.pos_in_file <= pos &&
00166   info->rec_cache.flush())
00167       return(-1);
00168     info->rec_cache.seek_not_done=1;    /* We have done a seek */
00169 
00170     int error= info->s->file_read(info, record, info->s->base.reclength, pos,MYF(MY_NABP)) != 0;
00171     fast_mi_writeinfo(info);
00172     if (! error)
00173     {
00174       if (!*record)
00175       {
00176   errno=HA_ERR_RECORD_DELETED;
00177   return(1);        /* Record is deleted */
00178       }
00179       info->update|= HA_STATE_AKTIV;    /* Record is read */
00180       return(0);
00181     }
00182     return(-1);         /* Error on read */
00183   }
00184   fast_mi_writeinfo(info);      /* No such record */
00185   return(-1);
00186 }
00187 
00188 
00189 
00190 int _mi_read_rnd_static_record(MI_INFO *info, unsigned char *buf,
00191              register internal::my_off_t filepos,
00192              bool skip_deleted_blocks)
00193 {
00194   int locked,error,cache_read;
00195   MYISAM_SHARE *share=info->s;
00196 
00197   cache_read=0;
00198   if (info->opt_flag & WRITE_CACHE_USED &&
00199       (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) &&
00200       info->rec_cache.flush())
00201     return(errno);
00202   if (info->opt_flag & READ_CACHE_USED)
00203   {           /* Cache in use */
00204     if (filepos == info->rec_cache.tell() &&
00205   (skip_deleted_blocks || !filepos))
00206     {
00207       cache_read=1;       /* Read record using cache */
00208     }
00209     else
00210       info->rec_cache.seek_not_done=1;    /* Filepos is changed */
00211   }
00212   locked=0;
00213   if (info->lock_type == F_UNLCK)
00214   {
00215     if (filepos >= info->state->data_file_length)
00216     {           /* Test if new records */
00217       if (_mi_readinfo(info,F_RDLCK,0))
00218   return(errno);
00219       locked=1;
00220     }
00221     else
00222     {           /* We don't nead new info */
00223 #ifndef UNSAFE_LOCKING
00224       locked=1;
00225 #else
00226       info->tmp_lock_type=F_RDLCK;
00227 #endif
00228     }
00229   }
00230   if (filepos >= info->state->data_file_length)
00231   {
00232     fast_mi_writeinfo(info);
00233     return(errno=HA_ERR_END_OF_FILE);
00234   }
00235   info->lastpos= filepos;
00236   info->nextpos= filepos+share->base.pack_reclength;
00237 
00238   if (! cache_read)     /* No cacheing */
00239   {
00240     if ((error=_mi_read_static_record(info,filepos,buf)))
00241     {
00242       if (error > 0)
00243   error=errno=HA_ERR_RECORD_DELETED;
00244       else
00245   error=errno;
00246     }
00247     return(error);
00248   }
00249 
00250   /* Read record with cacheing */
00251   error= info->rec_cache.read(buf, share->base.reclength);
00252   if (info->s->base.pack_reclength != info->s->base.reclength && !error)
00253   {
00254     char tmp[8];        /* Skill fill bytes */
00255     error= info->rec_cache.read(tmp, info->s->base.pack_reclength - info->s->base.reclength);
00256   }
00257   if (locked)
00258     _mi_writeinfo(info,0);    /* Unlock keyfile */
00259   if (!error)
00260   {
00261     if (!buf[0])
00262     {           /* Record is removed */
00263       return(errno=HA_ERR_RECORD_DELETED);
00264     }
00265             /* Found and may be updated */
00266     info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
00267     return(0);
00268   }
00269   /* errno should be set if rec_cache.error == -1 */
00270   if (info->rec_cache.error != -1 || errno == 0)
00271     errno=HA_ERR_WRONG_IN_RECORD;
00272   return(errno);      /* Something wrong (EOF?) */
00273 }