00001
00002
00003
00004
00005
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
00027 fixed_smartlist2::fixed_smartlist2():
00028 endof_file_ptr(-1),
00029 doubleptr(NULL),
00030 recend(NULL),
00031 sbptr(NULL),
00032 fp(-1)
00033 {
00034 nentries=0;
00035 end_saved=0;
00036 eof_flag=0;
00037 noreadflag=0;
00038 written_flag=0;
00039 direction=0;
00040 bufsize=0;
00041 true_buffer=0;
00042 true_buffend=0;
00043 buffer=0;
00044 buffend=0;
00045 bptr=buffer;
00046 }
00050 fixed_smartlist2::fixed_smartlist2(const size_t _bufsize,
00051 const adstring& _filename):
00052 endof_file_ptr(-1),
00053 recend(NULL),
00054 sbptr(NULL)
00055 {
00056 allocate(_bufsize,_filename);
00057 }
00058
00063 void fixed_smartlist2::allocate(const size_t _bufsize,
00064 const adstring& _filename)
00065 {
00066 nentries=_bufsize/sizeof(int);
00067 end_saved=0;
00068 eof_flag=0;
00069 noreadflag=0;
00070 written_flag=0;
00071 direction=0;
00072 bufsize=_bufsize;
00073 filename=_filename;
00074 AD_ALLOCATE(true_buffer,int,nentries+2,df1b2_gradlist)
00075 doubleptr=(double*)true_buffer;
00076 true_buffend=true_buffer+nentries+1;
00077 buffer=true_buffer+1;
00078 buffend=true_buffend-1;
00079 bptr=buffer;
00080 *true_buffer=5678;
00081 *true_buffend=9999;
00082 fp=open((char*)(filename), O_RDWR | O_CREAT | O_TRUNC |
00083 O_BINARY, S_IREAD | S_IWRITE);
00084 if (fp < 0)
00085 {
00086 cerr << "Error trying to open file " << filename
00087 << " in class fixed_smartlist2 " << endl;
00088 ad_exit(1);
00089 }
00090 else
00091 {
00092 lseek(fp, 0L, SEEK_CUR);
00093 }
00094 }
00095
00099 void fixed_smartlist2::write(const size_t n)
00100 {
00101 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00102 assert(n <= INT_MAX);
00103 ssize_t nw = ::write(fp, buffer, (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
00117 void fixed_smartlist2::rewind(void)
00118 {
00119 bptr=buffer;
00120 eof_flag=0;
00121 if (written_flag)
00122 {
00123 lseek(fp,0L,SEEK_SET);
00124
00125 unsigned int nbytes = 0;
00126 ssize_t ret = ::read(fp,&nbytes,sizeof(unsigned int));
00127 assert(ret != -1);
00128 if (nbytes > bufsize)
00129 {
00130 cerr << "Error -- record size in file seems to be larger than"
00131 " the buffer it was created from " << endl
00132 << " buffer size is " << bufsize << " record size is supposedly "
00133 << nbytes << endl;
00134 ad_exit(1);
00135 }
00136
00137 ret = ::read(fp,buffer,nbytes);
00138 assert(ret != -1);
00139
00140
00141
00142 lseek(fp,(off_t)sizeof(off_t),SEEK_CUR);
00143 }
00144 }
00145
00150 void fixed_smartlist2::initialize(void)
00151 {
00152 end_saved=0;
00153 eof_flag=0;
00154 bptr=buffer;
00155
00156 written_flag=0;
00157 lseek(fp,0L,SEEK_SET);
00158 set_forward();
00159 }
00160
00165 void fixed_smartlist2::check_buffer_size(const size_t nsize)
00166 {
00167 if ( bptr+nsize-1 > buffend)
00168 {
00169 if (df1b2variable::get_passnumber()==2 && !noreadflag )
00170 {
00171 read_buffer();
00172 }
00173 else
00174 {
00175 if (nsize>bufsize)
00176 {
00177 cout << "Need to increase buffsize in list" << endl;
00178 exit(1);
00179 }
00180 write_buffer();
00181 }
00182 }
00183 }
00187 void fixed_smartlist2::restore_end()
00188 {
00189 if (written_flag)
00190 {
00191 if (end_saved)
00192 {
00193 #ifdef OPT_LIB
00194 lseek(fp, endof_file_ptr, SEEK_SET);
00195 #else
00196 off_t ret = lseek(fp, endof_file_ptr, SEEK_SET);
00197 assert(ret >= 0);
00198 #endif
00199 read_buffer();
00200 set_recend();
00201 }
00202 }
00203 }
00204
00209 void fixed_smartlist2::save_end(void)
00210 {
00211 if (written_flag)
00212 {
00213 if (!end_saved)
00214 {
00215 write_buffer_one_less();
00216 end_saved=1;
00217 }
00218 }
00219 }
00220
00225 void fixed_smartlist2::write_buffer_one_less(void)
00226 {
00227 int _nbytes=adptr_diff(bptr,buffer);
00228 if (_nbytes > 0)
00229 {
00230 unsigned int nbytes = (unsigned int)_nbytes;
00231
00232 written_flag=1;
00233
00234 off_t pos=lseek(fp,0L,SEEK_CUR);
00235
00236
00237 ssize_t ret = ::write(fp,&nbytes,sizeof(unsigned int));
00238 assert(ret != -1);
00239
00240
00241 ssize_t nw = ::write(fp,buffer,nbytes);
00242 if (nw < _nbytes)
00243 {
00244 cerr << "Error writing to file " << filename << endl;
00245 ad_exit(1);
00246 }
00247
00248 bptr=buffer;
00249
00250
00251
00252 ret = ::write(fp,&pos,sizeof(off_t));
00253 assert(ret != -1);
00254
00255 endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00256
00257
00258 }
00259 }
00260
00265 void fixed_smartlist2::write_buffer(void)
00266 {
00267 int _nbytes=adptr_diff(bptr+1,buffer);
00268 if (_nbytes > 0)
00269 {
00270 unsigned int nbytes = (unsigned int)_nbytes;
00271
00272 written_flag=1;
00273
00274 off_t pos=lseek(fp,0L,SEEK_CUR);
00275
00276
00277 ssize_t ret = ::write(fp, &nbytes, sizeof(unsigned int));
00278 assert(ret != -1);
00279
00280
00281 ret = ::write(fp,buffer,nbytes);
00282 assert(ret != -1);
00283 if (ret < _nbytes)
00284 {
00285 cerr << "Error writing to file " << filename << endl;
00286 ad_exit(1);
00287 }
00288
00289 bptr=buffer;
00290
00291
00292
00293 ret = ::write(fp,&pos,sizeof(off_t));
00294 assert(ret != -1);
00295
00296 endof_file_ptr=lseek(fp,0L,SEEK_CUR);
00297
00298
00299 }
00300 }
00301
00305 void fixed_smartlist2::read_buffer(void)
00306 {
00307 if (!written_flag)
00308 {
00309 if (direction ==-1)
00310 eof_flag=-1;
00311 else
00312 eof_flag=1;
00313 }
00314 else
00315 {
00316 off_t pos = 0;
00317 if (direction ==-1)
00318 {
00319 off_t ipos=lseek(fp,0L,SEEK_CUR);
00320 if (ipos ==0)
00321 {
00322 eof_flag=-1;
00323 return;
00324 }
00325
00326
00327 #ifdef OPT_LIB
00328 lseek(fp,-((off_t)sizeof(off_t)),SEEK_CUR);
00329 #else
00330 off_t ret2 = lseek(fp,-((off_t)sizeof(off_t)),SEEK_CUR);
00331 assert(ret2 >= 0);
00332 #endif
00333 ssize_t ret = read(fp,&pos,sizeof(off_t));
00334 assert(ret != -1);
00335
00336
00337 #ifdef OPT_LIB
00338 lseek(fp,pos,SEEK_SET);
00339 #else
00340 ret2 = lseek(fp,pos,SEEK_SET);
00341 assert(ret2 >= 0);
00342 #endif
00343
00344 }
00345
00346 int _nbytes = 0;
00347 ssize_t ret = ::read(fp,&_nbytes,sizeof(int));
00348 assert(ret != -1);
00349 if (_nbytes > 0)
00350 {
00351 const size_t nbytes = (size_t)_nbytes;
00352 if (nbytes > bufsize)
00353 {
00354 cerr << "Error -- record size in file seems to be larger than"
00355 " the buffer it was created from " << endl
00356 << " buffer size is " << bufsize << " record size is supposedly "
00357 << nbytes << endl;
00358 ad_exit(1);
00359 }
00360
00361 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00362 ssize_t nr = ::read(fp,buffer,_nbytes);
00363 #else
00364 ssize_t nr = ::read(fp,buffer,nbytes);
00365 #endif
00366 assert(nr != -1);
00367 if (nr != _nbytes)
00368 {
00369 cerr << "Error: read only " << nr << " of " << nbytes << "bytes.\n";
00370 exit(1);
00371 }
00372
00373 bptr=buffer;
00374 size_t ns = nbytes / sizeof(int);
00375 recend=bptr+ns-1;
00376
00377
00378 if (direction ==-1)
00379 {
00380
00381 #ifdef OPT_LIB
00382 lseek(fp,pos,SEEK_SET);
00383 #else
00384 off_t ret = lseek(fp,pos,SEEK_SET);
00385 assert(ret >= 0);
00386 #endif
00387
00388 }
00389 else
00390 {
00391
00392
00393
00394 #ifdef OPT_LIB
00395 lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
00396 #else
00397 off_t ret = lseek(fp, (off_t)sizeof(off_t), SEEK_CUR);
00398 assert(ret >= 0);
00399 #endif
00400 }
00401 }
00402 }
00403 }
00404
00409 void memcpy(const fixed_smartlist2 & _list,void * p, const size_t nsize)
00410 {
00411 ADUNCONST(fixed_smartlist2,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(list.bptr,p,nsize);
00418 list.bptr+=nsize;
00419 }
00420
00425 void memcpy(void * p,const fixed_smartlist2 & _list, const size_t nsize)
00426 {
00427 ADUNCONST(fixed_smartlist2,list)
00428 if ( list.bptr+nsize-1 > list.buffend)
00429 {
00430 cerr << " Trying to write outside list buffer" << endl;
00431 exit(1);
00432 }
00433 memcpy(p,list.bptr,nsize);
00434 list.bptr+=nsize;
00435 }
00436
00441 void fixed_smartlist2::operator -= (int n)
00442 {
00443 if (bptr-n<buffer)
00444 {
00445 if (bptr != buffer)
00446 {
00447 cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00448 exit(1);
00449 }
00450 else
00451 {
00452
00453 read_buffer();
00454 bptr=recend-n+1;
00455 }
00456 }
00457 else
00458 {
00459 bptr-=n;
00460 }
00461 }
00462
00467 void fixed_smartlist2::operator -- (void)
00468 {
00469 if (bptr-1<buffer)
00470 {
00471 if (bptr != buffer)
00472 {
00473 cerr << " Sanity error in fixed_smartlist2::operator -= (int)" << endl;
00474 exit(1);
00475 }
00476 else
00477 {
00478
00479 read_buffer();
00480
00481 bptr=recend;
00482 }
00483 }
00484 else
00485 {
00486 bptr--;
00487 }
00488 }
00489
00494 void fixed_smartlist2::operator += (int nsize)
00495 {
00496 if ( bptr+nsize-1 > buffend)
00497 {
00498 if (df1b2variable::get_passnumber()==2 && !noreadflag )
00499 {
00500 read_buffer();
00501 }
00502 else
00503 {
00504 if ((unsigned int)nsize>bufsize)
00505 {
00506 cout << "Need to increase buffsize in list" << endl;
00507 exit(1);
00508 }
00509 write_buffer();
00510 }
00511 }
00512 else
00513 {
00514 bptr+=nsize;
00515 }
00516 }
00517
00522 void fixed_smartlist2::operator ++ (void)
00523 {
00524 if ( bptr==buffend)
00525 {
00526 if (df1b2variable::get_passnumber()==2 && !noreadflag )
00527 {
00528 read_buffer();
00529 }
00530 else
00531 {
00532 write_buffer();
00533 }
00534 }
00535 else
00536 {
00537 bptr++;
00538 }
00539 }
00540
00544 void fixed_smartlist2::read_file(void)
00545 {
00546
00547 off_t pos=lseek(fp,0L,SEEK_SET);
00548 char buffer[50000];
00549 int offset=0;
00550 fixed_list_entry * b= (fixed_list_entry*) &(buffer[0]);
00551 cout << b << endl;
00552 ssize_t nw = 0;
00553 do
00554 {
00555 int nbytes = 0;
00556 nw = ::read(fp,&nbytes,sizeof(int));
00557 if (nw != -1)
00558 {
00559 nw = ::read(fp, buffer + offset, (size_t)nbytes);
00560 if (nw != -1)
00561 {
00562 offset+=nbytes;
00563 nw = ::read(fp,&pos,sizeof(off_t));
00564 }
00565 }
00566 }
00567 while(nw);
00568 }