Stxxl  1.4.0
containers/write_vector.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines