ADMB Documentation  11.1.2438
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f14.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f14.cpp 2326 2014-09-11 23:19:22Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <df1b2fun.h>
00012 #include <cassert>
00013 
00014 #ifdef _MSC_VER
00015 typedef int ssize_t;
00016 #endif
00017 
00022 fixed_smartlist2::fixed_smartlist2(void)
00023 {
00024   nentries=0;
00025   end_saved=0;
00026   eof_flag=0;
00027   noreadflag=0;
00028   written_flag=0;
00029   direction=0;
00030   bufsize=0;
00031   true_buffer=0;
00032   true_buffend=0;
00033   buffer=0;
00034   buffend=0;
00035   bptr=buffer;
00036 }
00037 
00042 fixed_smartlist2::fixed_smartlist2(unsigned int _bufsize,
00043   const adstring& _filename)
00044 {
00045   allocate(_bufsize,_filename);
00046 }
00047 
00052 void fixed_smartlist2::allocate(unsigned int _bufsize,
00053   const adstring& _filename)
00054 {
00055   nentries=_bufsize/sizeof(int);
00056   end_saved=0;
00057   eof_flag=0;
00058   noreadflag=0;
00059   written_flag=0;
00060   direction=0;
00061   bufsize=_bufsize;
00062   filename=_filename;
00063   AD_ALLOCATE(true_buffer,int,nentries+2,df1b2_gradlist)
00064   doubleptr=(double*)true_buffer;
00065   true_buffend=true_buffer+nentries+1;
00066   buffer=true_buffer+1;
00067   buffend=true_buffend-1;
00068   bptr=buffer;
00069   *true_buffer=5678;
00070   *true_buffend=9999;
00071   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00072                    O_BINARY, S_IREAD | S_IWRITE);
00073   if (fp == -1)
00074   {
00075     cerr << "Error trying to open file " << filename
00076          << " in class fixed_smartlist2 " << endl;
00077     ad_exit(1);
00078   }
00079 
00080   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00081 }
00082 
00086 void fixed_smartlist2::write(int n)
00087 {
00088   ssize_t nw = ::write(fp, buffer, n);
00089   if (nw < n)
00090   {
00091     cerr << "Error writing to file " << filename << endl;
00092     ad_exit(1);
00093   }
00094 }
00095 
00099 void fixed_smartlist2::rewind(void)
00100 {
00101   bptr=buffer;
00102   eof_flag=0;
00103   if (written_flag)
00104   {
00105     lseek(fp,0L,SEEK_SET);
00106     // get the record size
00107     int nbytes=0;
00108     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00109     assert(ret != -1);
00110     assert(nbytes >= 0);
00111     if ((unsigned int)nbytes > bufsize)
00112     {
00113       cerr << "Error -- record size in file seems to be larger than"
00114        " the buffer it was created from " << endl
00115         << " buffer size is " << bufsize << " record size is supposedly "
00116         << nbytes << endl;
00117       ad_exit(1);
00118     }
00119     // now read the record into the buffer
00120     ret = ::read(fp,buffer,nbytes);
00121     assert(ret != -1);
00122     //cout << "Number of bytes read " << nr << endl;
00123     // skip over file postion entry in file
00124     // so we are ready to read second record
00125     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00126   }
00127 }
00128 
00133 void fixed_smartlist2::initialize(void)
00134 {
00135   end_saved=0;
00136   eof_flag=0;
00137   bptr=buffer;
00138   //int nbytes=0;
00139   written_flag=0;
00140   lseek(fp,0L,SEEK_SET);
00141   set_forward();
00142 }
00143 
00148 void fixed_smartlist2::check_buffer_size(int nsize)
00149 {
00150   if ( bptr+nsize-1 > buffend)
00151   {
00152     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00153     {
00154       read_buffer();
00155     }
00156     else
00157     {
00158       if ((unsigned int)nsize>bufsize)
00159       {
00160          cout << "Need to increase buffsize in list" << endl;
00161          exit(1);
00162       }
00163       write_buffer();
00164     }
00165   }
00166 }
00167 
00172 void fixed_smartlist2::restore_end(void)
00173 {
00174   if (written_flag)
00175   {
00176     if (end_saved)
00177     {
00178       /*off_t ipos=*/lseek(fp,endof_file_ptr,SEEK_SET);
00179       read_buffer();
00180       set_recend();
00181     }
00182   }
00183 }
00184 
00189 void fixed_smartlist2::save_end(void)
00190 {
00191   if (written_flag)
00192   {
00193     if (!end_saved)
00194     {
00195       write_buffer_one_less();
00196       end_saved=1;
00197     }
00198   }
00199 }
00200 
00205 void fixed_smartlist2::write_buffer_one_less(void)
00206 {
00207   int nbytes=adptr_diff(bptr,buffer);
00208   if (nbytes)
00209   {
00210     written_flag=1;
00211     // get the current file position
00212     off_t pos=lseek(fp,0L,SEEK_CUR);
00213 
00214     // write the size of the next record into the file
00215     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00216     assert(ret != -1);
00217 
00218     // write the record into the file
00219     ssize_t nw = ::write(fp,buffer,nbytes);
00220     //cout << "Number of bytes written " << nw
00221      //    << " bptr value =  " << bptr << endl;
00222     //for (int ii=0;ii<=25;ii++)
00223     //  cout << int (*(buffer+ii)) << " ";
00224     //cout << endl;
00225     if (nw<nbytes)
00226     {
00227       cerr << "Error writing to file " << filename << endl;
00228       ad_exit(1);
00229     }
00230     // reset the pointer to the beginning of the buffer
00231     bptr=buffer;
00232 
00233     // now write the previous file position into the file so we can back up
00234     // when we want to.
00235     ret = ::write(fp,&pos,sizeof(off_t));
00236     assert(ret != -1);
00237 
00238     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00239 
00240     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00241   }
00242 }
00243 
00248 void fixed_smartlist2::write_buffer(void)
00249 {
00250   int nbytes=adptr_diff(bptr+1,buffer);
00251   if (nbytes)
00252   {
00253     written_flag=1;
00254     // get the current file position
00255     off_t pos=lseek(fp,0L,SEEK_CUR);
00256 
00257     // write the size of the next record into the file
00258     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00259     assert(ret != -1);
00260 
00261     // write the record into the file
00262     ret = ::write(fp,buffer,nbytes);
00263     assert(ret != -1);
00264     //cout << "Number of bytes written " << ret
00265      //    << " bptr value =  " << bptr << endl;
00266     //for (int ii=0;ii<=25;ii++)
00267     //  cout << int (*(buffer+ii)) << " ";
00268     //cout << endl;
00269     if (ret < nbytes)
00270     {
00271       cerr << "Error writing to file " << filename << endl;
00272       ad_exit(1);
00273     }
00274     // reset the pointer to the beginning of the buffer
00275     bptr=buffer;
00276 
00277     // now write the previous file position into the file so we can back up
00278     // when we want to.
00279     ret = ::write(fp,&pos,sizeof(off_t));
00280     assert(ret != -1);
00281 
00282     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00283 
00284     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00285   }
00286 }
00287 
00292 void fixed_smartlist2::read_buffer(void)
00293 {
00294   if (!written_flag)
00295   {
00296     if (direction ==-1)
00297       eof_flag=-1;
00298     else
00299       eof_flag=1;
00300   }
00301   else
00302   {
00303     off_t pos = 0;
00304     if (direction ==-1) // we are going backwards
00305     {
00306       off_t ipos=lseek(fp,0L,SEEK_CUR);
00307       if (ipos ==0)
00308       {
00309         eof_flag=-1;
00310         return;
00311       }
00312       // offset of the begining of the record is at the end
00313       // of the record
00314       lseek(fp,-((long)sizeof(off_t)),SEEK_CUR);
00315       ssize_t ret = read(fp,&pos,sizeof(off_t));
00316       assert(ret != -1);
00317       // back up to the beginning of the record (plus record size)
00318       lseek(fp,pos,SEEK_SET);
00319       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00320     }
00321     // get the record size
00322     int nbytes = 0;
00323     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00324     assert(ret != -1);
00325     assert(nbytes >= 0);
00326     if ((unsigned int)nbytes > bufsize)
00327     {
00328       cerr << "Error -- record size in file seems to be larger than"
00329        " the buffer it was created from " << endl
00330         << " buffer size is " << bufsize << " record size is supposedly "
00331         << nbytes << endl;
00332       ad_exit(1);
00333     }
00334     // now read the record into the buffer
00335     ssize_t nr=::read(fp,buffer,nbytes);
00336     assert(nr != -1);
00337     if (nr != nbytes)
00338     {
00339       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00340       exit(1);
00341     }
00342 
00343    /*
00344     cout << "Number of bytes read " << nr << endl;
00345     cout << "buffer value = ";
00346     for (int ii=0;ii<=25;ii++)
00347       cout << int (*(buffer+ii)) << " ";
00348     cout << endl;
00349     */
00350     // reset the pointer to the beginning of the buffer
00351     bptr=buffer;
00352     int ns=nbytes/(int)sizeof(int);
00353     recend=bptr+ns-1;
00354     //cout << "Number of bytes read " << nr
00355      //    << "  recend value = " << recend << endl;
00356     if (direction ==-1) // we are going backwards
00357     {
00358       // backup the file pointer again
00359       lseek(fp,pos,SEEK_SET);
00360       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00361     }
00362     else  // we are going forward
00363     {
00364       // skip over file postion entry in file
00365       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00366     }
00367   }
00368 }
00369 
00374 void memcpy(const fixed_smartlist2 & _list,void * p,int nsize)
00375 {
00376   ADUNCONST(fixed_smartlist2,list)
00377   if ( list.bptr+nsize-1 > list.buffend)
00378   {
00379     cerr << " Trying to write outside list buffer" << endl;
00380     exit(1);
00381   }
00382   memcpy(list.bptr,p,nsize);
00383   list.bptr+=nsize;
00384 }
00385 
00390 void memcpy(void * p,const fixed_smartlist2 & _list,int nsize)
00391 {
00392   ADUNCONST(fixed_smartlist2,list)
00393   if ( list.bptr+nsize-1 > list.buffend)
00394   {
00395     cerr << " Trying to write outside list buffer" << endl;
00396     exit(1);
00397   }
00398   memcpy(p,list.bptr,nsize);
00399   list.bptr+=nsize;
00400 }
00401 
00406 void fixed_smartlist2::operator -= (int n)
00407 {
00408   if (bptr-n<buffer)
00409   {
00410     if (bptr != buffer)
00411     {
00412       cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00413       exit(1);
00414     }
00415     else
00416     {
00417       // get previous record from the file
00418       read_buffer();
00419       bptr=recend-n+1;
00420     }
00421   }
00422   else
00423   {
00424     bptr-=n;
00425   }
00426 }
00427 
00432 void fixed_smartlist2::operator -- (void)
00433 {
00434   if (bptr-1<buffer)
00435   {
00436     if (bptr != buffer)
00437     {
00438       cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00439       exit(1);
00440     }
00441     else
00442     {
00443       // get previous record from the file
00444       read_buffer();
00445       //bptr=recend+1;
00446       bptr=recend;
00447     }
00448   }
00449   else
00450   {
00451     bptr--;
00452   }
00453 }
00454 
00459 void fixed_smartlist2::operator += (int nsize)
00460 {
00461   if ( bptr+nsize-1 > buffend)
00462   {
00463     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00464     {
00465       read_buffer();
00466     }
00467     else
00468     {
00469       if ((unsigned int)nsize>bufsize)
00470       {
00471          cout << "Need to increase buffsize in list" << endl;
00472          exit(1);
00473       }
00474       write_buffer();
00475     }
00476   }
00477   else
00478   {
00479     bptr+=nsize;
00480   }
00481 }
00482 
00487 void fixed_smartlist2::operator ++ (void)
00488 {
00489   if ( bptr==buffend)
00490   {
00491     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00492     {
00493       read_buffer();
00494     }
00495     else
00496     {
00497       write_buffer();
00498     }
00499   }
00500   else
00501   {
00502     bptr++;
00503   }
00504 }
00505 
00509 void fixed_smartlist2::read_file(void)
00510 {
00511   //rewind the file
00512   off_t pos=lseek(fp,0L,SEEK_SET);
00513   int nbytes=0;
00514   char buffer[50000];
00515   int offset=0;
00516   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00517   cout << b << endl;
00518   size_t nw = 0;
00519   do
00520   {
00521     nw = ::read(fp,&nbytes,sizeof(int));
00522     nw = ::read(fp,buffer+offset,nbytes);
00523     offset+=nbytes;
00524     nw = ::read(fp,&pos,sizeof(off_t));
00525   }
00526   while(nw);
00527 }