Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * containers/write_vector.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2006 Roman Dementiev <dementiev@ira.uka.de> 00007 * 00008 * Distributed under the Boost Software License, Version 1.0. 00009 * (See accompanying file LICENSE_1_0.txt or copy at 00010 * http://www.boost.org/LICENSE_1_0.txt) 00011 **************************************************************************/ 00012 00013 #include <stxxl/io> 00014 #include <stxxl/vector> 00015 #include <stxxl/bits/mng/buf_ostream.h> 00016 00017 // efficiently writes data into an stxxl::vector with overlapping of I/O and 00018 // computation 00019 template <class VectorType> 00020 class write_vector 00021 { 00022 typedef VectorType vector_type; 00023 typedef typename vector_type::size_type size_type; 00024 typedef typename vector_type::value_type value_type; 00025 typedef typename vector_type::block_type block_type; 00026 typedef typename vector_type::iterator ExtIterator; 00027 typedef typename vector_type::const_iterator ConstExtIterator; 00028 typedef stxxl::buf_ostream<block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type; 00029 00030 vector_type & Vec; 00031 size_type RealSize; 00032 unsigned nbuffers; 00033 buf_ostream_type * outstream; 00034 00035 public: 00036 write_vector(vector_type & Vec_, 00037 unsigned nbuffers_ // buffers to use for overlapping (>=2 recommended) 00038 ) : Vec(Vec_), RealSize(0), nbuffers(nbuffers_) 00039 { 00040 assert(Vec.empty()); // precondition: Vec is empty 00041 Vec.resize(2 * block_type::size); 00042 outstream = new buf_ostream_type(Vec.begin().bid(), nbuffers); 00043 } 00044 00045 void push_back(const value_type & val) 00046 { 00047 ++RealSize; 00048 if (Vec.size() < RealSize) 00049 { 00050 // double the size of the array 00051 delete outstream; // flush overlap buffers 00052 Vec.resize(2 * Vec.size()); 00053 outstream = new buf_ostream_type((Vec.begin() + RealSize - 1).bid(), nbuffers); 00054 } 00055 ExtIterator it = Vec.begin() + RealSize - 1; 00056 if (it.block_offset() == 0) 00057 it.block_externally_updated(); 00058 // tells the vector that the block was modified) 00059 **outstream = val; 00060 ++(*outstream); 00061 } 00062 00063 void finish() 00064 { 00065 ExtIterator out = Vec.begin() + RealSize; 00066 ConstExtIterator const_out = out; 00067 00068 while (const_out.block_offset()) 00069 { 00070 **outstream = *const_out; // might cause I/Os for loading the page that 00071 ++const_out; // contains data beyond out 00072 ++(*outstream); 00073 } 00074 00075 out.flush(); 00076 delete outstream; 00077 outstream = NULL; 00078 Vec.resize(RealSize); 00079 } 00080 00081 virtual ~write_vector() 00082 { 00083 if (outstream) 00084 finish(); 00085 } 00086 }; 00087 00088 typedef unsigned char my_type; 00089 00090 // copies a file to another file 00091 00092 using stxxl::syscall_file; 00093 using stxxl::file; 00094 00095 int main(int argc, char * argv[]) 00096 { 00097 if (argc < 3) 00098 { 00099 std::cout << "Usage: " << argv[0] << " input_file output_file " << std::endl; 00100 return -1; 00101 } 00102 00103 unlink(argv[2]); // delete output file 00104 00105 syscall_file InputFile(argv[1], file::RDONLY); // Input file object 00106 syscall_file OutputFile(argv[2], file::RDWR | file::CREAT); // Output file object 00107 00108 typedef stxxl::vector<my_type> vector_type; 00109 00110 std::cout << "Copying file " << argv[1] << " to " << argv[2] << std::endl; 00111 00112 vector_type InputVector(&InputFile); // InputVector is mapped to InputFile 00113 vector_type OutputVector(&OutputFile); // OutputVector is mapped to OutputFile 00114 00115 std::cout << "File " << argv[1] << " has size " << InputVector.size() << " bytes." << std::endl; 00116 00117 vector_type::const_iterator it = InputVector.begin(); // creating const iterator 00118 00119 write_vector<vector_type> Writer(OutputVector, 6); 00120 00121 for ( ; it != InputVector.end(); ++it) // iterate through InputVector 00122 { 00123 Writer.push_back(*it); // add the value pointed by 'it' to OutputVector 00124 } 00125 Writer.finish(); // flush buffers 00126 00127 00128 return 0; 00129 }