ADMB Documentation  11.2.2828
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f13.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f13.cpp 2811 2014-12-17 21:48:01Z 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   #ifdef _M_X64
00016   typedef __int64 ssize_t;
00017   #else
00018   typedef int ssize_t;
00019   #endif
00020 #else
00021   #include <unistd.h>
00022 #endif
00023 
00028 void fixed_smartlist::reset(void)
00029 {
00030   end_saved=0;
00031   bptr=buffer;
00032   eof_flag=0;
00033   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00034   endof_file_ptr=lseek(fp,0L,SEEK_SET);
00035   written_flag=0;
00036 }
00037 
00042 fixed_smartlist::fixed_smartlist(void)
00043 {
00044   nentries=0;
00045   bufsize=0;
00046   buffer=0;
00047   true_buffer=0;
00048   buffend=0;
00049   bptr=0;
00050   fp=-1;
00051 }
00052 
00057 fixed_smartlist::fixed_smartlist(const size_t _bufsize,
00058   const adstring& _filename)
00059 {
00060   allocate(_bufsize,_filename);
00061 }
00062 void fixed_smartlist::allocate(const size_t _bufsize,const adstring& _filename)
00063 {
00064   nentries=_bufsize/sizeof(fixed_list_entry);
00065   end_saved=0;
00066   eof_flag=0;
00067   noreadflag=0;
00068   written_flag=0;
00069   direction=0;
00070   bufsize=_bufsize;
00071   filename=_filename;
00072   AD_ALLOCATE(true_buffer,fixed_list_entry,nentries+2,df1b2_gradlist)
00073   doubleptr=(double*)true_buffer;
00074   true_buffend=true_buffer+nentries+1;
00075   buffer=true_buffer+1;
00076   buffend=true_buffend-2;
00077   bptr=buffer;
00078   true_buffer->numbytes=5678;
00079   //int(true_buffer->pf)=1234;
00080   true_buffend->numbytes=9999;
00081   //int(true_buffend->pf)=6666;
00082   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00083                    O_BINARY, S_IREAD | S_IWRITE);
00084   if (fp == -1)
00085   {
00086     cerr << "Error trying to open file " << filename
00087          << " in class fixed_smartlist " << endl;
00088     ad_exit(1);
00089   }
00090 
00091   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00092 }
00093 
00097 void fixed_smartlist::write(const size_t n)
00098 {
00099 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00100   #ifndef OPT_LIB
00101   assert(n <= UINT_MAX);
00102   #endif
00103   ssize_t nw = ::write(fp,buffer,(unsigned int)n);
00104 #else
00105   ssize_t nw = ::write(fp, buffer, n);
00106 #endif
00107   if (nw <= -1 || (size_t)nw != n)
00108   {
00109     cerr << "Error writing to file " << filename << endl;
00110     ad_exit(1);
00111   }
00112 }
00113 
00118 void fixed_smartlist::rewind(void)
00119 {
00120   bptr=buffer;
00121   eof_flag=0;
00122   if (written_flag)
00123   {
00124     lseek(fp,0L,SEEK_SET);
00125     // get the record size
00126     unsigned int nbytes=0;
00127     ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00128     assert(ret != -1);
00129     if (nbytes > bufsize)
00130     {
00131       cerr << "Error -- record size in file seems to be larger than"
00132        " the buffer it was created from " << endl
00133         << " buffer size is " << bufsize << " record size is supposedly "
00134         << nbytes << endl;
00135       ad_exit(1);
00136     }
00137     // now read the record into the buffer
00138     ret = ::read(fp,buffer,nbytes);
00139     assert(ret != -1);
00140     //cout << "Number of bytes read " << nr << endl;
00141     // skip over file postion entry in file
00142     // so we are ready to read second record
00143     lseek(fp,(off_t)sizeof(off_t),SEEK_CUR);
00144   }
00145 }
00146 
00151 void fixed_smartlist::initialize(void)
00152 {
00153   end_saved=0;
00154   eof_flag=0;
00155   bptr=buffer;
00156   //int nbytes=0;
00157   written_flag=0;
00158   lseek(fp,0L,SEEK_SET);
00159   set_forward();
00160 }
00161 
00166 void fixed_smartlist::check_buffer_size(const size_t nsize)
00167 {
00168   if ( bptr+nsize-1 > buffend)
00169   {
00170     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00171     {
00172       read_buffer();
00173     }
00174     else
00175     {
00176       if (nsize>bufsize)
00177       {
00178          cout << "Need to increase buffsize in list" << endl;
00179          exit(1);
00180       }
00181       write_buffer();
00182     }
00183   }
00184 }
00185 
00190 void fixed_smartlist::restore_end(void)
00191 {
00192   if (written_flag)
00193   {
00194     if (end_saved)
00195     {
00196       /*off_t ipos=*/lseek(fp,0L,SEEK_END);
00197       lseek(fp,endof_file_ptr,SEEK_SET);
00198       read_buffer();
00199       set_recend();
00200     }
00201   }
00202 }
00203 
00208 void fixed_smartlist::save_end(void)
00209 {
00210   if (written_flag)
00211   {
00212     if (!end_saved)
00213     {
00214       write_buffer_one_less();
00215       end_saved=1;
00216     }
00217   }
00218 }
00219 
00224 void fixed_smartlist::write_buffer_one_less(void)
00225 {
00226   int _nbytes=adptr_diff(bptr,buffer);
00227   if (_nbytes > 0)
00228   {
00229     const unsigned int nbytes = (unsigned int)_nbytes;
00230 
00231     written_flag=1;
00232     // get the current file position
00233     off_t pos=lseek(fp,0L,SEEK_CUR);
00234 
00235     // write the size of the next record into the file
00236 #if defined(OPT_LIB) && !defined(_MSC_VER)
00237     ::write(fp, &nbytes, sizeof(unsigned int));
00238 #else
00239     ssize_t ret = ::write(fp, &nbytes, sizeof(unsigned int));
00240     assert(ret != -1);
00241 #endif
00242 
00243     // write the record into the file
00244     ssize_t nw = ::write(fp,buffer,nbytes);
00245 #ifndef OPT_LIB
00246     assert(nw != -1);
00247 #endif
00248     if ((size_t)nw < nbytes)
00249     {
00250       cerr << "Error writing to file " << filename << endl;
00251       ad_exit(1);
00252     }
00253     // reset the pointer to the beginning of the buffer
00254     bptr=buffer;
00255 
00256     // now write the previous file position into the file so we can back up
00257     // when we want to.
00258 #if defined(OPT_LIB) && !defined(_MSC_VER)
00259     ::write(fp,&pos,sizeof(off_t));
00260 #else
00261     ret = ::write(fp,&pos,sizeof(off_t));
00262     assert(ret != -1);
00263 #endif
00264 
00265     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00266     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00267   }
00268 }
00269 
00274 void fixed_smartlist::write_buffer(void)
00275 {
00276   int _nbytes=adptr_diff(bptr+1,buffer);
00277   if (_nbytes > 0)
00278   {
00279     unsigned int nbytes = (unsigned int)_nbytes;
00280     if (nbytes > bufsize)
00281     {
00282       cerr << "n bytes > bufsize in "
00283         "fixed_smartlist::write_buffer(void) this can't happen!" << endl;
00284     }
00285     written_flag=1;
00286     // get the current file position
00287     off_t pos=lseek(fp,0L,SEEK_CUR);
00288 
00289     // write the size of the next record into the file
00290     ssize_t ret = ::write(fp,&nbytes,sizeof(unsigned int));
00291     assert(ret != -1);
00292 
00293     // write the record into the file
00294     ssize_t nw=::write(fp,buffer,nbytes);
00295 #ifndef OPT_LIB
00296     assert(nw != -1);
00297 #endif
00298     if ((size_t)nw < nbytes)
00299     {
00300       cerr << "Error writing to file " << filename << endl;
00301       ad_exit(1);
00302     }
00303     // reset the pointer to the beginning of the buffer
00304     bptr=buffer;
00305 
00306     // now write the previous file position into the file so we can back up
00307     // when we want to.
00308     ret = ::write(fp,&pos,sizeof(off_t));
00309     assert(ret != -1);
00310 
00311     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00312     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00313   }
00314 }
00315 
00320 void fixed_smartlist::read_buffer(void)
00321 {
00322   if (!written_flag)
00323   {
00324     if (direction ==-1)
00325       eof_flag=-1;
00326     else
00327       eof_flag=1;
00328   }
00329   else
00330   {
00331     off_t pos = 0;
00332     if (direction ==-1) // we are going backwards
00333     {
00334       off_t ipos=lseek(fp,0L,SEEK_CUR);
00335       if (ipos ==0)
00336       {
00337         eof_flag=-1;
00338         return;
00339       }
00340       // offset of the begining of the record is at the end
00341       // of the record
00342       lseek(fp,-((off_t)sizeof(off_t)),SEEK_CUR);
00343       ssize_t ret = read(fp,&pos,sizeof(off_t));
00344       assert(ret != -1);
00345       // back up to the beginning of the record (plus record size)
00346       lseek(fp,pos,SEEK_SET);
00347       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00348     }
00349     // get the record size
00350     unsigned int nbytes = 0;
00351     ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00352     assert(ret != -1);
00353     if (nbytes > bufsize)
00354     {
00355       cerr << "Error -- record size in file seems to be larger than"
00356        " the buffer it was created from " << endl
00357         << " buffer size is " << bufsize << " record size is supposedly "
00358         << nbytes << endl;
00359       ad_exit(1);
00360     }
00361     // now read the record into the buffer
00362     ssize_t nr = ::read(fp,buffer,nbytes);
00363 #ifndef OPT_LIB
00364     assert(nr != -1);
00365 #endif
00366     if ((size_t)nr != nbytes)
00367     {
00368       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00369       exit(1);
00370     }
00371 
00372     // reset the pointer to the beginning of the buffer
00373     bptr=buffer;
00374     int ns=nbytes/(int)sizeof(fixed_list_entry);
00375     recend=bptr+ns-1;
00376     //cout << "Number of bytes read " << nr
00377      //    << "  recend value = " << recend << endl;
00378     if (direction ==-1) // we are going backwards
00379     {
00380       // backup the file pointer again
00381       lseek(fp,pos,SEEK_SET);
00382       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00383     }
00384     else  // we are going forward
00385     {
00386       // skip over file postion entry in file
00387       lseek(fp,(off_t)sizeof(off_t),SEEK_CUR);
00388     }
00389   }
00390 }
00391 
00396 void memcpy(const fixed_smartlist& _list, void* p, const size_t nsize)
00397 {
00398   ADUNCONST(fixed_smartlist,list)
00399   if (list.bptr+nsize-1 > list.buffend)
00400   {
00401     cerr << " Trying to write outside list buffer" << endl;
00402     exit(1);
00403   }
00404   memcpy(list.bptr,p,nsize);
00405   list.bptr+=nsize;
00406 }
00407 
00412 void memcpy(void* p, const fixed_smartlist& _list, const size_t nsize)
00413 {
00414   ADUNCONST(fixed_smartlist,list)
00415   if (list.bptr+nsize-1 > list.buffend)
00416   {
00417     cerr << " Trying to write outside list buffer" << endl;
00418     exit(1);
00419   }
00420   memcpy(p,list.bptr,nsize);
00421   list.bptr+=nsize;
00422 }
00423 
00424 void fixed_smartlist::operator -= (int n)
00425 {
00426   if (bptr-n<buffer)
00427   {
00428     if (bptr != buffer)
00429     {
00430       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00431       exit(1);
00432     }
00433     else
00434     {
00435       // get previous record from the file
00436       read_buffer();
00437       bptr=recend-n+1;
00438     }
00439   }
00440   else
00441   {
00442     bptr-=n;
00443   }
00444 }
00445 void fixed_smartlist::operator -- (void)
00446 {
00447   if (bptr-1<buffer)
00448   {
00449     if (bptr != buffer)
00450     {
00451       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00452       exit(1);
00453     }
00454     else
00455     {
00456       // get previous record from the file
00457       read_buffer();
00458       //bptr=recend+1;
00459       bptr=recend;
00460     }
00461   }
00462   else
00463   {
00464     bptr--;
00465   }
00466 }
00467 
00468 void fixed_smartlist::operator += (int nsize)
00469 {
00470   if ( bptr+nsize-1 > buffend)
00471   {
00472     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00473     {
00474       read_buffer();
00475     }
00476     else
00477     {
00478       if ((unsigned int)nsize>bufsize)
00479       {
00480         cout << "Need to increase buffsize in list" << endl;
00481         exit(1);
00482       }
00483       write_buffer();
00484     }
00485   }
00486   else
00487   {
00488     bptr+=nsize;
00489   }
00490 }
00491 
00496 void fixed_smartlist::operator ++ (void)
00497 {
00498   if ( bptr==buffend)
00499   {
00500     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00501     {
00502       read_buffer();
00503     }
00504     else
00505     {
00506       write_buffer();
00507     }
00508   }
00509   else
00510   {
00511     bptr++;
00512   }
00513 }
00514 
00518 void fixed_smartlist::read_file(void)
00519 {
00520   //rewind the file
00521   off_t pos=lseek(fp,0L,SEEK_SET);
00522   char buffer[50000];
00523   int offset=0;
00524   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00525   cout << b << endl;
00526   ssize_t nw = 0;
00527   do
00528   {
00529     unsigned int nbytes=0;
00530     nw = ::read(fp,&nbytes,sizeof(unsigned int));
00531     if (nw != -1)
00532     {
00533       nw = ::read(fp, buffer + offset, (size_t)nbytes);
00534       if (nw != -1)
00535       {
00536         offset+=nbytes;
00537         nw = ::read(fp, &pos, sizeof(off_t));
00538       }
00539     }
00540   }
00541   while(nw);
00542 }