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