00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #ifndef __VVECOTOR_H__
00147 #define __VVECOTOR_H__
00148 #include "ecell_config.h"
00149 #include <sys/types.h>
00150 #if defined(__GNUC__) || defined(_MSC_VER)
00151 #include <vector>
00152 #else
00153 #include <vector.h>
00154 #endif
00155
00156
00157 #if defined(__BORLANDC__) || defined(_MSC_VER)
00158 typedef int ssize_t;
00159 #endif
00160
00161
00162 #include <string.h>
00163 #include <memory.h>
00164 #include <stdio.h>
00165 #include <assert.h>
00166 #include <errno.h>
00167 #if defined(__BORLANDC__) || defined(_MSC_VER)
00168 #include <io.h>
00169 #elif defined(__linux__) && !defined(__powerpc__)
00170 #include <unistd.h>
00171 #include <sys/io.h>
00172 #else
00173 #include <unistd.h>
00174 #endif
00175
00176 #include "Exceptions.hpp"
00177
00178 #define OPEN_WHEN_ACCESS
00179
00180 const unsigned int VVECTOR_READ_CACHE_SIZE = 2048;
00181 const unsigned int VVECTOR_WRITE_CACHE_SIZE = 2048;
00182 const unsigned int VVECTOR_READ_CACHE_INDEX_SIZE = 2;
00183 const unsigned int VVECTOR_WRITE_CACHE_INDEX_SIZE = 2;
00184
00185 class vvector_full : public std::exception {
00186 public:
00187
00188 virtual char const* what() throw()
00189 {
00190 return "Total disk space or allocated space is full.\n";
00191 }
00192 };
00193
00194 class vvector_write_error : public std::exception {
00195 public:
00196
00197 virtual char const* what() throw()
00198 {
00199 return "I/O error while attempting to write on disk.\n";
00200 }
00201 };
00202
00203 class vvector_read_error : public std::exception {
00204 public:
00205
00206 virtual char const* what() throw()
00207 {
00208 return "I/O error while attempting to read from disk.\n";
00209 }
00210 };
00211
00212
00213 class vvector_init_error : public std::exception {
00214 public:
00215
00216 virtual char const* what() throw()
00217 {
00218 return "VVector initialization error.\n";
00219 }
00220 };
00221
00222 class vvectorbase {
00223
00224 public:
00225 typedef void (*cbfp_t)();
00226
00227 private:
00228 static int _serialNumber;
00229 static char const *_defaultDirectory;
00230 static int _directoryPriority;
00231
00232 static std::vector<char const *> _tmp_name;
00233 static std::vector<int> _file_desc_read;
00234 static std::vector<int> _file_desc_write;
00235
00236 static bool _atexitSet;
00237 static cbfp_t _cb_full;
00238 static cbfp_t _cb_error;
00239 static long _margin;
00240
00241
00242 protected:
00243 int _myNumber;
00244 char *_file_name;
00245 int _fdr,_fdw;
00246 void unlinkfile();
00247
00248
00249 void initBase(char const * const dirname);
00250 void my_open_to_append();
00251 void my_open_to_read(off_t offset);
00252 void my_close_read();
00253 void my_close_write();
00254
00255
00256 public:
00257 vvectorbase();
00258 ~vvectorbase();
00259
00260
00261 static void setTmpDir(char const * const dirname, int);
00262 static void removeTmpFile();
00263 static void setCBFull(cbfp_t __c) { _cb_full = __c; };
00264 static void cbFull();
00265 static void margin(long __m) { _margin = __m; };
00266 };
00267
00268
00269 template<class T> class vvector : public vvectorbase {
00270
00271 public:
00272 typedef T value_type;
00273 typedef size_t size_type;
00274
00275
00276 private:
00277 size_type _size;
00278 value_type _buf;
00279 value_type _cacheRV[VVECTOR_READ_CACHE_SIZE];
00280 size_type _cacheRI[VVECTOR_READ_CACHE_INDEX_SIZE];
00281 value_type _cacheWV[VVECTOR_WRITE_CACHE_SIZE];
00282 size_type _cacheWI[VVECTOR_WRITE_CACHE_INDEX_SIZE];
00283 size_type _cacheWNum;
00284 bool size_fixed;
00285 int end_policy;
00286 size_type max_size;
00287 size_type start_offset;
00288
00289
00290 libecs::Real LastTime, diff, lastRead;
00291
00292
00293 public:
00294 vvector();
00295 ~vvector();
00296
00297
00298 public:
00299 void push_back(const value_type & x);
00300 value_type const & operator [] (size_type i);
00301 value_type const & at(size_type i);
00302 size_type size() const { return _size; };
00303 void clear();
00304 static void setDiskFullCB(void(*)());
00305 void setEndPolicy( int );
00306 int getEndPolicy();
00307 void setMaxSize( int aMaxSize );
00308 };
00309
00310
00311
00312
00313
00314
00315
00316 template<class T> vvector<T>::vvector()
00317 {
00318 size_fixed = false;
00319 end_policy = 0;
00320 max_size = 0;
00321 start_offset = 0;
00322 initBase(NULL);
00323 int counter = VVECTOR_READ_CACHE_INDEX_SIZE;
00324 do {
00325 _cacheRI[counter] = -1;
00326 } while (0 <= --counter);
00327 counter = VVECTOR_WRITE_CACHE_INDEX_SIZE;
00328 do {
00329 _cacheWI[counter] = -1;
00330 } while (0 <= --counter);
00331 _cacheWNum = 0;
00332 _size = 0;
00333 }
00334
00335
00336 template<class T> vvector<T>::~vvector()
00337 {
00338
00339 }
00340
00341 template<class T> void vvector<T>::setEndPolicy( int anEndPolicy)
00342 {
00343 end_policy=anEndPolicy;
00344 }
00345
00346 template<class T> int vvector<T>::getEndPolicy()
00347 {
00348 return end_policy;
00349 }
00350
00351 template<class T> void vvector<T>::setMaxSize( int aMaxSize )
00352 {
00353 if (aMaxSize == 0) {
00354 max_size = 0;
00355 }
00356 else{
00357 max_size = ((aMaxSize/VVECTOR_WRITE_CACHE_SIZE)+1)*VVECTOR_WRITE_CACHE_SIZE;
00358 }
00359 }
00360
00361 template<class T> void vvector<T>::push_back(const T & x)
00362 {
00363 ssize_t red_bytes;
00364 bool write_successful;
00365 if(VVECTOR_WRITE_CACHE_SIZE <= _cacheWNum)
00366 {
00367 throw vvector_write_error();
00368 }
00369
00370 _cacheWV[_cacheWNum] = x;
00371 if (_cacheWNum==0)
00372 {
00373 _cacheWI[0]=_size;
00374 }
00375 _cacheWI[1] = _size;
00376 if (size_fixed)
00377 {
00378 _cacheWI[0]--;
00379 }
00380 else
00381 {
00382 _size++;
00383 }
00384 _cacheWNum++;
00385
00386 if ( VVECTOR_WRITE_CACHE_SIZE <= _cacheWNum )
00387 {
00388
00389 if (!size_fixed)
00390 {
00391 #ifdef OPEN_WHEN_ACCESS
00392 my_open_to_append();
00393 #endif
00394 #ifndef _MSC_VER
00395 red_bytes = write( _fdw, _cacheWV, sizeof(T) * VVECTOR_WRITE_CACHE_SIZE );
00396 #else
00397 red_bytes = _write( _fdw, _cacheWV, sizeof(T) * VVECTOR_WRITE_CACHE_SIZE );
00398 #endif
00399 #ifdef OPEN_WHEN_ACCESS
00400 my_close_write();
00401 #endif
00402
00403 write_successful = ( red_bytes == sizeof(T) * VVECTOR_WRITE_CACHE_SIZE );
00404 if ( (!write_successful ) || ( _size == max_size ) )
00405 {
00406 if (end_policy == 0)
00407 {
00408 if (_size>0)
00409 {
00410 throw vvector_full();
00411 }
00412 else{
00413 throw vvector_write_error();
00414 }
00415 }
00416 else
00417 {
00418 size_fixed=true;
00419 if ( !write_successful )
00420 {
00421 _size-=VVECTOR_WRITE_CACHE_SIZE;
00422 }
00423
00424 }
00425 }
00426 }
00427
00428 if (size_fixed){
00429
00430 #ifdef OPEN_WHEN_ACCESS
00431 my_open_to_append();
00432 #endif
00433
00434 #ifndef _MSC_VER
00435 if (lseek(_fdw, static_cast<off_t>((start_offset) * sizeof(T)), SEEK_SET) == static_cast<off_t>(-1))
00436 #else
00437 if (_lseeki64(_fdw, static_cast<off_t>((start_offset) * sizeof(T)), SEEK_SET) == static_cast<off_t>(-1))
00438 #endif
00439 {
00440 my_close_write();
00441 throw vvector_write_error();
00442 }
00443
00444 #ifndef _MSC_VER
00445 red_bytes = write(_fdw, _cacheWV, sizeof(T) * VVECTOR_WRITE_CACHE_SIZE);
00446 #else
00447 red_bytes = _write(_fdw, _cacheWV, sizeof(T) * VVECTOR_WRITE_CACHE_SIZE);
00448 #endif
00449 #ifdef OPEN_WHEN_ACCESS
00450 my_close_write();
00451 #endif
00452
00453 if ( red_bytes != sizeof(T) * VVECTOR_WRITE_CACHE_SIZE)
00454 {
00455 throw vvector_write_error();
00456 }
00457 start_offset += VVECTOR_WRITE_CACHE_SIZE;
00458 if (start_offset >= _size)
00459 {
00460 start_offset -= _size;
00461 }
00462
00463
00464 }
00465 _cacheWNum = 0;
00466
00467 }
00468 }
00469
00470
00471 template<class T> T const & vvector<T>::operator [] (size_type i)
00472 {
00473 return at(i);
00474 }
00475
00476
00477 template<class T> T const & vvector<T>::at(size_type i)
00478 {
00479
00480 assert(i < _size);
00481
00482 if (!size_fixed){
00483 if (( i >= _cacheRI[0])&&(_cacheRI[1]>=i)){
00484
00485 return _cacheRV[i-_cacheRI[0]];
00486 }
00487 }
00488
00489 if ((i>=_cacheWI[0])&&(_cacheWI[1]>=i)){
00490
00491
00492 return _cacheWV[i-_cacheWI[0]];
00493 }
00494 size_type i2=i;
00495 size_type log_read_start, phys_read_start;
00496 size_t half_size,read_interval;
00497 read_interval=VVECTOR_READ_CACHE_SIZE;
00498
00499
00500 if (!size_fixed){
00501 if ((i+1)==_cacheRI[0])
00502 {
00503 if (_cacheRI[0]>=read_interval)
00504 {
00505 i2=_cacheRI[0]-read_interval;
00506 }
00507 else
00508 {
00509 i2=0;
00510 }
00511 }
00512 else if((_cacheRI[1]+1)!=i){
00513 half_size=read_interval/2;
00514 if (i>half_size){i2=(i-half_size);} else {i2=0;}
00515 }
00516 }
00517 ssize_t num_red;
00518 size_type num_to_read = _size - i2 ;
00519 if (VVECTOR_READ_CACHE_SIZE < num_to_read) {
00520 num_to_read = VVECTOR_READ_CACHE_SIZE;
00521 }
00522 log_read_start=i2;
00523 if (size_fixed){
00524 phys_read_start=(i2+start_offset+_cacheWNum);
00525 if (phys_read_start>=_size){ phys_read_start-=_size;}
00526 }
00527 else{
00528 phys_read_start=i2;
00529 }
00530 #ifdef OPEN_WHEN_ACCESS
00531 my_open_to_read( off_t( phys_read_start * sizeof(T) ));
00532 #endif
00533 #ifndef _MSC_VER
00534 num_red = read(_fdr, _cacheRV, num_to_read * sizeof(T));
00535 #else
00536 num_red = _read(_fdr, _cacheRV, static_cast<unsigned int>(num_to_read * sizeof(T)));
00537 #endif
00538 #ifdef OPEN_WHEN_ACCESS
00539 my_close_read();
00540 #endif
00541 if (num_red < 0) {
00542 throw vvector_read_error();
00543
00544 }
00545 num_red /= sizeof(T);
00546 _cacheRI[0]=log_read_start;
00547 _cacheRI[1]=log_read_start+num_red-1;
00548
00549 _buf = _cacheRV[i-log_read_start];
00550 return _buf;
00551 }
00552
00553
00554 template<class T> void vvector<T>::clear()
00555 {
00556 unlinkfile();
00557 }
00558
00559
00560 #endif