[696] | 1 | #ifndef __XIOS_REGISTRY_HPP__ |
---|
| 2 | #define __XIOS_REGISTRY_HPP__ |
---|
| 3 | |
---|
| 4 | #include "base_type.hpp" |
---|
| 5 | #include "type.hpp" |
---|
| 6 | #include "mpi.hpp" |
---|
| 7 | #include "message.hpp" |
---|
[1134] | 8 | #ifdef _usingEP |
---|
| 9 | #include "ep_declaration.hpp" |
---|
| 10 | #endif |
---|
[696] | 11 | |
---|
[1134] | 12 | |
---|
[700] | 13 | // Those two headers can be replaced by the C++11 equivalent in the future |
---|
| 14 | #include <boost/utility/enable_if.hpp> |
---|
| 15 | #include <boost/type_traits.hpp> |
---|
| 16 | |
---|
[696] | 17 | namespace xios |
---|
| 18 | { |
---|
| 19 | /*! |
---|
| 20 | \class CRegistry |
---|
[700] | 21 | This class is a registry database which store key with an associated value. Internally the value is stored as a memory bloc |
---|
| 22 | and the key is a string. The registry can be gathered and merge between MPI process, broadcast and read or wrote from a file |
---|
[696] | 23 | */ |
---|
| 24 | class CRegistry : virtual public CBaseType |
---|
| 25 | { |
---|
| 26 | public: |
---|
| 27 | |
---|
| 28 | /** Constructor, the communicator is used for bcast or gather operation between MPI processes */ |
---|
[1134] | 29 | CRegistry(const ep_lib::MPI_Comm& comm=MPI_COMM_WORLD) : communicator(comm) {} |
---|
[700] | 30 | |
---|
[696] | 31 | /** Copy constructor */ |
---|
| 32 | CRegistry(const CRegistry& reg) ; |
---|
| 33 | |
---|
[700] | 34 | |
---|
[696] | 35 | /** insert a value associated to a key*/ |
---|
[700] | 36 | void setKey(const std::string& key, const CBaseType& value) { this->setKey_(key,value); } |
---|
[696] | 37 | |
---|
| 38 | /** insert a value associated to a key*/ |
---|
[700] | 39 | template<typename T> typename boost::enable_if_c<!boost::is_convertible<T&, CBaseType&>::value>::type |
---|
| 40 | setKey(const std::string& key, const T& value) { this->setKey_(key,CType<T>(value)); } |
---|
[696] | 41 | |
---|
| 42 | |
---|
[700] | 43 | /** retrieve a value from a key */ |
---|
| 44 | void getKey(const std::string& key, CBaseType& value) { this->getKey_(key,value); } |
---|
[696] | 45 | |
---|
[700] | 46 | /** retrieve a value from a key */ |
---|
| 47 | template<typename T> typename boost::enable_if_c<!boost::is_convertible<T&, CBaseType&>::value>::type |
---|
| 48 | getKey(const std::string& key, T& value) { CType_ref<T> valRef(value); this->getKey_(key,valRef); } |
---|
[696] | 49 | |
---|
| 50 | |
---|
| 51 | /** query for an already inserted key */ |
---|
| 52 | bool foundKey(const std::string& key) const ; |
---|
[700] | 53 | |
---|
[696] | 54 | /** The registry is wrote into a memory buffer */ |
---|
| 55 | bool toBuffer(CBufferOut& buffer) const ; |
---|
| 56 | |
---|
| 57 | /** The registry is read from a memory buffer */ |
---|
| 58 | bool fromBuffer(CBufferIn& buffer) ; |
---|
| 59 | |
---|
| 60 | /** The registry is wrote to the file given by "filename". If the registry is empty no file is wrote */ |
---|
| 61 | void toFile(const string& filename) ; |
---|
| 62 | |
---|
[700] | 63 | /** The registry is read from the file given by "filename". If no file exist, the registry remain empty */ |
---|
[696] | 64 | void fromFile(const string& filename) ; |
---|
| 65 | |
---|
[700] | 66 | /** Merge the registry with an other. Existing keys in the current registry are not overwritten */ |
---|
[696] | 67 | void mergeRegistry(const CRegistry& inRegistry) ; |
---|
| 68 | |
---|
[700] | 69 | /** Broadcast registry from the root process (rank 0) to the other processes of the communicator */ |
---|
[696] | 70 | void bcastRegistry(void) ; |
---|
| 71 | |
---|
[700] | 72 | /** Gather registry to the root process (rank 0) from the other processes of the communicator */ |
---|
[696] | 73 | void gatherRegistry(void) ; |
---|
| 74 | |
---|
[700] | 75 | /** Gather registry with a hierarchical algorithm which avoid root process to get registries from whole processes of the communicator. |
---|
| 76 | Registry are merged two by two hierarchically. */ |
---|
[696] | 77 | void hierarchicalGatherRegistry(void) ; |
---|
| 78 | |
---|
| 79 | /** Destructor */ |
---|
| 80 | ~CRegistry() { reset() ; } |
---|
| 81 | |
---|
| 82 | /** Unimplemented, do not use (need for CBaseType pure virtual class) */ |
---|
| 83 | void fromString(const string& str) ; |
---|
| 84 | |
---|
[700] | 85 | /** Dump registry to a string (need for CBaseType pure virtual class)*/ |
---|
[696] | 86 | string toString(void) const ; |
---|
| 87 | |
---|
[700] | 88 | /** Clone the registry (need for CBaseType pure virtual class)*/ |
---|
[696] | 89 | CRegistry* clone(void) const { return new CRegistry(*this); } |
---|
| 90 | |
---|
[700] | 91 | /** return the size needed to bufferize the registry (need for CBaseType pure virtual class)*/ |
---|
[696] | 92 | size_t size(void) const ; |
---|
| 93 | |
---|
[700] | 94 | /** return true if the registry is empty (need for CBaseType pure virtual class)*/ |
---|
[696] | 95 | bool isEmpty(void) const { return registry.empty(); } |
---|
| 96 | |
---|
[700] | 97 | /** Clean the registry and delete associated memory (need for CBaseType pure virtual class)*/ |
---|
[696] | 98 | void reset(void) ; |
---|
| 99 | |
---|
[700] | 100 | /** Set the prefix added systematically to the keys, with "::" as separator*/ |
---|
[696] | 101 | void setPath(const string& str) { path=str+"::" ; } |
---|
[700] | 102 | |
---|
[696] | 103 | private: |
---|
| 104 | |
---|
| 105 | /** insert a value associated to a key (internal use)*/ |
---|
| 106 | void setKey_(const std::string& key, const CBaseType& value) ; |
---|
| 107 | |
---|
[700] | 108 | /** retrieve a value from a key (internal use)*/ |
---|
| 109 | void getKey_(const std::string& key, CBaseType& value) ; |
---|
| 110 | |
---|
[696] | 111 | /** use internally for recursivity */ |
---|
| 112 | void gatherRegistry(const MPI_Comm& comm) ; |
---|
| 113 | |
---|
| 114 | /** use internally for recursivity */ |
---|
| 115 | void hierarchicalGatherRegistry(const MPI_Comm& comm) ; |
---|
| 116 | |
---|
| 117 | |
---|
[700] | 118 | /** Prefix added systematically to the keys, with "::" as separator*/ |
---|
[696] | 119 | std::string path ; |
---|
| 120 | |
---|
| 121 | /** Map containing registry, the key is a string type and the value is stored in a pair with the size |
---|
[700] | 122 | * of the memory bloc and the associated pointer*/ |
---|
[696] | 123 | std::map<std::string,std::pair<size_t,char*> > registry ; |
---|
| 124 | |
---|
| 125 | /** MPI communicator used for broadcast and gather operation */ |
---|
[1134] | 126 | ep_lib::MPI_Comm communicator ; |
---|
[696] | 127 | } ; |
---|
| 128 | |
---|
| 129 | inline CMessage& operator<<(CMessage& msg, CRegistry& registry) |
---|
| 130 | { |
---|
| 131 | msg.push(registry) ; |
---|
| 132 | return msg ; |
---|
| 133 | } |
---|
| 134 | |
---|
| 135 | inline CMessage& operator<<(CMessage& msg, const CRegistry& registry) |
---|
| 136 | { |
---|
| 137 | msg.push(registry) ; |
---|
| 138 | return msg ; |
---|
| 139 | } |
---|
| 140 | |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | #endif |
---|