ADMB Documentation  11.1.2353
 All Classes Files Functions Variables Typedefs Friends Defines
df1b2f13.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df1b2f13.cpp 2324 2014-09-11 21:47:31Z 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 
00091 void fixed_smartlist::write(int n)
00092 {
00093   ssize_t nw = ::write(fp, buffer, n);
00094   if (nw < n)
00095   {
00096     cerr << "Error writing to file " << filename << endl;
00097     ad_exit(1);
00098   }
00099 }
00100 
00105 void fixed_smartlist::rewind(void)
00106 {
00107   bptr=buffer;
00108   eof_flag=0;
00109   if (written_flag)
00110   {
00111     lseek(fp,0L,SEEK_SET);
00112     // get the record size
00113     int nbytes=0;
00114     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00115     assert(ret != -1);
00116     assert(nbytes >= 0);
00117     if ((unsigned int)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 #ifdef OPT_LIB
00223     ::write(fp, &nbytes, sizeof(int));
00224 #else
00225     ssize_t ret = ::write(fp, &nbytes, sizeof(int));
00226     assert(ret != -1);
00227 #endif
00228 
00229     // write the record into the file
00230     ssize_t nw = ::write(fp,buffer,nbytes);
00231     //cout << "Number of bytes written 1less " << nw
00232      //    << " bptr value =  " << bptr << endl;
00233     //for (int ii=0;ii<=25;ii++)
00234     //  cout << int (*(buffer+ii)) << " ";
00235     //cout << endl;
00236     if (nw<nbytes)
00237     {
00238       cerr << "Error writing to file " << filename << endl;
00239       ad_exit(1);
00240     }
00241     // reset the pointer to the beginning of the buffer
00242     bptr=buffer;
00243 
00244     // now write the previous file position into the file so we can back up
00245     // when we want to.
00246 #ifdef OPT_LIB
00247     ::write(fp,&pos,sizeof(off_t));
00248 #else
00249     ret = ::write(fp,&pos,sizeof(off_t));
00250     assert(ret != -1);
00251 #endif
00252 
00253     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00254     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00255   }
00256 }
00257 
00262 void fixed_smartlist::write_buffer(void)
00263 {
00264   int nbytes=adptr_diff(bptr+1,buffer);
00265   assert(nbytes >= 0);
00266   if ((unsigned int)nbytes > bufsize)
00267   {
00268     cerr << "n bytes > bufsize in "
00269       "fixed_smartlist::write_buffer(void) this can't happen!" << endl;
00270   }
00271   if (nbytes)
00272   {
00273     written_flag=1;
00274     // get the current file position
00275     off_t pos=lseek(fp,0L,SEEK_CUR);
00276 
00277     // write the size of the next record into the file
00278     ssize_t ret = ::write(fp,&nbytes,sizeof(int));
00279     assert(ret != -1);
00280 
00281     // write the record into the file
00282     ssize_t nw=::write(fp,buffer,nbytes);
00283     //cout << "Number of bytes written " << nw
00284      //    << " bptr value =  " << bptr << endl;
00285     //for (int ii=0;ii<=25;ii++)
00286     //  cout << int (*(buffer+ii)) << " ";
00287     //cout << endl;
00288     if (nw<nbytes)
00289     {
00290       cerr << "Error writing to file " << filename << endl;
00291       ad_exit(1);
00292     }
00293     // reset the pointer to the beginning of the buffer
00294     bptr=buffer;
00295 
00296     // now write the previous file position into the file so we can back up
00297     // when we want to.
00298     ret = ::write(fp,&pos,sizeof(off_t));
00299     assert(ret != -1);
00300 
00301     endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00302     //cout << lseek(fp,0L,SEEK_CUR) << endl;
00303   }
00304 }
00305 
00310 void fixed_smartlist::read_buffer(void)
00311 {
00312   if (!written_flag)
00313   {
00314     if (direction ==-1)
00315       eof_flag=-1;
00316     else
00317       eof_flag=1;
00318   }
00319   else
00320   {
00321     off_t pos = 0;
00322     if (direction ==-1) // we are going backwards
00323     {
00324       off_t ipos=lseek(fp,0L,SEEK_CUR);
00325       if (ipos ==0)
00326       {
00327         eof_flag=-1;
00328         return;
00329       }
00330       // offset of the begining of the record is at the end
00331       // of the record
00332       lseek(fp,-((long)sizeof(off_t)),SEEK_CUR);
00333       ssize_t ret = read(fp,&pos,sizeof(off_t));
00334       assert(ret != -1);
00335       // back up to the beginning of the record (plus record size)
00336       lseek(fp,pos,SEEK_SET);
00337       //*(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00338     }
00339     // get the record size
00340     int nbytes = 0;
00341     ssize_t ret = ::read(fp,&nbytes,sizeof(int));
00342     assert(ret != -1);
00343     assert(nbytes >= 0);
00344     if ((unsigned int)nbytes > bufsize)
00345     {
00346       cerr << "Error -- record size in file seems to be larger than"
00347        " the buffer it was created from " << endl
00348         << " buffer size is " << bufsize << " record size is supposedly "
00349         << nbytes << endl;
00350       ad_exit(1);
00351     }
00352     // now read the record into the buffer
00353     ssize_t nr = ::read(fp,buffer,nbytes);
00354     assert(nr != -1);
00355     if (nr != nbytes)
00356     {
00357       cerr << "Error reading -- should be " << nbytes << " got " << nr << endl;
00358       exit(1);
00359     }
00360 
00361     //cout << "Number of bytes read " << nr << endl;
00362    /*
00363     cout << "buffer value = ";
00364     for (int ii=0;ii<=2;ii++)
00365       cout << *(buffer+ii) << " ";
00366     cout << endl;
00367     */
00368 
00369     // reset the pointer to the beginning of the buffer
00370     bptr=buffer;
00371     int ns=nbytes/(int)sizeof(fixed_list_entry);
00372     recend=bptr+ns-1;
00373     //cout << "Number of bytes read " << nr
00374      //    << "  recend value = " << recend << endl;
00375     if (direction ==-1) // we are going backwards
00376     {
00377       // backup the file pointer again
00378       lseek(fp,pos,SEEK_SET);
00379       // *(off_t*)(bptr)=lseek(fp,pos,SEEK_SET);
00380     }
00381     else  // we are going forward
00382     {
00383       // skip over file postion entry in file
00384       lseek(fp,long(sizeof(off_t)),SEEK_CUR);
00385     }
00386   }
00387 }
00388 
00393 void memcpy(const fixed_smartlist & _list,void * p,int nsize)
00394 {
00395   ADUNCONST(fixed_smartlist,list)
00396   if ( list.bptr+nsize-1 > list.buffend)
00397   {
00398     cerr << " Trying to write outside list buffer" << endl;
00399     exit(1);
00400   }
00401   memcpy(list.bptr,p,nsize);
00402   list.bptr+=nsize;
00403 }
00404 
00409 void memcpy(void * p,const fixed_smartlist & _list,int nsize)
00410 {
00411   ADUNCONST(fixed_smartlist,list)
00412   if ( list.bptr+nsize-1 > list.buffend)
00413   {
00414     cerr << " Trying to write outside list buffer" << endl;
00415     exit(1);
00416   }
00417   memcpy(p,list.bptr,nsize);
00418   list.bptr+=nsize;
00419 }
00420 
00421 void fixed_smartlist::operator -= (int n)
00422 {
00423   if (bptr-n<buffer)
00424   {
00425     if (bptr != buffer)
00426     {
00427       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00428       exit(1);
00429     }
00430     else
00431     {
00432       // get previous record from the file
00433       read_buffer();
00434       bptr=recend-n+1;
00435     }
00436   }
00437   else
00438   {
00439     bptr-=n;
00440   }
00441 }
00442 void fixed_smartlist::operator -- (void)
00443 {
00444   if (bptr-1<buffer)
00445   {
00446     if (bptr != buffer)
00447     {
00448       cerr << " Sanity error in fixed_smartlist::operator -= (int)" << endl;
00449       exit(1);
00450     }
00451     else
00452     {
00453       // get previous record from the file
00454       read_buffer();
00455       //bptr=recend+1;
00456       bptr=recend;
00457     }
00458   }
00459   else
00460   {
00461     bptr--;
00462   }
00463 }
00464 
00465 void fixed_smartlist::operator += (int nsize)
00466 {
00467   if ( bptr+nsize-1 > buffend)
00468   {
00469     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00470     {
00471       read_buffer();
00472     }
00473     else
00474     {
00475       if ((unsigned int)nsize>bufsize)
00476       {
00477         cout << "Need to increase buffsize in list" << endl;
00478         exit(1);
00479       }
00480       write_buffer();
00481     }
00482   }
00483   else
00484   {
00485     bptr+=nsize;
00486   }
00487 }
00488 
00493 void fixed_smartlist::operator ++ (void)
00494 {
00495   if ( bptr==buffend)
00496   {
00497     if (df1b2variable::get_passnumber()==2 && !noreadflag )
00498     {
00499       read_buffer();
00500     }
00501     else
00502     {
00503       write_buffer();
00504     }
00505   }
00506   else
00507   {
00508     bptr++;
00509   }
00510 }
00511 
00515 void fixed_smartlist::read_file(void)
00516 {
00517   //rewind the file
00518   off_t pos=lseek(fp,0L,SEEK_SET);
00519   int nbytes=0;
00520   char buffer[50000];
00521   int offset=0;
00522   fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00523   cout << b << endl;
00524   ssize_t nw = 0;
00525   do
00526   {
00527     nw = ::read(fp,&nbytes,sizeof(int));
00528     nw = ::read(fp,buffer+offset,nbytes);
00529     offset+=nbytes;
00530     nw = ::read(fp,&pos,sizeof(off_t));
00531   }
00532   while(nw);
00533 }