message.hpp
Go to the documentation of this file.
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Maxim Shishmarev <maxim.shishmarev@monash.edu>
*
* Contributing authors:
* Guido Tack <tack@gecode.org>
* Kevin Leo <kevin.leo@monash.edu>
*
* Copyright:
* Maxim Shishmarev, 2017
* Guido Tack, 2017
* Kevin Leo, 2017
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <vector>
#include <string>
#include <cassert>
#include <cstdint>
namespace Gecode { namespace CPProfiler {
static const int32_t PROFILER_PROTOCOL_VERSION = 3;
enum NodeStatus {
SOLVED = 0,
FAILED = 1,
BRANCH = 2,
SKIPPED = 3
};
enum class MsgType {
NODE = 0,
DONE = 1,
START = 2,
RESTART = 3
};
template <class T>
class Option {
protected:
T value_;
bool present{false};
public:
bool valid(void) const;
void set(const T& t);
void unset(void);
const T& value(void) const;
T& value(void);
};
template <class T>
forceinline bool
Option<T>::valid(void) const {
return present;
}
template <class T>
forceinline void
Option<T>::set(const T& t) {
present = true; value_ = t;
}
template <class T>
forceinline void
Option<T>::unset(void) {
present = false;
}
template <class T>
forceinline const T&
Option<T>::value(void) const {
assert(present); return value_;
}
template <class T>
forceinline T&
Option<T>::value(void) {
assert(present); return value_;
}
struct NodeUID {
int32_t nid;
int32_t rid;
int32_t tid;
};
class Message {
protected:
MsgType _type;
NodeUID _node;
NodeUID _parent;
int32_t _alt;
int32_t _kids;
NodeStatus _status;
bool _have_label{false};
std::string _label;
bool _have_nogood{false};
std::string _nogood;
bool _have_info{false};
std::string _info;
bool _have_version{false};
int32_t _version; // PROFILER_PROTOCOL_VERSION;
public:
bool isNode(void) const { return _type == MsgType::NODE; }
bool isDone(void) const { return _type == MsgType::DONE; }
bool isStart(void) const { return _type == MsgType::START; }
bool isRestart(void) const { return _type == MsgType::RESTART; }
NodeUID nodeUID(void) const { return _node; }
void set_nodeUID(const NodeUID& n) { _node = n; }
NodeUID parentUID(void) const { return _parent; }
void set_parentUID(const NodeUID& p) { _parent = p; }
int32_t alt(void) const { return _alt; }
void set_alt(int32_t alt) { _alt = alt; }
int32_t kids(void) const { return _kids; }
void set_kids(int32_t kids) { _kids = kids; }
NodeStatus status(void) const { return _status; }
void set_status(NodeStatus status) { _status = status; }
void set_label(const std::string& label) {
_have_label = true;
_label = label;
}
void set_info(const std::string& info) {
_have_info = true;
_info = info;
}
void set_nogood(const std::string& nogood) {
_have_nogood = true;
_nogood = nogood;
}
void set_version(int32_t v) {
_have_version = true;
_version = v;
}
bool has_version(void) const { return _have_version; }
int32_t version(void) const { return _version; }
bool has_label(void) const { return _have_label; }
const std::string& label() const { return _label; }
bool has_nogood(void) const { return _have_nogood; }
const std::string& nogood(void) const { return _nogood; }
// generic optional fields
bool has_info(void) const { return _have_info; }
const std::string& info(void) const { return _info; }
void set_type(MsgType type) { _type = type; }
MsgType type(void) const { return _type; }
void reset(void) {
_have_label = false;
_have_nogood = false;
_have_info = false;
_have_version = false;
}
};
class MessageMarshalling {
private:
enum Field {
LABEL = 0,
NOGOOD = 1,
INFO = 2,
VERSION = 3
};
Message msg;
typedef char* iter;
static void serializeType(std::vector<char>& data, MsgType f) {
data.push_back(static_cast<char>(f));
}
static void serializeField(std::vector<char>& data, Field f) {
data.push_back(static_cast<char>(f));
}
static void serialize(std::vector<char>& data, int32_t i) {
data.push_back(static_cast<char>((i & 0xFF000000) >> 24));
data.push_back(static_cast<char>((i & 0xFF0000) >> 16));
data.push_back(static_cast<char>((i & 0xFF00) >> 8));
data.push_back(static_cast<char>((i & 0xFF)));
}
static void serialize(std::vector<char>& data, NodeStatus s) {
data.push_back(static_cast<char>(s));
}
static void serialize(std::vector<char>& data, const std::string& s) {
serialize(data, static_cast<int32_t>(s.size()));
for (char c : s) {
data.push_back(c);
}
}
static MsgType deserializeMsgType(iter& it) {
auto m = static_cast<MsgType>(*it);
++it;
return m;
}
static Field deserializeField(iter& it) {
auto f = static_cast<Field>(*it);
++it;
return f;
}
static int32_t deserializeInt(iter& it) {
auto b1 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
auto b2 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
auto b3 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
auto b4 = static_cast<uint32_t>(reinterpret_cast<uint8_t&>(*it++));
return static_cast<int32_t>(b1 << 24 | b2 << 16 | b3 << 8 | b4);
}
static NodeStatus deserializeStatus(iter& it) {
auto f = static_cast<NodeStatus>(*it);
++it;
return f;
}
static std::string deserializeString(iter& it) {
std::string result;
int32_t size = deserializeInt(it);
result.reserve(static_cast<size_t>(size));
for (int32_t i = 0; i < size; i++) {
result += *it;
++it;
}
return result;
}
public:
Message& makeNode(NodeUID node, NodeUID parent,
int32_t alt, int32_t kids, NodeStatus status) {
msg.reset();
msg.set_type(MsgType::NODE);
msg.set_nodeUID(node);
msg.set_parentUID(parent);
msg.set_alt(alt);
msg.set_kids(kids);
msg.set_status(status);
return msg;
}
void makeStart(const std::string& info) {
msg.reset();
msg.set_type(MsgType::START);
msg.set_version(PROFILER_PROTOCOL_VERSION);
msg.set_info(info);
}
void makeRestart(const std::string& info) {
msg.reset();
msg.set_type(MsgType::RESTART);
msg.set_info(info);
}
void makeDone(void) {
msg.reset();
msg.set_type(MsgType::DONE);
}
const Message& get_msg(void) { return msg; }
std::vector<char> serialize(void) const {
std::vector<char> data;
size_t dataSize = 1 + (msg.isNode() ? 4 * 8 + 1 : 0) +
(msg.has_label() ? 1 + 4 + msg.label().size() : 0) +
(msg.has_nogood() ? 1 + 4 + msg.nogood().size() : 0) +
(msg.has_info() ? 1 + 4 + msg.info().size() : 0);
data.reserve(dataSize);
serializeType(data, msg.type());
if (msg.isNode()) {
// serialize NodeId node
auto n_uid = msg.nodeUID();
serialize(data, n_uid.nid);
serialize(data, n_uid.rid);
serialize(data, n_uid.tid);
// serialize NodeId parent
auto p_uid = msg.parentUID();
serialize(data, p_uid.nid);
serialize(data, p_uid.rid);
serialize(data, p_uid.tid);
// Other Data
serialize(data, msg.alt());
serialize(data, msg.kids());
serialize(data, msg.status());
}
if(msg.has_version()) {
serializeField(data, VERSION);
serialize(data, msg.version());
}
if (msg.has_label()) {
serializeField(data, LABEL);
serialize(data, msg.label());
}
if (msg.has_nogood()) {
serializeField(data, NOGOOD);
serialize(data, msg.nogood());
}
if (msg.has_info()) {
serializeField(data, INFO);
serialize(data, msg.info());
}
return data;
}
void deserialize(char* data, size_t size) {
char *end = data + size;
msg.set_type(deserializeMsgType(data));
if (msg.isNode()) {
int32_t nid = deserializeInt(data);
int32_t rid = deserializeInt(data);
int32_t tid = deserializeInt(data);
msg.set_nodeUID({nid, rid, tid});
nid = deserializeInt(data);
rid = deserializeInt(data);
tid = deserializeInt(data);
msg.set_parentUID({nid, rid, tid});
msg.set_alt(deserializeInt(data));
msg.set_kids(deserializeInt(data));
msg.set_status(deserializeStatus(data));
}
msg.reset();
while (data != end) {
MessageMarshalling::Field f = deserializeField(data);
switch (f) {
case VERSION:
msg.set_version(deserializeInt(data)); break;
case LABEL:
msg.set_label(deserializeString(data)); break;
case NOGOOD:
msg.set_nogood(deserializeString(data)); break;
case INFO:
msg.set_info(deserializeString(data)); break;
default:
break;
}
}
}
};
}}
// STATISTICS: search-trace
Gecode::CPProfiler::MessageMarshalling
Definition message.hpp:212
Gecode::CPProfiler::MessageMarshalling::serialize
std::vector< char > serialize(void) const
Definition message.hpp:326
Gecode::CPProfiler::MessageMarshalling::deserialize
void deserialize(char *data, size_t size)
Definition message.hpp:371
Gecode::CPProfiler::MessageMarshalling::get_msg
const Message & get_msg(void)
Definition message.hpp:324
Gecode::CPProfiler::MessageMarshalling::makeNode
Message & makeNode(NodeUID node, NodeUID parent, int32_t alt, int32_t kids, NodeStatus status)
Definition message.hpp:291
Gecode::CPProfiler::MessageMarshalling::makeStart
void makeStart(const std::string &info)
Definition message.hpp:306
Gecode::CPProfiler::MessageMarshalling::makeDone
void makeDone(void)
Definition message.hpp:319
Gecode::CPProfiler::MessageMarshalling::makeRestart
void makeRestart(const std::string &info)
Definition message.hpp:313
Gecode::CPProfiler::Message
Message for the CP Profiler.
Definition message.hpp:124
Gecode::CPProfiler::Message::set_alt
void set_alt(int32_t alt)
Definition message.hpp:159
Gecode::CPProfiler::Message::_status
NodeStatus _status
Definition message.hpp:132
Gecode::CPProfiler::Message::has_info
bool has_info(void) const
Definition message.hpp:197
Gecode::CPProfiler::Message::reset
void reset(void)
Definition message.hpp:203
Gecode::CPProfiler::Message::_nogood
std::string _nogood
Definition message.hpp:138
Gecode::CPProfiler::Message::nodeUID
NodeUID nodeUID(void) const
Definition message.hpp:152
Gecode::CPProfiler::Message::set_label
void set_label(const std::string &label)
Definition message.hpp:167
Gecode::CPProfiler::Message::set_status
void set_status(NodeStatus status)
Definition message.hpp:165
Gecode::CPProfiler::Message::parentUID
NodeUID parentUID(void) const
Definition message.hpp:155
Gecode::CPProfiler::Message::set_nogood
void set_nogood(const std::string &nogood)
Definition message.hpp:177
Gecode::CPProfiler::Message::_have_info
bool _have_info
Definition message.hpp:140
Gecode::CPProfiler::Message::set_nodeUID
void set_nodeUID(const NodeUID &n)
Definition message.hpp:153
Gecode::CPProfiler::Message::label
const std::string & label() const
Definition message.hpp:191
Gecode::CPProfiler::Message::_have_nogood
bool _have_nogood
Definition message.hpp:137
Gecode::CPProfiler::Message::nogood
const std::string & nogood(void) const
Definition message.hpp:194
Gecode::CPProfiler::Message::_have_label
bool _have_label
Definition message.hpp:134
Gecode::CPProfiler::Message::_version
int32_t _version
Definition message.hpp:144
Gecode::CPProfiler::Message::isNode
bool isNode(void) const
Definition message.hpp:147
Gecode::CPProfiler::Message::_node
NodeUID _node
Definition message.hpp:128
Gecode::CPProfiler::Message::_label
std::string _label
Definition message.hpp:135
Gecode::CPProfiler::Message::_have_version
bool _have_version
Definition message.hpp:143
Gecode::CPProfiler::Message::set_info
void set_info(const std::string &info)
Definition message.hpp:172
Gecode::CPProfiler::Message::isStart
bool isStart(void) const
Definition message.hpp:149
Gecode::CPProfiler::Message::_alt
int32_t _alt
Definition message.hpp:130
Gecode::CPProfiler::Message::version
int32_t version(void) const
Definition message.hpp:188
Gecode::CPProfiler::Message::_info
std::string _info
Definition message.hpp:141
Gecode::CPProfiler::Message::alt
int32_t alt(void) const
Definition message.hpp:158
Gecode::CPProfiler::Message::status
NodeStatus status(void) const
Definition message.hpp:164
Gecode::CPProfiler::Message::set_version
void set_version(int32_t v)
Definition message.hpp:182
Gecode::CPProfiler::Message::isRestart
bool isRestart(void) const
Definition message.hpp:150
Gecode::CPProfiler::Message::has_nogood
bool has_nogood(void) const
Definition message.hpp:193
Gecode::CPProfiler::Message::_parent
NodeUID _parent
Definition message.hpp:129
Gecode::CPProfiler::Message::_type
MsgType _type
Definition message.hpp:126
Gecode::CPProfiler::Message::set_type
void set_type(MsgType type)
Definition message.hpp:200
Gecode::CPProfiler::Message::type
MsgType type(void) const
Definition message.hpp:201
Gecode::CPProfiler::Message::kids
int32_t kids(void) const
Definition message.hpp:161
Gecode::CPProfiler::Message::isDone
bool isDone(void) const
Definition message.hpp:148
Gecode::CPProfiler::Message::set_kids
void set_kids(int32_t kids)
Definition message.hpp:162
Gecode::CPProfiler::Message::_kids
int32_t _kids
Definition message.hpp:131
Gecode::CPProfiler::Message::info
const std::string & info(void) const
Definition message.hpp:198
Gecode::CPProfiler::Message::has_label
bool has_label(void) const
Definition message.hpp:190
Gecode::CPProfiler::Message::has_version
bool has_version(void) const
Definition message.hpp:187
Gecode::CPProfiler::Message::set_parentUID
void set_parentUID(const NodeUID &p)
Definition message.hpp:156
Gecode::CPProfiler::Option
Optional value class.
Definition message.hpp:68
Gecode::CPProfiler::Option::valid
bool valid(void) const
Check whether value is present.
Definition message.hpp:89
Gecode::CPProfiler::Option::set
void set(const T &t)
Set value to t.
Definition message.hpp:94
Gecode::CPProfiler::Option::present
bool present
Whether value is present.
Definition message.hpp:73
Gecode::CPProfiler::Option::value_
T value_
A value, potentially not initialized.
Definition message.hpp:71
Gecode::CPProfiler::Option::unset
void unset(void)
Disregard value.
Definition message.hpp:99
Gecode::CPProfiler::Option::value
const T & value(void) const
Access value.
Definition message.hpp:104
Gecode::CPProfiler
Code that is specific to the CPProfiler.
Definition search.hh:406
Gecode::CPProfiler::NodeStatus
NodeStatus
Types of nodes for CP Profiler.
Definition message.hpp:51
Gecode::CPProfiler::SOLVED
@ SOLVED
Node representing a solution.
Definition message.hpp:52
Gecode::CPProfiler::BRANCH
@ BRANCH
Node representing a branch.
Definition message.hpp:54
Gecode::CPProfiler::SKIPPED
@ SKIPPED
Node skipped by backjumping.
Definition message.hpp:55
Gecode::CPProfiler::FAILED
@ FAILED
Node representing failure.
Definition message.hpp:53
Gecode::CPProfiler::MsgType
MsgType
Types of messages for CP Profiler.
Definition message.hpp:59
Gecode::CPProfiler::MsgType::NODE
@ NODE
Definition message.hpp:60
Gecode::CPProfiler::MsgType::RESTART
@ RESTART
Definition message.hpp:63
Gecode::CPProfiler::MsgType::DONE
@ DONE
Definition message.hpp:61
Gecode::CPProfiler::MsgType::START
@ START
Definition message.hpp:62
Gecode
Gecode toplevel namespace
Gecode::CPProfiler::NodeUID
Unique identifier for a node.
Definition message.hpp:114
Gecode::CPProfiler::NodeUID::nid
int32_t nid
Node number.
Definition message.hpp:116
Gecode::CPProfiler::NodeUID::rid
int32_t rid
Restart id.
Definition message.hpp:118
Gecode::CPProfiler::NodeUID::tid
int32_t tid
Thread id.
Definition message.hpp:120
forceinline
#define forceinline
Definition config.hpp:187