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