SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
 All Classes Namespaces Files Functions Variables Typedefs Friends
sdsl/include/sdsl/temp_write_read_buffer.hpp
Go to the documentation of this file.
00001 
00005 #ifndef INCLUDED_SDSL_TEMP_WRITE_READ_BUFFER
00006 #define INCLUDED_SDSL_TEMP_WRITE_READ_BUFFER
00007 #include "int_vector.hpp"
00008 #include <string>
00009 #include <fstream>
00010 
00011 namespace sdsl
00012 {
00013 
00014 
00015 
00019 template<uint8_t int_width=0>
00020 class temp_write_read_buffer
00021 {
00022     public:
00023         typedef int_vector<int_width> buffer_type;
00024         typedef typename buffer_type::size_type size_type;
00025         typedef typename buffer_type::value_type value_type;
00026 
00027     private:
00028 
00029         buffer_type             m_buf; // buffer for the data
00030         size_type               m_buf_size; // size of the buffer
00031         std::string             m_file_name; // filename for the file holding
00032         // the data which does not fit in the buffer
00033         size_type                       m_in_buf_idx;// current index in the buffer
00034         size_type                       m_buf_idx;// index of the current buffer
00035         size_type                       m_buf_cnt;// number of buffers written to disk
00036         std::ofstream           m_out;           // file out stream
00037         std::ifstream           m_in;            // file in stream
00038         bool                            m_output_exists; // if there exists output to the file
00039         size_type                       m_r;// remaining entries in the buffer
00040         size_type                       m_last_block_size; // size of the last block written to disk
00041         static size_t           m_buffer_id;
00042 
00043     public:
00044 
00046 
00050         temp_write_read_buffer(size_type buf_size, uint8_t width, std::string dir="./") {
00051             m_buf_size = buf_size;
00052             m_buf = buffer_type(buf_size, 0, width);    // initialize buffer
00053             m_in_buf_idx = 0;
00054             m_buf_cnt = 0;
00055             m_file_name =  dir + "temp_write_read_buffer_" + util::to_string(util::get_pid())+"_"
00056                            + util::to_string(util::get_id())+"_"
00057                            + util::to_string(m_buffer_id);
00058             m_buffer_id++; // increase the object counter
00059             m_output_exists = false;
00060         }
00061 
00062         // Destructor
00063         ~temp_write_read_buffer() {
00064             if (m_out.is_open()) { // if out buffer is still open
00065                 m_out.close();     // close it
00066             }
00067             if (m_in.is_open()) { // if in buffer is still open
00068                 m_in.close();     // close it
00069             }
00070             if (m_output_exists)  // if we have written output to a file
00071                 std::remove(m_file_name.c_str());   // delete it
00072         }
00073 
00074         value_type operator<<(value_type x) {
00075             if (m_in_buf_idx == m_buf_size) {
00076                 m_in_buf_idx = 0;
00077                 ++m_buf_cnt; ++m_buf_idx; // increase the number of buffers written to disk; increase the number of the current buffer
00078                 if (m_buf_cnt == 1) {
00079                     m_out.open(m_file_name.c_str(), std::ios::trunc | std::ios::out | std::ios::binary);   // open file buffer
00080                 }
00081                 m_buf.serialize(m_out);   // write buffer to disk
00082                 m_output_exists = true;
00083             }
00084             m_buf[m_in_buf_idx++] = x;
00085             return x;
00086         }
00087 
00088         void write_close() {
00089             if (m_buf_cnt > 0) {
00090                 m_buf.serialize(m_out);    // write last buffer to disk
00091                 m_out.close(); // close stream
00092                 m_last_block_size = m_in_buf_idx;
00093                 ++m_buf_cnt;
00094                 m_out.close();
00095                 m_r = 0;
00096                 m_in.open(m_file_name.c_str(), std::ios::in | std::ios::binary);
00097             } else {
00098                 m_r = m_in_buf_idx;
00099                 m_last_block_size = 0;
00100             }
00101             m_in_buf_idx = 0;
00102             m_buf_idx = 0;
00103         }
00104 
00105         void reset() {
00106             m_in_buf_idx = 0;
00107             m_buf_cnt = 0;
00108             if (m_out.is_open()) {
00109                 m_out.close();
00110             }
00111             if (m_in.is_open()) {
00112                 m_in.close();
00113             }
00114         }
00115 
00116         bool operator>>(value_type& x) {
00117             if (m_in_buf_idx >= m_r) {  // load next buffer
00118 //                      std::cout<< "m_in_buf_idx = " << m_in_buf_idx << " m_r "<< m_r <<" m_buf_idx = "<< m_buf_idx<<" m_buf_cnt = "<< m_buf_cnt << std::endl;
00119                 if (m_buf_idx < m_buf_cnt) {
00120                     ++m_buf_idx; // increase buffer index
00121                     m_in_buf_idx = 0; // reset in buffer index
00122                     m_buf.load(m_in);   // load next block
00123                     if (m_buf_idx == m_buf_cnt)
00124                         m_r = m_last_block_size;
00125                     else
00126                         m_r = m_buf_size;
00127                 } else {
00128                     x = 0;
00129                     return false;
00130                 }
00131             }
00132             x = m_buf[ m_in_buf_idx++ ];
00133             return true;
00134         }
00135 };
00136 
00137 template<uint8_t int_width>
00138 size_t temp_write_read_buffer<int_width>::m_buffer_id = 0;
00139 
00140 } // end namespace sdsl
00141 
00142 #endif
00143 
00144