Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * containers/write_vector2.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 ExtIterator> 00020 class write_vector 00021 { 00022 typedef typename ExtIterator::size_type size_type; 00023 typedef typename ExtIterator::value_type value_type; 00024 typedef typename ExtIterator::block_type block_type; 00025 typedef typename ExtIterator::const_iterator ConstExtIterator; 00026 typedef stxxl::buf_ostream<block_type, typename ExtIterator::bids_container_iterator> buf_ostream_type; 00027 00028 ExtIterator it; 00029 unsigned nbuffers; 00030 buf_ostream_type * outstream; 00031 00032 public: 00033 write_vector(ExtIterator begin, 00034 unsigned nbuffers_ // buffers to use for overlapping (>=2 recommended) 00035 ) : it(begin), nbuffers(nbuffers_) 00036 { 00037 outstream = new buf_ostream_type(it.bid(), nbuffers); 00038 } 00039 00040 value_type & operator * () 00041 { 00042 if (it.block_offset() == 0) 00043 it.block_externally_updated(); 00044 // tells the vector that the block was modified 00045 return **outstream; 00046 } 00047 00048 write_vector & operator ++ () 00049 { 00050 ++it; 00051 ++(*outstream); 00052 return *this; 00053 } 00054 00055 void flush() 00056 { 00057 ConstExtIterator const_out = it; 00058 00059 while (const_out.block_offset()) 00060 { 00061 **outstream = *const_out; // might cause I/Os for loading the page that 00062 ++const_out; // contains data beyond out 00063 ++(*outstream); 00064 } 00065 00066 it.flush(); 00067 delete outstream; 00068 outstream = NULL; 00069 } 00070 00071 virtual ~write_vector() 00072 { 00073 if (outstream) 00074 flush(); 00075 } 00076 }; 00077 00078 typedef unsigned char my_type; 00079 00080 // copies a file to another file 00081 00082 using stxxl::syscall_file; 00083 using stxxl::file; 00084 00085 int main(int argc, char * argv[]) 00086 { 00087 if (argc < 3) 00088 { 00089 std::cout << "Usage: " << argv[0] << " input_file output_file " << std::endl; 00090 return -1; 00091 } 00092 00093 unlink(argv[2]); // delete output file 00094 00095 syscall_file InputFile(argv[1], file::RDONLY); // Input file object 00096 syscall_file OutputFile(argv[2], file::RDWR | file::CREAT); // Output file object 00097 00098 typedef stxxl::vector<my_type> vector_type; 00099 00100 std::cout << "Copying file " << argv[1] << " to " << argv[2] << std::endl; 00101 00102 vector_type InputVector(&InputFile); // InputVector is mapped to InputFile 00103 vector_type OutputVector(&OutputFile); // OutputVector is mapped to OutputFile 00104 OutputVector.resize(InputVector.size()); 00105 00106 std::cout << "File " << argv[1] << " has size " << InputVector.size() << " bytes." << std::endl; 00107 00108 vector_type::const_iterator it = InputVector.begin(); // creating const iterator 00109 00110 write_vector<vector_type::iterator> Writer(OutputVector.begin(), 2); 00111 00112 for ( ; it != InputVector.end(); ++it, ++Writer) // iterate through InputVector 00113 { 00114 *Writer = *it; 00115 } 00116 Writer.flush(); // flush buffers 00117 00118 00119 return 0; 00120 }