ADMB Documentation  11.1.2192
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f14.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f14.cpp 1919 2014-04-22 22:02:01Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <df1b2fun.h>
00012 
00017 fixed_smartlist2::fixed_smartlist2(void)
00018 {
00019   nentries=0;
00020   end_saved=0;
00021   eof_flag=0;
00022   noreadflag=0;
00023   written_flag=0;
00024   direction=0;
00025   bufsize=0;
00026   true_buffer=0;
00027   true_buffend=0;
00028   buffer=0;
00029   buffend=0;
00030   bptr=buffer;
00031 }
00032 
00037 fixed_smartlist2::fixed_smartlist2(unsigned int _bufsize,
00038   const adstring& _filename)
00039 {
00040   allocate(_bufsize,_filename);
00041 }
00042 
00047 void fixed_smartlist2::allocate(unsigned int _bufsize,
00048   const adstring& _filename)
00049 {
00050   nentries=_bufsize/sizeof(int);
00051   end_saved=0;
00052   eof_flag=0;
00053   noreadflag=0;
00054   written_flag=0;
00055   direction=0;
00056   bufsize=_bufsize;
00057   filename=_filename;
00058   AD_ALLOCATE(true_buffer,int,nentries+2,df1b2_gradlist)
00059   doubleptr=(double*)true_buffer;
00060   true_buffend=true_buffer+nentries+1;
00061   buffer=true_buffer+1;
00062   buffend=true_buffend-1;
00063   bptr=buffer;
00064   *true_buffer=5678;
00065   *true_buffend=9999;
00066   fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00067                    O_BINARY, S_IREAD | S_IWRITE);
00068   if (fp == -1)
00069   {
00070     cerr << "Error trying to open file " << filename
00071          << " in class fixed_smartlist2 " << endl;
00072     ad_exit(1);
00073   }
00074 
00075   /*off_t pos=*/lseek(fp,0L,SEEK_CUR);
00076 }
00077 
00082 void fixed_smartlist2::write(int n)
00083 {
00084   int nw=::write(fp,buffer,n);
00085   if (nw<n)
00086   {
00087     cerr << "Error writing to file " << filename << endl;
00088     ad_exit(1);
00089   }
00090 }
00091 
00096 void fixed_smartlist2::rewind(void)
00097 {
00098   bptr=buffer;
00099   unsigned int nbytes=0;
00100   eof_flag=0;
00101   if (written_flag)
00102   {
00103     lseek(fp,0L,SEEK_SET);
00104     // get the record size
00105     ::read(fp,&nbytes,sizeof(int));
00106     if (nbytes>bufsize)
00107     {
00108       cerr << "Error -- record size in file seems to be larger than"
00109        " the buffer it was created from " << endl
00110         << " buffer size is " << bufsize << " record size is supposedly "
00111         << nbytes << endl;
00112       ad_exit(1);
00113     }
00114     // now read the record into the buffer
00115     /*int nr=*/::read(fp,buffer,nbytes);
00116     //cout << "Number of bytes read " << nr << endl;
00117     // skip over file postion entry in file
00118     // so we are ready to read second record
00119     lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00120   }
00121 }
00122 
00127 void fixed_smartlist2::initialize(void)
00128 {
00129   end_saved=0;
00130   eof_flag=0;
00131   bptr=buffer;
00132   //int nbytes=0;
00133   written_flag=0;
00134   lseek(fp,0L,SEEK_SET);
00135   set_forward();
00136 }
00137 
00142 void fixed_smartlist2::check_buffer_size(int nsize)
00143 {
00144   if ( bptr+nsize-1 > buffend)
00145   {
00146     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00147     {
00148       read_buffer();
00149     }
00150     else
00151     {
00152       if ((unsigned int)nsize>bufsize)
00153       {
00154          cout << "Need to increase buffsize in list" << endl;
00155          exit(1);
00156       }
00157       write_buffer();
00158     }
00159   }
00160 }
00161 
00166 void fixed_smartlist2::restore_end(void)
00167 {
00168   if (written_flag)
00169   {
00170     if (end_saved)
00171     {
00172       /*off_t ipos=*/lseek(fp,endof_file_ptr,SEEK_SET);
00173       read_buffer();
00174       set_recend();
00175     }
00176   }
00177 }
00178 
00183 void fixed_smartlist2::save_end(void)
00184 {
00185   if (written_flag)
00186   {
00187     if (!end_saved)
00188     {
00189       write_buffer_one_less();
00190       end_saved=1;
00191     }
00192   }
00193 }
00194 
00199 void fixed_smartlist2::write_buffer_one_less(void)
00200 {
00201   int nbytes=adptr_diff(bptr,buffer);
00202   if (nbytes)
00203   {
00204     written_flag=1;
00205     // get the current file position
00206     off_t pos=lseek(fp,0L,SEEK_CUR);
00207 
00208     // write the size of the next record into the file
00209     ::write(fp,&nbytes,sizeof(int));
00210 
00211     // write the record into the file
00212     int nw=::write(fp,buffer,nbytes);
00213     //cout << "Number of bytes written " << nw
00214      //    << " bptr value =  " << bptr << endl;
00215     //for (int ii=0;ii<=25;ii++)
00216     //  cout << int (*(buffer+ii)) << " ";
00217     //cout << endl;
00218     if (nw<nbytes)
00219     {
00220       cerr << "Error writing to file " << filename << endl;
00221       ad_exit(1);
00222     }
00223     // reset the pointer to the beginning of the buffer
00224     bptr=buffer;
00225 
00226     // now write the previous file position into the file so we can back up
00227     // when we want to.
00228     ::write(fp,&pos,sizeof(off_t));
00229 
00230     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00231 
00232     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00233   }
00234 }
00235 
00240 void fixed_smartlist2::write_buffer(void)
00241 {
00242   int nbytes=adptr_diff(bptr+1,buffer);
00243   if (nbytes)
00244   {
00245     written_flag=1;
00246     // get the current file position
00247     off_t pos=lseek(fp,0L,SEEK_CUR);
00248 
00249     // write the size of the next record into the file
00250     ::write(fp,&nbytes,sizeof(int));
00251 
00252     // write the record into the file
00253     int nw=::write(fp,buffer,nbytes);
00254     //cout << "Number of bytes written " << nw
00255      //    << " bptr value =  " << bptr << endl;
00256     //for (int ii=0;ii<=25;ii++)
00257     //  cout << int (*(buffer+ii)) << " ";
00258     //cout << endl;
00259     if (nw<nbytes)
00260     {
00261       cerr << "Error writing to file " << filename << endl;
00262       ad_exit(1);
00263     }
00264     // reset the pointer to the beginning of the buffer
00265     bptr=buffer;
00266 
00267     // now write the previous file position into the file so we can back up
00268     // when we want to.
00269     ::write(fp,&pos,sizeof(off_t));
00270 
00271     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00272 
00273     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00274   }
00275 }
00276 
00281 void fixed_smartlist2::read_buffer(void)
00282 {
00283   off_t pos;
00284   unsigned int nbytes;
00285   if (!written_flag)
00286   {
00287     if (direction ==-1)
00288       eof_flag=-1;
00289     else
00290       eof_flag=1;
00291   }
00292   else
00293   {
00294     if (direction ==-1) // we are going backwards
00295     {
00296       off_t ipos=lseek(fp,0L,SEEK_CUR);
00297       if (ipos ==0)
00298       {
00299         eof_flag=-1;
00300         return;
00301       }
00302       // offset of the begining of the record is at the end
00303       // of the record
00304       lseek(fp,long(-sizeof(off_t)),SEEK_CUR);
00305       read(fp,&pos,sizeof(off_t));
00306       // back up to the beginning of the record (plus record size)
00307       lseek(fp,pos,SEEK_SET);
00308       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00309     }
00310     // get the record size
00311     ::read(fp,&nbytes,sizeof(int));
00312     if (nbytes>bufsize)
00313     {
00314       cerr << "Error -- record size in file seems to be larger than"
00315        " the buffer it was created from " << endl
00316         << " buffer size is " << bufsize << " record size is supposedly "
00317         << nbytes << endl;
00318       ad_exit(1);
00319     }
00320     // now read the record into the buffer
00321     unsigned int nr=::read(fp,buffer,nbytes);
00322     if (nr != nbytes)
00323     {
00324       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00325       exit(1);
00326     }
00327 
00328    /*
00329     cout << "Number of bytes read " << nr << endl;
00330     cout << "buffer value = ";
00331     for (int ii=0;ii<=25;ii++)
00332       cout << int (*(buffer+ii)) << " ";
00333     cout << endl;
00334     */
00335     // reset the pointer to the beginning of the buffer
00336     bptr=buffer;
00337     int ns=nbytes/sizeof(int);
00338     recend=bptr+ns-1;
00339     //cout << "Number of bytes read " << nr
00340      //    << "  recend value = " << recend << endl;
00341     if (direction ==-1) // we are going backwards
00342     {
00343       // backup the file pointer again
00344       lseek(fp,pos,SEEK_SET);
00345       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00346     }
00347     else  // we are going forward
00348     {
00349       // skip over file postion entry in file
00350       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00351     }
00352   }
00353 }
00354 
00359 void memcpy(const fixed_smartlist2 & _list,void * p,int nsize)
00360 {
00361   ADUNCONST(fixed_smartlist2,list)
00362   if ( list.bptr+nsize-1 > list.buffend)
00363   {
00364     cerr << " Trying to write outside list buffer" << endl;
00365     exit(1);
00366   }
00367   memcpy(list.bptr,p,nsize);
00368   list.bptr+=nsize;
00369 }
00370 
00375 void memcpy(void * p,const fixed_smartlist2 & _list,int nsize)
00376 {
00377   ADUNCONST(fixed_smartlist2,list)
00378   if ( list.bptr+nsize-1 > list.buffend)
00379   {
00380     cerr << " Trying to write outside list buffer" << endl;
00381     exit(1);
00382   }
00383   memcpy(p,list.bptr,nsize);
00384   list.bptr+=nsize;
00385 }
00386 
00391 void fixed_smartlist2::operator -= (int n)
00392 {
00393   if (bptr-n<buffer)
00394   {
00395     if (bptr != buffer)
00396     {
00397       cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00398       exit(1);
00399     }
00400     else
00401     {
00402       // get previous record from the file
00403       read_buffer();
00404       bptr=recend-n+1;
00405     }
00406   }
00407   else
00408   {
00409     bptr-=n;
00410   }
00411 }
00412 
00417 void fixed_smartlist2::operator -- (void)
00418 {
00419   if (bptr-1<buffer)
00420   {
00421     if (bptr != buffer)
00422     {
00423       cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00424       exit(1);
00425     }
00426     else
00427     {
00428       // get previous record from the file
00429       read_buffer();
00430       //bptr=recend+1;
00431       bptr=recend;
00432     }
00433   }
00434   else
00435   {
00436     bptr--;
00437   }
00438 }
00439 
00444 void fixed_smartlist2::operator += (int nsize)
00445 {
00446   if ( bptr+nsize-1 > buffend)
00447   {
00448     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00449     {
00450       read_buffer();
00451     }
00452     else
00453     {
00454       if ((unsigned int)nsize>bufsize)
00455       {
00456          cout << "Need to increase buffsize in list" << endl;
00457          exit(1);
00458       }
00459       write_buffer();
00460     }
00461   }
00462   else
00463   {
00464     bptr+=nsize;
00465   }
00466 }
00467 
00472 void fixed_smartlist2::operator ++ (void)
00473 {
00474   if ( bptr==buffend)
00475   {
00476     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00477     {
00478       read_buffer();
00479     }
00480     else
00481     {
00482       write_buffer();
00483     }
00484   }
00485   else
00486   {
00487     bptr++;
00488   }
00489 }
00490 
00495 void fixed_smartlist2::read_file(void)
00496 {
00497   //rewind the file
00498   off_t pos=lseek(fp,0L,SEEK_SET);
00499   int nbytes=0;
00500   char buffer[50000];
00501   int offset=0;
00502   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00503   cout << b << endl;
00504   int nw=0;
00505   do
00506   {
00507     nw=::read(fp,&nbytes,sizeof(int));
00508     nw=::read(fp,buffer+offset,nbytes);
00509     offset+=nbytes;
00510     ::read(fp,&pos,sizeof(off_t));
00511   }
00512   while(nw);
00513 }