Disk ARchive 2.4.2
|
00001 /*********************************************************************/ 00002 // dar - disk archive - a backup/restoration program 00003 // Copyright (C) 2002-2052 Denis Corbin 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 // 00019 // to contact the author : http://dar.linux.free.fr/email.html 00020 /*********************************************************************/ 00021 // $Id: cache.hpp,v 1.26 2011/04/17 13:12:29 edrusb Rel $ 00022 // 00023 /*********************************************************************/ 00024 00028 00029 #ifndef CACHE_HPP 00030 #define CACHE_HPP 00031 00032 #include "../my_config.h" 00033 #include "infinint.hpp" 00034 #include "generic_file.hpp" 00035 00036 namespace libdar 00037 { 00038 00041 00043 00053 class cache : public generic_file 00054 { 00055 public: 00056 cache(generic_file & hidden, //< is the file to cache, it is never deleted by the cache object, 00057 bool shift_mode, //< if true, when all cached data has been read, half of the data is flushed from the cache, the other half is shifted and new data take place to fill the cache. This is necessary for sequential reading, but has some CPU overhead. 00058 U_I initial_size = 10240, //< is the initial size of the cache for reading (read this amount of data at a time) 00059 U_I unused_read_ratio = 10, //< is the ratio of cached data effectively asked for reading below which the cache size is divided by two in other words, if during observation_read_number fullfilment of the cache, less than unused_read_ratio percent of data has been effectively asked for reading, then the cache size is divided by two 00060 U_I observation_read_number = 100, //< period of cache size consideration 00061 U_I max_size_hit_read_ratio = 50, //< is the ratio above which the cache size is doubled. In other words, if during observation_read_number times of cache fullfilment, more than max_size_hit_read_ratio percent time all the cached data has been asked for reading the cache size is doubled. To have fixed size read caching, you can set unused_read_ratio to zero and max_size_hit_read_ratio to 101 or above. 00062 U_I unused_write_ratio = 10, //< same as unused_read_ratio but for writing operations 00063 U_I observation_write_number = 100, //< same as observation_read_number but for writing operations 00064 U_I max_size_hit_write_ratio = 50); //< same as max_size_hit_read_ratio but for writing operations 00065 00066 ~cache(); 00067 00068 00069 // inherited from generic_file 00070 bool skip(const infinint & pos); 00071 bool skip_to_eof(); 00072 bool skip_relative(S_I x); 00073 infinint get_position() { return current_position; }; 00074 00075 protected: 00076 // inherited from generic_file 00077 U_I inherited_read(char *a, U_I size); 00078 void inherited_write(const char *a, U_I size); 00079 void inherited_sync_write() { flush_write(); }; 00080 void inherited_terminate() { flush_write(); }; 00081 private: 00082 struct buf 00083 { 00084 char *buffer; 00085 U_I size; // allocated size 00086 U_I next; // next to read or next place to write to 00087 U_I last; // first to not read in the cache 00088 00089 buf() { buffer = NULL; size = next = last = 0; }; 00090 buf(const buf &ref) { throw SRC_BUG; }; 00091 ~buf() { if(buffer != NULL) delete [] buffer; }; 00092 void resize(U_I newsize); 00093 void shift_by_half(); 00094 void clear() { next = last = 0; }; 00095 }; 00096 00097 generic_file *ref; //< underlying file, (not owned by "this', not to be delete by "this") 00098 00099 struct buf buffer_cache; //< where is stored cached data 00100 infinint current_position; //< current offset in file to read from or write to 00101 bool read_mode; //< true if in read mode, false if in write mode 00102 bool shifted_mode; //< whether to half flush and shift or totally flush data 00103 bool failed_increase; //< whether we failed increasing the cache size 00104 00105 U_I read_obs; 00106 U_I read_unused_rate; 00107 U_I read_overused_rate; 00108 00109 U_I write_obs; 00110 U_I write_unused_rate; 00111 U_I write_overused_rate; 00112 00113 U_I stat_read_unused; 00114 U_I stat_read_overused; 00115 U_I stat_read_counter; 00116 00117 U_I stat_write_overused; 00118 U_I stat_write_counter; 00119 00120 void flush_write(); 00121 void fulfill_read(); 00122 void clear_read() { if(read_mode) buffer_cache.clear(); }; 00123 }; 00124 00126 00127 } // end of namespace 00128 00129 #endif 00130