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