libmoost
/home/mhx/git/github/libmoost/include/moost/io/variable_store.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_IO_VARIABLE_STORE_HPP__
00029 #define MOOST_IO_VARIABLE_STORE_HPP__
00030 
00031 #include <cmath>
00032 #include <string>
00033 #include <fstream>
00034 #include <stdexcept>
00035 
00036 #include <boost/filesystem/path.hpp>
00037 #include <boost/filesystem/operations.hpp>
00038 #include <boost/lexical_cast.hpp>
00039 
00040 #include <boost/scoped_array.hpp>
00041 #include <boost/scoped_ptr.hpp>
00042 
00043 #include "block_store.hpp"
00044 
00045 namespace moost { namespace io {
00046 
00049 class variable_store
00050 {
00051 private:
00052 
00053   size_t m_min_block_size;
00054   size_t m_max_block_size;
00055   boost::scoped_array< boost::scoped_ptr< block_store > > m_block_stores;
00056 
00057   size_t index_from_size(size_t block_size)
00058   {
00059     if (block_size < m_min_block_size)
00060       block_size = m_min_block_size;
00061     else if ( block_size > m_max_block_size )
00062       throw std::invalid_argument("cannot exceed max block size");
00063     return static_cast<size_t>( log( static_cast<double>(( block_size * 2 - 1) / m_min_block_size) ) / log(2.0) );
00064   }
00065 
00066 public:
00067 
00069   class scoped_block
00070   {
00071   private:
00072     block_store::scoped_block m_scoped_block;
00073   public:
00074     scoped_block(variable_store & variable_store_,
00075                  size_t block_size)
00076     : m_scoped_block( * variable_store_.m_block_stores[variable_store_.index_from_size(block_size)])
00077     {
00078     }
00079     scoped_block(variable_store & variable_store_,
00080                  size_t block_size,
00081                  size_t index)
00082     : m_scoped_block( * variable_store_.m_block_stores[variable_store_.index_from_size(block_size)], index)
00083     {
00084     }
00085     void free() { m_scoped_block.free(); }
00086     std::fstream & operator * () { return m_scoped_block.operator* (); }
00087     std::fstream * operator ->() { return m_scoped_block.operator->(); }
00088     size_t index()               { return m_scoped_block.index(); }
00089     size_t block_size()          { return m_scoped_block.block_size(); }
00090   };
00091 
00094   variable_store(const std::string & base_path,
00095                  size_t min_block_size = 64,
00096                  size_t max_block_size = 16777216,
00097                  size_t streams_per_block_size = 8)
00098   : m_min_block_size(min_block_size),
00099     m_max_block_size(max_block_size),
00100     m_block_stores( new boost::scoped_ptr< block_store >[1 + index_from_size(m_max_block_size) ] )
00101   {
00102     for (int i = 0; min_block_size <= max_block_size; min_block_size *= 2, ++i)
00103     {
00104       boost::filesystem::path p = boost::filesystem::path(base_path) / boost::filesystem::path(boost::lexical_cast<std::string>(min_block_size));
00105       m_block_stores[i].reset(new block_store(p.string(), min_block_size, streams_per_block_size));
00106     }
00107   }
00108 };
00109 
00110 }} // moost::io
00111 
00112 #endif // MOOST_IO_VARIABLE_STORE_HPP__