message.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <vector>
00041 #include <string>
00042 #include <cassert>
00043 #include <cstdint>
00044
00045 namespace Gecode { namespace CPProfiler {
00046
00048 static const int32_t PROFILER_PROTOCOL_VERSION = 3;
00049
00051 enum NodeStatus {
00052 SOLVED = 0,
00053 FAILED = 1,
00054 BRANCH = 2,
00055 SKIPPED = 3
00056 };
00057
00059 enum class MsgType {
00060 NODE = 0,
00061 DONE = 1,
00062 START = 2,
00063 RESTART = 3
00064 };
00065
00067 template <class T>
00068 class Option {
00069 protected:
00071 T value_;
00073 bool present{false};
00074 public:
00076 bool valid(void) const;
00078 void set(const T& t);
00080 void unset(void);
00082 const T& value(void) const;
00084 T& value(void);
00085 };
00086
00087 template <class T>
00088 forceinline bool
00089 Option<T>::valid(void) const {
00090 return present;
00091 }
00092 template <class T>
00093 forceinline void
00094 Option<T>::set(const T& t) {
00095 present = true; value_ = t;
00096 }
00097 template <class T>
00098 forceinline void
00099 Option<T>::unset(void) {
00100 present = false;
00101 }
00102 template <class T>
00103 forceinline const T&
00104 Option<T>::value(void) const {
00105 assert(present); return value_;
00106 }
00107 template <class T>
00108 forceinline T&
00109 Option<T>::value(void) {
00110 assert(present); return value_;
00111 }
00112
00114 struct NodeUID {
00116 int32_t nid;
00118 int32_t rid;
00120 int32_t tid;
00121 };
00122
00124 class Message {
00125 protected:
00126 MsgType _type;
00127
00128 NodeUID _node;
00129 NodeUID _parent;
00130 int32_t _alt;
00131 int32_t _kids;
00132 NodeStatus _status;
00133
00134 bool _have_label{false};
00135 std::string _label;
00136
00137 bool _have_nogood{false};
00138 std::string _nogood;
00139
00140 bool _have_info{false};
00141 std::string _info;
00142
00143 bool _have_version{false};
00144 int32_t _version;
00145
00146 public:
00147 bool isNode(void) const { return _type == MsgType::NODE; }
00148 bool isDone(void) const { return _type == MsgType::DONE; }
00149 bool isStart(void) const { return _type == MsgType::START; }
00150 bool isRestart(void) const { return _type == MsgType::RESTART; }
00151
00152 NodeUID nodeUID(void) const { return _node; }
00153 void set_nodeUID(const NodeUID& n) { _node = n; }
00154
00155 NodeUID parentUID(void) const { return _parent; }
00156 void set_parentUID(const NodeUID& p) { _parent = p; }
00157
00158 int32_t alt(void) const { return _alt; }
00159 void set_alt(int32_t alt) { _alt = alt; }
00160
00161 int32_t kids(void) const { return _kids; }
00162 void set_kids(int32_t kids) { _kids = kids; }
00163
00164 NodeStatus status(void) const { return _status; }
00165 void set_status(NodeStatus status) { _status = status; }
00166
00167 void set_label(const std::string& label) {
00168 _have_label = true;
00169 _label = label;
00170 }
00171
00172 void set_info(const std::string& info) {
00173 _have_info = true;
00174 _info = info;
00175 }
00176
00177 void set_nogood(const std::string& nogood) {
00178 _have_nogood = true;
00179 _nogood = nogood;
00180 }
00181
00182 void set_version(int32_t v) {
00183 _have_version = true;
00184 _version = v;
00185 }
00186
00187 bool has_version(void) const { return _have_version; }
00188 int32_t version(void) const { return _version; }
00189
00190 bool has_label(void) const { return _have_label; }
00191 const std::string& label() const { return _label; }
00192
00193 bool has_nogood(void) const { return _have_nogood; }
00194 const std::string& nogood(void) const { return _nogood; }
00195
00196
00197 bool has_info(void) const { return _have_info; }
00198 const std::string& info(void) const { return _info; }
00199
00200 void set_type(MsgType type) { _type = type; }
00201 MsgType type(void) const { return _type; }
00202
00203 void reset(void) {
00204 _have_label = false;
00205 _have_nogood = false;
00206 _have_info = false;
00207 _have_version = false;
00208 }
00209 };
00210
00211
00212 class MessageMarshalling {
00213 private:
00215 enum Field {
00216 LABEL = 0,
00217 NOGOOD = 1,
00218 INFO = 2,
00219 VERSION = 3
00220 };
00221
00222 Message msg;
00223
00224 typedef char* iter;
00225
00226 static void serializeType(std::vector<char>& data, MsgType f) {
00227 data.push_back(static_cast<char>(f));
00228 }
00229
00230 static void serializeField(std::vector<char>& data, Field f) {
00231 data.push_back(static_cast<char>(f));
00232 }
00233
00234 static void serialize(std::vector<char>& data, int32_t i) {
00235 data.push_back(static_cast<char>((i & 0xFF000000) >> 24));
00236 data.push_back(static_cast<char>((i & 0xFF0000) >> 16));
00237 data.push_back(static_cast<char>((i & 0xFF00) >> 8));
00238 data.push_back(static_cast<char>((i & 0xFF)));
00239 }
00240
00241 static void serialize(std::vector<char>& data, NodeStatus s) {
00242 data.push_back(static_cast<char>(s));
00243 }
00244
00245 static void serialize(std::vector<char>& data, const std::string& s) {
00246 serialize(data, static_cast<int32_t>(s.size()));
00247 for (char c : s) {
00248 data.push_back(c);
00249 }
00250 }
00251
00252 static MsgType deserializeMsgType(iter& it) {
00253 auto m = static_cast<MsgType>(*it);
00254 ++it;
00255 return m;
00256 }
00257
00258 static Field deserializeField(iter& it) {
00259 auto f = static_cast<Field>(*it);
00260 ++it;
00261 return f;
00262 }
00263
00264 static int32_t deserializeInt(iter& it) {
00265 auto b1 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
00266 auto b2 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
00267 auto b3 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
00268 auto b4 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
00269
00270 return static_cast<int32_t>(b1 << 24 | b2 << 16 | b3 << 8 | b4);
00271 }
00272
00273 static NodeStatus deserializeStatus(iter& it) {
00274 auto f = static_cast<NodeStatus>(*it);
00275 ++it;
00276 return f;
00277 }
00278
00279 static std::string deserializeString(iter& it) {
00280 std::string result;
00281 int32_t size = deserializeInt(it);
00282 result.reserve(static_cast<size_t>(size));
00283 for (int32_t i = 0; i < size; i++) {
00284 result += *it;
00285 ++it;
00286 }
00287 return result;
00288 }
00289
00290 public:
00291 Message& makeNode(NodeUID node, NodeUID parent,
00292 int32_t alt, int32_t kids, NodeStatus status) {
00293 msg.reset();
00294 msg.set_type(MsgType::NODE);
00295
00296 msg.set_nodeUID(node);
00297 msg.set_parentUID(parent);
00298
00299 msg.set_alt(alt);
00300 msg.set_kids(kids);
00301 msg.set_status(status);
00302
00303 return msg;
00304 }
00305
00306 void makeStart(const std::string& info) {
00307 msg.reset();
00308 msg.set_type(MsgType::START);
00309 msg.set_version(PROFILER_PROTOCOL_VERSION);
00310 msg.set_info(info);
00311 }
00312
00313 void makeRestart(const std::string& info) {
00314 msg.reset();
00315 msg.set_type(MsgType::RESTART);
00316 msg.set_info(info);
00317 }
00318
00319 void makeDone(void) {
00320 msg.reset();
00321 msg.set_type(MsgType::DONE);
00322 }
00323
00324 const Message& get_msg(void) { return msg; }
00325
00326 std::vector<char> serialize(void) const {
00327 std::vector<char> data;
00328 size_t dataSize = 1 + (msg.isNode() ? 4 * 8 + 1 : 0) +
00329 (msg.has_label() ? 1 + 4 + msg.label().size() : 0) +
00330 (msg.has_nogood() ? 1 + 4 + msg.nogood().size() : 0) +
00331 (msg.has_info() ? 1 + 4 + msg.info().size() : 0);
00332 data.reserve(dataSize);
00333
00334 serializeType(data, msg.type());
00335 if (msg.isNode()) {
00336
00337 auto n_uid = msg.nodeUID();
00338 serialize(data, n_uid.nid);
00339 serialize(data, n_uid.rid);
00340 serialize(data, n_uid.tid);
00341
00342 auto p_uid = msg.parentUID();
00343 serialize(data, p_uid.nid);
00344 serialize(data, p_uid.rid);
00345 serialize(data, p_uid.tid);
00346
00347 serialize(data, msg.alt());
00348 serialize(data, msg.kids());
00349 serialize(data, msg.status());
00350 }
00351
00352 if(msg.has_version()) {
00353 serializeField(data, VERSION);
00354 serialize(data, msg.version());
00355 }
00356 if (msg.has_label()) {
00357 serializeField(data, LABEL);
00358 serialize(data, msg.label());
00359 }
00360 if (msg.has_nogood()) {
00361 serializeField(data, NOGOOD);
00362 serialize(data, msg.nogood());
00363 }
00364 if (msg.has_info()) {
00365 serializeField(data, INFO);
00366 serialize(data, msg.info());
00367 }
00368 return data;
00369 }
00370
00371 void deserialize(char* data, size_t size) {
00372 char *end = data + size;
00373 msg.set_type(deserializeMsgType(data));
00374 if (msg.isNode()) {
00375 int32_t nid = deserializeInt(data);
00376 int32_t rid = deserializeInt(data);
00377 int32_t tid = deserializeInt(data);
00378
00379 msg.set_nodeUID({nid, rid, tid});
00380
00381 nid = deserializeInt(data);
00382 rid = deserializeInt(data);
00383 tid = deserializeInt(data);
00384
00385 msg.set_parentUID({nid, rid, tid});
00386
00387 msg.set_alt(deserializeInt(data));
00388 msg.set_kids(deserializeInt(data));
00389 msg.set_status(deserializeStatus(data));
00390 }
00391
00392 msg.reset();
00393
00394 while (data != end) {
00395 MessageMarshalling::Field f = deserializeField(data);
00396 switch (f) {
00397 case VERSION:
00398 msg.set_version(deserializeInt(data)); break;
00399 case LABEL:
00400 msg.set_label(deserializeString(data)); break;
00401 case NOGOOD:
00402 msg.set_nogood(deserializeString(data)); break;
00403 case INFO:
00404 msg.set_info(deserializeString(data)); break;
00405 default:
00406 break;
00407 }
00408 }
00409 }
00410 };
00411
00412 }}
00413
00414