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