ADMB Documentation  11.6rc.3396
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f13.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id$
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 
00041 fixed_smartlist::fixed_smartlist()
00042 {
00043   nentries=0;
00044   bufsize=0;
00045   buffer=0;
00046   true_buffer=0;
00047   buffend=0;
00048   bptr=0;
00049   fp=-1;
00050 }
00051 
00055 fixed_smartlist::fixed_smartlist(const size_t _bufsize,
00056   const adstring& _filename):
00057   endof_file_ptr(-1),
00058   recend(NULL),
00059   sbptr(NULL)
00060 {
00061   allocate(_bufsize,_filename);
00062 }
00063 void fixed_smartlist::allocate(const size_t _bufsize,const adstring& _filename)
00064 {
00065   nentries=_bufsize/sizeof(fixed_list_entry);
00066   end_saved=0;
00067   eof_flag=0;
00068   noreadflag=0;
00069   written_flag=0;
00070   direction=0;
00071   bufsize=_bufsize;
00072   filename=_filename;
00073   AD_ALLOCATE(true_buffer,fixed_list_entry,nentries+2,df1b2_gradlist)
00074 #ifndef OPT_LIB
00075   memset(true_buffer, 0, sizeof(fixed_list_entry) * (nentries + 2));
00076 #endif
00077   doubleptr=(double*)true_buffer;
00078   true_buffend=true_buffer+nentries+1;
00079   buffer=true_buffer+1;
00080   buffend=true_buffend-2;
00081   bptr=buffer;
00082   true_buffer->numbytes=5678;
00083   //int(true_buffer->pf)=1234;
00084   true_buffend->numbytes=9999;
00085   //int(true_buffend->pf)=6666;
00086   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00087                    O_BINARY, S_IREAD | S_IWRITE);
00088   if (fp < 0)
00089   {
00090     cerr << "Error trying to open file " << filename
00091          << " in class fixed_smartlist " << endl;
00092     ad_exit(1);
00093   }
00094   else
00095   {
00096     /*off_t pos=*/lseek(fp, 0L, SEEK_CUR);
00097   }
00098 }
00099 
00103 void fixed_smartlist::write(const size_t n)
00104 {
00105 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00106   #ifndef OPT_LIB
00107   assert(n <= UINT_MAX);
00108   #endif
00109   ssize_t nw = ::write(fp,buffer,(unsigned int)n);
00110 #else
00111   ssize_t nw = ::write(fp, buffer, n);
00112 #endif
00113   if (nw <= -1 || (size_t)nw != n)
00114   {
00115     cerr << "Error writing to file " << filename << endl;
00116     ad_exit(1);
00117   }
00118 }
00119 
00123 void fixed_smartlist::rewind(void)
00124 {
00125   bptr=buffer;
00126   eof_flag=0;
00127   if (written_flag)
00128   {
00129     lseek(fp,0L,SEEK_SET);
00130     // get the record size
00131     unsigned int nbytes=0;
00132     ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00133     assert(ret != -1);
00134     if (nbytes > bufsize)
00135     {
00136       cerr << "Error -- record size in file seems to be larger than"
00137        " the buffer it was created from " << endl
00138         << " buffer size is " << bufsize << " record size is supposedly "
00139         << nbytes << endl;
00140       ad_exit(1);
00141     }
00142     // now read the record into the buffer
00143     ret = ::read(fp,buffer,nbytes);
00144     assert(ret != -1);
00145 
00146     // skip over file postion entry in file
00147     // so we are ready to read second record
00148 #ifdef OPT_LIB
00149     lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
00150 #else
00151     ret = lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
00152     assert(ret >= 0);
00153 #endif
00154   }
00155 }
00156 
00161 void fixed_smartlist::initialize(void)
00162 {
00163   end_saved=0;
00164   eof_flag=0;
00165   bptr=buffer;
00166   //int nbytes=0;
00167   written_flag=0;
00168   lseek(fp,0L,SEEK_SET);
00169   set_forward();
00170 }
00171 
00176 void fixed_smartlist::check_buffer_size(const size_t nsize)
00177 {
00178   if ( bptr+nsize-1 > buffend)
00179   {
00180     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00181     {
00182       read_buffer();
00183     }
00184     else
00185     {
00186       if (nsize>bufsize)
00187       {
00188          cout << "Need to increase buffsize in list" << endl;
00189          exit(1);
00190       }
00191       write_buffer();
00192     }
00193   }
00194 }
00198 void fixed_smartlist::restore_end(void)
00199 {
00200   if (written_flag)
00201   {
00202     if (end_saved)
00203     {
00204 #ifdef OPT_LIB
00205       lseek(fp, 0L, SEEK_END);
00206       lseek(fp, endof_file_ptr, SEEK_SET);
00207 #else
00208       off_t ret = lseek(fp, 0L, SEEK_END);
00209       assert(ret >= 0);
00210       ret = lseek(fp, endof_file_ptr, SEEK_SET);
00211       assert(ret >= 0);
00212 #endif
00213       read_buffer();
00214       set_recend();
00215     }
00216   }
00217 }
00218 
00223 void fixed_smartlist::save_end(void)
00224 {
00225   if (written_flag)
00226   {
00227     if (!end_saved)
00228     {
00229       write_buffer_one_less();
00230       end_saved=1;
00231     }
00232   }
00233 }
00234 
00239 void fixed_smartlist::write_buffer_one_less(void)
00240 {
00241   int _nbytes=adptr_diff(bptr,buffer);
00242   if (_nbytes > 0)
00243   {
00244     const unsigned int nbytes = (unsigned int)_nbytes;
00245 
00246     written_flag=1;
00247     // get the current file position
00248     off_t pos=lseek(fp,0L,SEEK_CUR);
00249 
00250     // write the size of the next record into the file
00251 #if defined(OPT_LIB) && !defined(_MSC_VER)
00252     ::write(fp, &nbytes, sizeof(unsigned int));
00253 #else
00254     ssize_t ret = ::write(fp, &nbytes, sizeof(unsigned int));
00255     assert(ret != -1);
00256 #endif
00257 
00258     // write the record into the file
00259     ssize_t nw = ::write(fp,buffer,nbytes);
00260 #ifndef OPT_LIB
00261     assert(nw != -1);
00262 #endif
00263     if ((size_t)nw < nbytes)
00264     {
00265       cerr << "Error writing to file " << filename << endl;
00266       ad_exit(1);
00267     }
00268     // reset the pointer to the beginning of the buffer
00269     bptr=buffer;
00270 
00271     // now write the previous file position into the file so we can back up
00272     // when we want to.
00273 #if defined(OPT_LIB) && !defined(_MSC_VER)
00274     ::write(fp,&pos,sizeof(off_t));
00275 #else
00276     ret = ::write(fp,&pos,sizeof(off_t));
00277     assert(ret != -1);
00278 #endif
00279 
00280     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00281     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00282   }
00283 }
00284 
00289 void fixed_smartlist::write_buffer(void)
00290 {
00291   int _nbytes=adptr_diff(bptr+1,buffer);
00292   if (_nbytes > 0)
00293   {
00294     unsigned int nbytes = (unsigned int)_nbytes;
00295     if (nbytes > bufsize)
00296     {
00297       cerr << "n bytes > bufsize in "
00298         "fixed_smartlist::write_buffer(void) this can't happen!" << endl;
00299     }
00300     written_flag=1;
00301     // get the current file position
00302     off_t pos=lseek(fp,0L,SEEK_CUR);
00303 
00304     // write the size of the next record into the file
00305     ssize_t ret = ::write(fp,&nbytes,sizeof(unsigned int));
00306     assert(ret != -1);
00307 
00308     // write the record into the file
00309     ssize_t nw=::write(fp,buffer,nbytes);
00310 #ifndef OPT_LIB
00311     assert(nw != -1);
00312 #endif
00313     if ((size_t)nw < nbytes)
00314     {
00315       cerr << "Error writing to file " << filename << endl;
00316       ad_exit(1);
00317     }
00318     // reset the pointer to the beginning of the buffer
00319     bptr=buffer;
00320 
00321     // now write the previous file position into the file so we can back up
00322     // when we want to.
00323     ret = ::write(fp,&pos,sizeof(off_t));
00324     assert(ret != -1);
00325 
00326     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00327     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00328   }
00329 }
00330 
00335 void fixed_smartlist::read_buffer(void)
00336 {
00337   if (!written_flag)
00338   {
00339     if (direction ==-1)
00340       eof_flag=-1;
00341     else
00342       eof_flag=1;
00343   }
00344   else
00345   {
00346     off_t pos = 0;
00347     if (direction ==-1) // we are going backwards
00348     {
00349       off_t ipos=lseek(fp,0L,SEEK_CUR);
00350       if (ipos ==0)
00351       {
00352         eof_flag=-1;
00353         return;
00354       }
00355       // offset of the begining of the record is at the end
00356       // of the record
00357       lseek(fp,-((off_t)sizeof(off_t)),SEEK_CUR);
00358       ssize_t ret = read(fp,&pos,sizeof(off_t));
00359       assert(ret != -1);
00360       // back up to the beginning of the record (plus record size)
00361       lseek(fp,pos,SEEK_SET);
00362       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00363     }
00364     // get the record size
00365     unsigned int nbytes = 0;
00366     ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00367     assert(ret != -1);
00368     if (nbytes > bufsize)
00369     {
00370       cerr << "Error -- record size in file seems to be larger than"
00371        " the buffer it was created from " << endl
00372         << " buffer size is " << bufsize << " record size is supposedly "
00373         << nbytes << endl;
00374       ad_exit(1);
00375     }
00376     // now read the record into the buffer
00377     ssize_t nr = ::read(fp,buffer,nbytes);
00378 #ifndef OPT_LIB
00379     assert(nr != -1);
00380 #endif
00381     if ((size_t)nr != nbytes)
00382     {
00383       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00384       exit(1);
00385     }
00386 
00387     // reset the pointer to the beginning of the buffer
00388     bptr=buffer;
00389     int ns=nbytes/(int)sizeof(fixed_list_entry);
00390     recend=bptr+ns-1;
00391     //cout << "Number of bytes read " << nr
00392      //    << "  recend value = " << recend << endl;
00393     if (direction ==-1) // we are going backwards
00394     {
00395       // backup the file pointer again
00396 #ifdef OPT_LIB
00397       lseek(fp,pos,SEEK_SET);
00398 #else
00399       off_t ret = lseek(fp, pos, SEEK_SET);
00400       assert(ret >= 0);
00401 #endif
00402       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00403     }
00404     else  // we are going forward
00405     {
00406       // skip over file postion entry in file
00407 #ifdef OPT_LIB
00408       lseek(fp,(off_t)sizeof(off_t),SEEK_CUR);
00409 #else
00410       off_t ret = lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
00411       assert(ret >= 0);
00412 #endif
00413     }
00414   }
00415 }
00416 
00421 void memcpy(const fixed_smartlist& _list, void* p, const size_t nsize)
00422 {
00423   ADUNCONST(fixed_smartlist,list)
00424   if (list.bptr+nsize-1 > list.buffend)
00425   {
00426     cerr << " Trying to write outside list buffer" << endl;
00427     exit(1);
00428   }
00429   memcpy(list.bptr,p,nsize);
00430   list.bptr+=nsize;
00431 }
00432 
00437 void memcpy(void* p, const fixed_smartlist& _list, const size_t nsize)
00438 {
00439   ADUNCONST(fixed_smartlist,list)
00440   if (list.bptr+nsize-1 > list.buffend)
00441   {
00442     cerr << " Trying to write outside list buffer" << endl;
00443     exit(1);
00444   }
00445   memcpy(p,list.bptr,nsize);
00446   list.bptr+=nsize;
00447 }
00448 
00449 void fixed_smartlist::operator -= (int n)
00450 {
00451   if (bptr-n<buffer)
00452   {
00453     if (bptr != buffer)
00454     {
00455       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00456       exit(1);
00457     }
00458     else
00459     {
00460       // get previous record from the file
00461       read_buffer();
00462       bptr=recend-n+1;
00463     }
00464   }
00465   else
00466   {
00467     bptr-=n;
00468   }
00469 }
00470 void fixed_smartlist::operator -- (void)
00471 {
00472   if (bptr-1<buffer)
00473   {
00474     if (bptr != buffer)
00475     {
00476       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00477       exit(1);
00478     }
00479     else
00480     {
00481       // get previous record from the file
00482       read_buffer();
00483       //bptr=recend+1;
00484       bptr=recend;
00485     }
00486   }
00487   else
00488   {
00489     bptr--;
00490   }
00491 }
00492 
00493 void fixed_smartlist::operator += (int nsize)
00494 {
00495   if ( bptr+nsize-1 > buffend)
00496   {
00497     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00498     {
00499       read_buffer();
00500     }
00501     else
00502     {
00503       if ((unsigned int)nsize>bufsize)
00504       {
00505         cout << "Need to increase buffsize in list" << endl;
00506         exit(1);
00507       }
00508       write_buffer();
00509     }
00510   }
00511   else
00512   {
00513     bptr+=nsize;
00514   }
00515 }
00516 
00521 void fixed_smartlist::operator ++ (void)
00522 {
00523   if ( bptr==buffend)
00524   {
00525     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00526     {
00527       read_buffer();
00528     }
00529     else
00530     {
00531       write_buffer();
00532     }
00533   }
00534   else
00535   {
00536     bptr++;
00537   }
00538 }
00539 
00543 void fixed_smartlist::read_file(void)
00544 {
00545   //rewind the file
00546   off_t pos=lseek(fp,0L,SEEK_SET);
00547   char buffer[50000];
00548   int offset=0;
00549   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00550   cout << b << endl;
00551   ssize_t nw = 0;
00552   do
00553   {
00554     unsigned int nbytes=0;
00555     nw = ::read(fp,&nbytes,sizeof(unsigned int));
00556     if (nw != -1)
00557     {
00558       nw = ::read(fp, buffer + offset, (size_t)nbytes);
00559       if (nw != -1)
00560       {
00561         offset+=nbytes;
00562         nw = ::read(fp, &pos, sizeof(off_t));
00563       }
00564     }
00565   }
00566   while(nw);
00567 }