ADMB Documentation  11.1.2496
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f14.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f14.cpp 2491 2014-10-22 08:43:24Z 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,long(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(int 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 ((unsigned int)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,-((long)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       // skip over file postion entry in file
00367       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00368     }
00369   }
00370 }
00371 
00376 void memcpy(const fixed_smartlist2 & _list,void * p,int nsize)
00377 {
00378   ADUNCONST(fixed_smartlist2,list)
00379   if ( list.bptr+nsize-1 > list.buffend)
00380   {
00381     cerr << " Trying to write outside list buffer" << endl;
00382     exit(1);
00383   }
00384   memcpy(list.bptr,p,nsize);
00385   list.bptr+=nsize;
00386 }
00387 
00392 void memcpy(void * p,const fixed_smartlist2 & _list,int nsize)
00393 {
00394   ADUNCONST(fixed_smartlist2,list)
00395   if ( list.bptr+nsize-1 > list.buffend)
00396   {
00397     cerr << " Trying to write outside list buffer" << endl;
00398     exit(1);
00399   }
00400   memcpy(p,list.bptr,nsize);
00401   list.bptr+=nsize;
00402 }
00403 
00408 void fixed_smartlist2::operator -= (int n)
00409 {
00410   if (bptr-n<buffer)
00411   {
00412     if (bptr != buffer)
00413     {
00414       cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00415       exit(1);
00416     }
00417     else
00418     {
00419       // get previous record from the file
00420       read_buffer();
00421       bptr=recend-n+1;
00422     }
00423   }
00424   else
00425   {
00426     bptr-=n;
00427   }
00428 }
00429 
00434 void fixed_smartlist2::operator -- (void)
00435 {
00436   if (bptr-1<buffer)
00437   {
00438     if (bptr != buffer)
00439     {
00440       cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00441       exit(1);
00442     }
00443     else
00444     {
00445       // get previous record from the file
00446       read_buffer();
00447       //bptr=recend+1;
00448       bptr=recend;
00449     }
00450   }
00451   else
00452   {
00453     bptr--;
00454   }
00455 }
00456 
00461 void fixed_smartlist2::operator += (int nsize)
00462 {
00463   if ( bptr+nsize-1 > buffend)
00464   {
00465     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00466     {
00467       read_buffer();
00468     }
00469     else
00470     {
00471       if ((unsigned int)nsize>bufsize)
00472       {
00473          cout << "Need to increase buffsize in list" << endl;
00474          exit(1);
00475       }
00476       write_buffer();
00477     }
00478   }
00479   else
00480   {
00481     bptr+=nsize;
00482   }
00483 }
00484 
00489 void fixed_smartlist2::operator ++ (void)
00490 {
00491   if ( bptr==buffend)
00492   {
00493     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00494     {
00495       read_buffer();
00496     }
00497     else
00498     {
00499       write_buffer();
00500     }
00501   }
00502   else
00503   {
00504     bptr++;
00505   }
00506 }
00507 
00511 void fixed_smartlist2::read_file(void)
00512 {
00513   //rewind the file
00514   off_t pos=lseek(fp,0L,SEEK_SET);
00515   int nbytes=0;
00516   char buffer[50000];
00517   int offset=0;
00518   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00519   cout << b << endl;
00520   size_t nw = 0;
00521   do
00522   {
00523     nw = ::read(fp,&nbytes,sizeof(int));
00524     nw = ::read(fp,buffer+offset,nbytes);
00525     offset+=nbytes;
00526     nw = ::read(fp,&pos,sizeof(off_t));
00527   }
00528   while(nw);
00529 }