SDSL: Succinct Data Structure Library
A C++ template library for succinct data structures
|
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