ADMB Documentation  11.1.2274
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f13.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f13.cpp 2270 2014-08-29 00:15: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 void fixed_smartlist::reset(void)
00023 {
00024   end_saved=0;
00025   bptr=buffer;
00026   eof_flag=0;
00027   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00028   endof_file_ptr=lseek(fp,0L,SEEK_SET);
00029   written_flag=0;
00030 }
00031 
00036 fixed_smartlist::fixed_smartlist(void)
00037 {
00038   nentries=0;
00039   bufsize=0;
00040   buffer=0;
00041   true_buffer=0;
00042   buffend=0;
00043   bptr=0;
00044   fp=-1;
00045 }
00046 
00051 fixed_smartlist::fixed_smartlist(unsigned int _bufsize,
00052   const adstring& _filename)
00053 {
00054   allocate(_bufsize,_filename);
00055 }
00056 void fixed_smartlist::allocate(unsigned int _bufsize,const adstring& _filename)
00057 {
00058   nentries=_bufsize/sizeof(fixed_list_entry);
00059   end_saved=0;
00060   eof_flag=0;
00061   noreadflag=0;
00062   written_flag=0;
00063   direction=0;
00064   bufsize=_bufsize;
00065   filename=_filename;
00066   AD_ALLOCATE(true_buffer,fixed_list_entry,nentries+2,df1b2_gradlist)
00067   doubleptr=(double*)true_buffer;
00068   true_buffend=true_buffer+nentries+1;
00069   buffer=true_buffer+1;
00070   buffend=true_buffend-2;
00071   bptr=buffer;
00072   true_buffer->numbytes=5678;
00073   //int(true_buffer->pf)=1234;
00074   true_buffend->numbytes=9999;
00075   //int(true_buffend->pf)=6666;
00076   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00077                    O_BINARY, S_IREAD | S_IWRITE);
00078   if (fp == -1)
00079   {
00080     cerr << "Error trying to open file " << filename
00081          << " in class fixed_smartlist " << endl;
00082     ad_exit(1);
00083   }
00084 
00085   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00086 }
00087 
00092 void fixed_smartlist::write(int n)
00093 {
00094   int nw=::write(fp,buffer,n);
00095   if (nw<n)
00096   {
00097     cerr << "Error writing to file " << filename << endl;
00098     ad_exit(1);
00099   }
00100 }
00101 
00106 void fixed_smartlist::rewind(void)
00107 {
00108   bptr=buffer;
00109   unsigned int nbytes=0;
00110   eof_flag=0;
00111   if (written_flag)
00112   {
00113     lseek(fp,0L,SEEK_SET);
00114     // get the record size
00115     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00116     assert(ret != -1);
00117     if (nbytes>bufsize)
00118     {
00119       cerr << "Error -- record size in file seems to be larger than"
00120        " the buffer it was created from " << endl
00121         << " buffer size is " << bufsize << " record size is supposedly "
00122         << nbytes << endl;
00123       ad_exit(1);
00124     }
00125     // now read the record into the buffer
00126     ret = ::read(fp,buffer,nbytes);
00127     assert(ret != -1);
00128     //cout << "Number of bytes read " << nr << endl;
00129     // skip over file postion entry in file
00130     // so we are ready to read second record
00131     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00132   }
00133 }
00134 
00139 void fixed_smartlist::initialize(void)
00140 {
00141   end_saved=0;
00142   eof_flag=0;
00143   bptr=buffer;
00144   //int nbytes=0;
00145   written_flag=0;
00146   lseek(fp,0L,SEEK_SET);
00147   set_forward();
00148 }
00149 
00154 void fixed_smartlist::check_buffer_size(int nsize)
00155 {
00156   if ( bptr+nsize-1 > buffend)
00157   {
00158     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00159     {
00160       read_buffer();
00161     }
00162     else
00163     {
00164       if ((unsigned int)nsize>bufsize)
00165       {
00166          cout << "Need to increase buffsize in list" << endl;
00167          exit(1);
00168       }
00169       write_buffer();
00170     }
00171   }
00172 }
00173 
00178 void fixed_smartlist::restore_end(void)
00179 {
00180   if (written_flag)
00181   {
00182     if (end_saved)
00183     {
00184       /*off_t ipos=*/lseek(fp,0L,SEEK_END);
00185       lseek(fp,endof_file_ptr,SEEK_SET);
00186       read_buffer();
00187       set_recend();
00188     }
00189   }
00190 }
00191 
00196 void fixed_smartlist::save_end(void)
00197 {
00198   if (written_flag)
00199   {
00200     if (!end_saved)
00201     {
00202       write_buffer_one_less();
00203       end_saved=1;
00204     }
00205   }
00206 }
00207 
00212 void fixed_smartlist::write_buffer_one_less(void)
00213 {
00214   int nbytes=adptr_diff(bptr,buffer);
00215   if (nbytes)
00216   {
00217     written_flag=1;
00218     // get the current file position
00219     off_t pos=lseek(fp,0L,SEEK_CUR);
00220 
00221     // write the size of the next record into the file
00222     //cout << nbytes << endl;
00223     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00224     assert(ret != -1);
00225 
00226     // write the record into the file
00227     int nw=::write(fp,buffer,nbytes);
00228     //cout << "Number of bytes written 1less " << nw
00229      //    << " bptr value =  " << bptr << endl;
00230     //for (int ii=0;ii<=25;ii++)
00231     //  cout << int (*(buffer+ii)) << " ";
00232     //cout << endl;
00233     if (nw<nbytes)
00234     {
00235       cerr << "Error writing to file " << filename << endl;
00236       ad_exit(1);
00237     }
00238     // reset the pointer to the beginning of the buffer
00239     bptr=buffer;
00240 
00241     // now write the previous file position into the file so we can back up
00242     // when we want to.
00243     ret = ::write(fp,&pos,sizeof(off_t));
00244     assert(ret != -1);
00245 
00246     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00247     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00248   }
00249 }
00250 
00255 void fixed_smartlist::write_buffer(void)
00256 {
00257   unsigned int nbytes=adptr_diff(bptr+1,buffer);
00258   if (nbytes>bufsize)
00259   {
00260     cerr << "n bytes > bufsize in "
00261       "fixed_smartlist::write_buffer(void) this can't happen!" << endl;
00262   }
00263   if (nbytes)
00264   {
00265     written_flag=1;
00266     // get the current file position
00267     off_t pos=lseek(fp,0L,SEEK_CUR);
00268 
00269     // write the size of the next record into the file
00270     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00271     assert(ret != -1);
00272 
00273     // write the record into the file
00274     unsigned int nw=::write(fp,buffer,nbytes);
00275     //cout << "Number of bytes written " << nw
00276      //    << " bptr value =  " << bptr << endl;
00277     //for (int ii=0;ii<=25;ii++)
00278     //  cout << int (*(buffer+ii)) << " ";
00279     //cout << endl;
00280     if (nw<nbytes)
00281     {
00282       cerr << "Error writing to file " << filename << endl;
00283       ad_exit(1);
00284     }
00285     // reset the pointer to the beginning of the buffer
00286     bptr=buffer;
00287 
00288     // now write the previous file position into the file so we can back up
00289     // when we want to.
00290     ret = ::write(fp,&pos,sizeof(off_t));
00291     assert(ret != -1);
00292 
00293     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00294     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00295   }
00296 }
00297 
00302 void fixed_smartlist::read_buffer(void)
00303 {
00304   off_t pos;
00305   unsigned int nbytes;
00306   if (!written_flag)
00307   {
00308     if (direction ==-1)
00309       eof_flag=-1;
00310     else
00311       eof_flag=1;
00312   }
00313   else
00314   {
00315     if (direction ==-1) // we are going backwards
00316     {
00317       off_t ipos=lseek(fp,0L,SEEK_CUR);
00318       if (ipos ==0)
00319       {
00320         eof_flag=-1;
00321         return;
00322       }
00323       // offset of the begining of the record is at the end
00324       // of the record
00325       lseek(fp,long(-sizeof(off_t)),SEEK_CUR);
00326       ssize_t ret = read(fp,&pos,sizeof(off_t));
00327       assert(ret != -1);
00328       // back up to the beginning of the record (plus record size)
00329       lseek(fp,pos,SEEK_SET);
00330       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00331     }
00332     // get the record size
00333     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00334     assert(ret != -1);
00335     if (nbytes>bufsize)
00336     {
00337       cerr << "Error -- record size in file seems to be larger than"
00338        " the buffer it was created from " << endl
00339         << " buffer size is " << bufsize << " record size is supposedly "
00340         << nbytes << endl;
00341       ad_exit(1);
00342     }
00343     // now read the record into the buffer
00344     ssize_t nr=::read(fp,buffer,nbytes);
00345     assert(nr != -1);
00346     if (nr != nbytes)
00347     {
00348       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00349       exit(1);
00350     }
00351 
00352     //cout << "Number of bytes read " << nr << endl;
00353    /*
00354     cout << "buffer value = ";
00355     for (int ii=0;ii<=2;ii++)
00356       cout << *(buffer+ii) << " ";
00357     cout << endl;
00358     */
00359 
00360     // reset the pointer to the beginning of the buffer
00361     bptr=buffer;
00362     int ns=nbytes/sizeof(fixed_list_entry);
00363     recend=bptr+ns-1;
00364     //cout << "Number of bytes read " << nr
00365      //    << "  recend value = " << recend << endl;
00366     if (direction ==-1) // we are going backwards
00367     {
00368       // backup the file pointer again
00369       lseek(fp,pos,SEEK_SET);
00370       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00371     }
00372     else  // we are going forward
00373     {
00374       // skip over file postion entry in file
00375       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00376     }
00377   }
00378 }
00379 
00384 void memcpy(const fixed_smartlist & _list,void * p,int nsize)
00385 {
00386   ADUNCONST(fixed_smartlist,list)
00387   if ( list.bptr+nsize-1 > list.buffend)
00388   {
00389     cerr << " Trying to write outside list buffer" << endl;
00390     exit(1);
00391   }
00392   memcpy(list.bptr,p,nsize);
00393   list.bptr+=nsize;
00394 }
00395 
00400 void memcpy(void * p,const fixed_smartlist & _list,int nsize)
00401 {
00402   ADUNCONST(fixed_smartlist,list)
00403   if ( list.bptr+nsize-1 > list.buffend)
00404   {
00405     cerr << " Trying to write outside list buffer" << endl;
00406     exit(1);
00407   }
00408   memcpy(p,list.bptr,nsize);
00409   list.bptr+=nsize;
00410 }
00411 
00412 void fixed_smartlist::operator -= (int n)
00413 {
00414   if (bptr-n<buffer)
00415   {
00416     if (bptr != buffer)
00417     {
00418       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00419       exit(1);
00420     }
00421     else
00422     {
00423       // get previous record from the file
00424       read_buffer();
00425       bptr=recend-n+1;
00426     }
00427   }
00428   else
00429   {
00430     bptr-=n;
00431   }
00432 }
00433 void fixed_smartlist::operator -- (void)
00434 {
00435   if (bptr-1<buffer)
00436   {
00437     if (bptr != buffer)
00438     {
00439       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00440       exit(1);
00441     }
00442     else
00443     {
00444       // get previous record from the file
00445       read_buffer();
00446       //bptr=recend+1;
00447       bptr=recend;
00448     }
00449   }
00450   else
00451   {
00452     bptr--;
00453   }
00454 }
00455 
00456 void fixed_smartlist::operator += (int nsize)
00457 {
00458   if ( bptr+nsize-1 > buffend)
00459   {
00460     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00461     {
00462       read_buffer();
00463     }
00464     else
00465     {
00466       if ((unsigned int)nsize>bufsize)
00467       {
00468         cout << "Need to increase buffsize in list" << endl;
00469         exit(1);
00470       }
00471       write_buffer();
00472     }
00473   }
00474   else
00475   {
00476     bptr+=nsize;
00477   }
00478 }
00479 
00484 void fixed_smartlist::operator ++ (void)
00485 {
00486   if ( bptr==buffend)
00487   {
00488     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00489     {
00490       read_buffer();
00491     }
00492     else
00493     {
00494       write_buffer();
00495     }
00496   }
00497   else
00498   {
00499     bptr++;
00500   }
00501 }
00502 
00507 void fixed_smartlist::read_file(void)
00508 {
00509   //rewind the file
00510   off_t pos=lseek(fp,0L,SEEK_SET);
00511   int nbytes=0;
00512   char buffer[50000];
00513   int offset=0;
00514   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00515   cout << b << endl;
00516   int nw=0;
00517   do
00518   {
00519     nw=::read(fp,&nbytes,sizeof(int));
00520     nw=::read(fp,buffer+offset,nbytes);
00521     offset+=nbytes;
00522     ::read(fp,&pos,sizeof(off_t));
00523   }
00524   while(nw);
00525 }