Disk ARchive 2.4.2
cache.hpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines