My Project
WriteSerializationFile.hh
00001 /*
00002  * $Id:$
00003  */
00004 
00005 #if !defined(WRITESERIALIZATIONFILE)
00006 #define WRITESERIALIZATIONFILE
00007 
00008 #include <iostream>
00009 #include <fstream>
00010 
00011 #include <boost/serialization/serialization.hpp>
00012 #include <boost/serialization/vector.hpp>
00013 
00014 #include <boost/archive/binary_oarchive.hpp>
00015 #include <boost/archive/text_oarchive.hpp>
00016 #include <boost/archive/xml_oarchive.hpp>
00017 #include <boost/archive/binary_iarchive.hpp>
00018 #include <boost/archive/text_iarchive.hpp>
00019 #include <boost/archive/xml_iarchive.hpp>
00020 
00021 #include <boost/filesystem.hpp>
00022 
00023 #if defined(SPLITSERIALIZEXML)
00024 #define ARCFORMAT xml
00025 #else
00026 #define ARCFORMAT binary
00027 #endif
00028 
00029 #define cat(x,y)                x##y
00030 #define wrapped_cat(x,y)        cat(x,y)
00031 
00032 #ifdef MULTH
00033 # include <omp.h>
00034 #endif
00035 
00036 #include "Header.hh"
00037 
00038 #include "HeaderBase.hh"
00039 #include "ElementContainer.hh"
00040 #include "ElementContainerArray.hh"
00041 #include "ElementContainerMatrix.hh"
00042 #include "UInt4Container.hh"
00043 #include "UInt4ContainerArray.hh"
00044 #include "UInt4ContainerMatrix.hh"
00045 
00059 template <class Archive>
00060 class WriteSerializationFile {
00061 private:
00062   std::ofstream ofil;   
00063   Archive oa;           
00064   // template class Archive should be {binary,text,xml}_oarchive
00065 
00066   const std::string _ofname;    
00067 public:
00068   WriteSerializationFile(const char *filename)
00069     : ofil(filename), oa(ofil), _ofname(filename)
00070   {};
00071 
00072   void Save(const UInt4 &data) {
00073         oa << boost::serialization::make_nvp("UInt4Val", data);
00074   }
00075 
00076   void Save(const Int4 &data) {
00077         oa << boost::serialization::make_nvp("Int4Val", data);
00078   }
00079 
00080   void Save(const std::string &data) {
00081         oa << boost::serialization::make_nvp("StringVal", data);
00082   }
00083 
00084   void Save(const Double &data) {
00085         oa << boost::serialization::make_nvp("DoubleVal", data);
00086   }
00087 
00088   void Save(const vector<UInt4> &data) {
00089         oa << boost::serialization::make_nvp("UInt4VectorVal", data);
00090   }
00091 
00092   void Save(const vector<Int4> &data) {
00093         oa << boost::serialization::make_nvp("Int4VectorVal", data);
00094   }
00095 
00096   void Save(const vector<std::string> &data) {
00097         oa << boost::serialization::make_nvp("StringVectorVal", data);
00098   }
00099 
00100   void Save(const vector<Double> &data) {
00101         oa << boost::serialization::make_nvp("DoubleVectorVal", data);
00102   }
00103 
00104   void Save(const HeaderBase &data) {
00105         oa << boost::serialization::make_nvp("HeaderBase", data);
00106   }
00107 
00108   void Save(const ElementContainer &data) {
00109         oa << boost::serialization::make_nvp("ElementContainer", data);
00110   }
00111 
00112   void Save(const ElementContainerArray &data) {
00113         oa << boost::serialization::make_nvp("ElementContainerArray", data);
00114   }
00115 
00116   void Save(const ElementContainerMatrix &data) {
00117         oa << boost::serialization::make_nvp("ElementContainerMatrix", data);
00118   }
00119 
00120   void Save(const UInt4Container &data) {
00121         oa << boost::serialization::make_nvp("UInt4Container", data);
00122   }
00123 
00124   void Save(const UInt4ContainerArray &data) {
00125         oa << boost::serialization::make_nvp("UInt4ContainerArray", data);
00126   }
00127 
00128   void Save(const UInt4ContainerMatrix &data) {
00129         oa << boost::serialization::make_nvp("UInt4ContainerMatrix", data);
00130   }
00131 
00132 private:
00133   template <class pContainer, class cContainer>
00134   void SplitSave(const pContainer &data, const unsigned int splitnum);
00135 
00136 public:
00137   void SplitSave(const ElementContainerArray  &data, const unsigned int splitnum=1) {
00138         SplitSave<ElementContainerArray, ElementContainer>(data, splitnum);
00139   }
00140 
00141   void SplitSave(const ElementContainerMatrix &data, const unsigned int splitnum=1) {
00142         SplitSave<ElementContainerMatrix, ElementContainerArray>(data, splitnum);
00143   }
00144 
00145   void SplitSave(const UInt4ContainerArray  &data, const unsigned int splitnum=1) {
00146         SplitSave<UInt4ContainerArray, UInt4Container>(data, splitnum);
00147   }
00148 
00149   void SplitSave(const UInt4ContainerMatrix &data, const unsigned int splitnum=1) {
00150         SplitSave<UInt4ContainerMatrix, UInt4ContainerArray>(data, splitnum);
00151   }
00152 };
00153 
00154 
00155 
00156 template <class Archive>
00157 template <class pContainer, class cContainer>
00158 void WriteSerializationFile<Archive>::SplitSave(const pContainer &data, const unsigned int splitnum) {
00159   std::vector<std::string> S = data.presave(oa, _ofname, splitnum);
00160   boost::filesystem::path serializepath(_ofname);
00161   serializepath = serializepath.branch_path();
00162   unsigned int size = S.size()-1;
00163 
00164   {
00165     std::ofstream ofil((serializepath / S[0]).string().c_str());
00166         boost::archive::wrapped_cat(ARCFORMAT,_oarchive) obin(ofil);
00167 
00168         obin << boost::serialization::make_nvp("Header", *data.PutHeaderPointer());
00169   }
00170 
00171   std::vector<std::vector< cContainer *> > _EC(size);
00172   unsigned int vstart = 0, vnum = data.PutSize() / size;
00173   signed int _N = data.PutSize() - vnum * size;
00174   for (unsigned int i=0;i<size;++i) {
00175         unsigned int vnum0 = vnum;
00176         if (_N>0) {
00177           ++vnum0; --_N;
00178         }
00179         _EC[i].assign(&(data.v[vstart]), &(data.v[vstart+vnum0]));
00180         vstart += vnum0;
00181   }
00182 
00183   std::vector<UInt4> csize;
00184   for (UInt4 i=0;i<_EC.size();++i)
00185         csize.push_back(_EC[i].size());
00186   oa & boost::serialization::make_nvp("ContainerSizes", csize);
00187 
00188 
00189 #ifdef MULTH
00190   omp_set_num_threads(
00191     std::min(MULTH,  std::min(omp_get_max_threads(), omp_get_num_procs()) )
00192   );
00193 #endif
00194 #pragma omp parallel for
00195   for (unsigned int i=0;i<size;++i) {
00196     std::ofstream ofil((serializepath / S[i+1]).string().c_str());
00197         boost::archive::wrapped_cat(ARCFORMAT,_oarchive) A(ofil);
00198     A << boost::serialization::make_nvp("StoredContainers", _EC[i]);
00199     ofil.close();
00200   }
00201 }
00202 
00203 #endif /* WRITESERIALIZATIONFILE */
 All Classes Functions Variables Friends