diff --git a/include/warthog/memory/node_pool.h b/include/warthog/memory/node_pool.h index cc5f5e8..4d780ff 100644 --- a/include/warthog/memory/node_pool.h +++ b/include/warthog/memory/node_pool.h @@ -24,26 +24,109 @@ // #include "cpool.h" +#include +#include +#include +#include #include -#include - namespace warthog::memory { namespace node_pool_ns { -static const uint64_t NBS = 8; // node block size; set this >= 8 -static const uint64_t LOG2_NBS = 3; -static const uint64_t NBS_MASK = 7; +constexpr uint64_t LOG2_NBS = 6; // node block size = 2^n, n >= 3 +constexpr uint64_t NBS = 1 << LOG2_NBS; +constexpr uint64_t NBS_MASK = NBS - 1; +static_assert(LOG2_NBS >= 3, "must be at least 3 for size of 8"); } class node_pool { public: + struct data_deleter_ptr + { + void (*del)(void*) = nullptr; + + constexpr data_deleter_ptr() noexcept = default; + constexpr data_deleter_ptr(void (*p)(void*)) noexcept : del(p) { } + + void + operator()(void* data) const noexcept + { + (*del)(data); + } + }; + node_pool(); node_pool(size_t num_nodes); ~node_pool(); + template< + std::derived_from T = search::search_node, + typename... NodeArgs> + void + set_type(NodeArgs... node_args) noexcept + { + clear(); + using arg_type = std::tuple; + if constexpr(sizeof...(NodeArgs) != 0) + { + create_block_data_ = static_cast( + new arg_type(std::forward(node_args)...)); + } + block_type_sizes_ = sizeof(T); + size_t block_sz = node_pool_ns::NBS * sizeof(T); + blockspool_ = std::make_unique(block_sz, 1); + create_block_ = [](void* block_p, sn_id_t block_id, + void* data) noexcept { + assert(block_p != nullptr); + T* block = reinterpret_cast(block_p); + pad_id current_id = pad_id{block_id << node_pool_ns::LOG2_NBS}; + for(uint32_t i = 0; i < node_pool_ns::NBS; ++i, ++current_id.id) + { + if constexpr(sizeof...(NodeArgs) == 0) + { + std::construct_at(block + i, current_id); + } + else + { + assert(data != nullptr); + std::apply( + [block_i = block + i, + current_id](NodeX&&... args) { + std::construct_at(block_i, current_id, args...); + }, + *static_cast(data)); + } + } + }; + clear_ = [](node_pool& np) noexcept { + if(np.blocks_) + { + for(size_t i = 0; i < np.num_blocks_; ++i) + { + T* nodes = reinterpret_cast(np.blocks_[i]); + if(nodes != nullptr) + { + for(uint32_t j = 0; j < node_pool_ns::NBS; ++j) + { + std::destroy_at(nodes + j); + } + } + } + } + if constexpr(sizeof...(NodeArgs) == 0) + { + if(!np.create_block_data_) + { + arg_type* args + = static_cast(np.create_block_data_); + delete args; + } + } + }; + } + // return a warthog::search_node object corresponding to the given id. // if the node has already been generated, return a pointer to the // previous instance; otherwise allocate memory for a new object. @@ -58,13 +141,24 @@ class node_pool size_t mem(); + // reset nodes + void + clear(); + private: void init(size_t nblocks); + void + release(); - size_t num_blocks_; - search::search_node** blocks_; - cpool* blockspool_; + size_t num_blocks_ = 0; + std::unique_ptr blocks_; + size_t block_type_sizes_ = 0; + std::unique_ptr blockspool_; + void (*create_block_)(void* block, sn_id_t bock_id, void* data) noexcept + = nullptr; + void (*clear_)(node_pool& np) = nullptr; + void* create_block_data_; // uint64_t* node_init_; // uint64_t node_init_sz_; }; diff --git a/include/warthog/search/search_node.h b/include/warthog/search/search_node.h index 90b9eba..b091c9a 100644 --- a/include/warthog/search/search_node.h +++ b/include/warthog/search/search_node.h @@ -16,23 +16,15 @@ namespace warthog::search { -class search_node +struct search_node { -public: - search_node(pad_id id = pad_id::max()) - : id_(id), parent_id_(warthog::SN_ID_MAX), g_(warthog::COST_MAX), - f_(warthog::COST_MAX), ub_(warthog::COST_MAX), status_(0), - priority_(warthog::INF32), search_number_(UINT32_MAX) - { - refcount_++; - } - - ~search_node() { refcount_--; } + search_node() noexcept = default; + search_node(pad_id id = pad_id::max()) noexcept : id_(id) { } inline void init( uint32_t search_number, pad_id parent_id, cost_t g, cost_t f, - cost_t ub = warthog::COST_MAX) + cost_t ub = warthog::COST_MAX) noexcept { parent_id_ = parent_id; f_ = f; @@ -43,103 +35,103 @@ class search_node } inline uint32_t - get_search_number() const + get_search_number() const noexcept { return search_number_; } inline void - set_search_number(uint32_t search_number) + set_search_number(uint32_t search_number) noexcept { search_number_ = search_number; } inline pad_id - get_id() const + get_id() const noexcept { return id_; } inline void - set_id(pad_id id) + set_id(pad_id id) noexcept { id_ = id; } inline bool - get_expanded() const + get_expanded() const noexcept { return status_; } inline void - set_expanded(bool expanded) + set_expanded(bool expanded) noexcept { status_ = expanded; } inline pad_id - get_parent() const + get_parent() const noexcept { return parent_id_; } inline void - set_parent(pad_id parent_id) + set_parent(pad_id parent_id) noexcept { parent_id_ = parent_id; } inline uint32_t - get_priority() const + get_priority() const noexcept { return priority_; } inline void - set_priority(uint32_t priority) + set_priority(uint32_t priority) noexcept { priority_ = priority; } inline cost_t - get_g() const + get_g() const noexcept { return g_; } inline void - set_g(cost_t g) + set_g(cost_t g) noexcept { g_ = g; } inline cost_t - get_f() const + get_f() const noexcept { return f_; } inline void - set_f(cost_t f) + set_f(cost_t f) noexcept { f_ = f; } inline cost_t - get_ub() const + get_ub() const noexcept { return ub_; } inline void - set_ub(cost_t ub) + set_ub(cost_t ub) noexcept { ub_ = ub; } inline void - relax(cost_t g, pad_id parent_id) + relax(cost_t g, pad_id parent_id) noexcept { assert(g < g_); f_ = (f_ - g_) + g; @@ -149,7 +141,7 @@ class search_node } inline bool - operator<(const search_node& other) const + operator<(const search_node& other) const noexcept { // static uint64_t SIGN_MASK = UINT64_MAX & (1ULL<<63); // cost_t result = this->f_ - other.f_; @@ -170,7 +162,7 @@ class search_node } inline bool - operator>(const search_node& other) const + operator>(const search_node& other) const noexcept { if(f_ > other.f_) { return true; } if(f_ < other.f_) { return false; } @@ -181,14 +173,14 @@ class search_node } inline bool - operator==(const search_node& other) const + operator==(const search_node& other) const noexcept { if(!(*this < other) && !(*this > other)) { return true; } return false; } inline bool - operator<=(const search_node& other) const + operator<=(const search_node& other) const noexcept { if(*this < other) { return true; } if(!(*this > other)) { return true; } @@ -196,50 +188,34 @@ class search_node } inline bool - operator>=(const search_node& other) const + operator>=(const search_node& other) const noexcept { if(*this > other) { return true; } if(!(*this < other)) { return true; } return false; } - inline void - print(std::ostream& out) const - { - out << "search_node id:" << get_id().id; - out << " p_id: "; - out << parent_id_.id; - out << " g: " << g_ << " f: " << this->get_f() << " ub: " << ub_ - << " expanded: " << get_expanded() << " " - << " search_number_: " << search_number_; - } + void + print(std::ostream& out) const; uint32_t - mem() + mem() noexcept { return sizeof(*this); } - static uint32_t - get_refcount() - { - return refcount_; - } - -private: - pad_id id_; - pad_id parent_id_; + pad_id id_ = pad_id(warthog::SN_ID_MAX); + pad_id parent_id_ = pad_id(warthog::SN_ID_MAX); - cost_t g_; - cost_t f_; - cost_t ub_; + cost_t g_ = warthog::COST_MAX; + cost_t f_ = warthog::COST_MAX; + cost_t ub_ = warthog::COST_MAX; // TODO steal the high-bit from priority instead of ::status_ ? - uint8_t status_; // open or closed - uint32_t priority_; // expansion priority + uint8_t status_ = 0; // open or closed + uint32_t priority_ = warthog::INF32; // expansion priority - uint32_t search_number_; - static uint32_t refcount_; + uint32_t search_number_ = UINT32_MAX; }; struct cmp_less_search_node diff --git a/include/warthog/search/uds_traits.h b/include/warthog/search/uds_traits.h index bfaac52..9d65c8b 100644 --- a/include/warthog/search/uds_traits.h +++ b/include/warthog/search/uds_traits.h @@ -14,6 +14,7 @@ #include "search_metrics.h" #include +#include namespace warthog::search { @@ -133,7 +134,7 @@ enum class reopen_policy // decide whether to renopen nodes already expanded (when their g-value // can be improved). we handle the positive case via specialisation. -template +template inline bool reopen() { @@ -147,6 +148,108 @@ reopen() return true; } +struct uds_default_traits +{ + // using node = std::tuple<>; + // using observer = std::tuple<>; + static constexpr admissibility_criteria ac = admissibility_criteria::any; + static constexpr feasibility_criteria fc + = feasibility_criteria::until_exhaustion; + static constexpr reopen_policy rp = reopen_policy::no; +}; + +template< + typename N = search_node, typename L = std::tuple<>, + admissibility_criteria AC = admissibility_criteria::any, + feasibility_criteria FC = feasibility_criteria::until_exhaustion, + reopen_policy RP = reopen_policy::no> +struct uds_traits +{ + using node = N; + using observer = L; + static constexpr admissibility_criteria ac = AC; + static constexpr feasibility_criteria fc = FC; + static constexpr reopen_policy rp = RP; +}; + +namespace details +{ + +template +struct uds_trait_node +{ + using type = search_node; +}; +template + requires requires { typename Traits::node; } +struct uds_trait_node +{ + using type = typename Traits::node; +}; + +template +struct uds_trait_observer +{ + using type = search_node; +}; +template + requires requires { typename Traits::observer; } +struct uds_trait_observer +{ + using type = typename Traits::observer; +}; + +} // namespace details + +template +using uds_trait_node = typename details::uds_trait_node::type; + +template +using uds_trait_observer = typename details::uds_trait_observer::type; + +template +inline consteval admissibility_criteria +uds_trait_ac() noexcept +{ + if constexpr(requires { + { + Traits::ac + } -> util::same_as_rmref; + }) + { + return Traits::ac; + } + else { return admissibility_criteria::any; } +} + +template +inline consteval feasibility_criteria +uds_trait_fc() noexcept +{ + if constexpr(requires { + { + Traits::fc + } -> util::same_as_rmref; + }) + { + return Traits::fc; + } + else { return feasibility_criteria::until_exhaustion; } +} + +template +inline consteval reopen_policy +uds_trait_rp() noexcept +{ + if constexpr(requires { + { Traits::rp } -> util::same_as_rmref; + }) + { + return Traits::rp; + } + else { return reopen_policy::no; } +} + } // namespace warthog::search #endif // WARTHOG_SEARCH_UDS_TRAITS_H diff --git a/include/warthog/search/unidirectional_search.h b/include/warthog/search/unidirectional_search.h index 2a04e05..e8e871d 100644 --- a/include/warthog/search/unidirectional_search.h +++ b/include/warthog/search/unidirectional_search.h @@ -41,20 +41,30 @@ namespace warthog::search // (default: search for any solution, until OPEN is exhausted) template< typename H, typename E, typename Q = util::pqueue_min, - typename L = std::tuple<>, - admissibility_criteria AC = admissibility_criteria::any, - feasibility_criteria FC = feasibility_criteria::until_exhaustion, - reopen_policy RP = reopen_policy::no> -class unidirectional_search + typename Traits = uds_default_traits> +class unidirectional_search_full { public: - unidirectional_search( + using traits = Traits; + using search_node = uds_trait_node; + using L = uds_trait_observer; + + static constexpr admissibility_criteria AC = uds_trait_ac(); + static constexpr feasibility_criteria FC = uds_trait_fc(); + static constexpr reopen_policy RP = uds_trait_rp(); + + unidirectional_search_full( H* heuristic, E* expander, Q* queue, L listeners = L{}) : heuristic_(heuristic), expander_(expander), open_(queue), listeners_(listeners) { } + unidirectional_search_full(const unidirectional_search_full& other) + = delete; + ~unidirectional_search_full() = default; - ~unidirectional_search() { } + unidirectional_search_full& + operator=(const unidirectional_search_full& other) + = delete; void get_pathcost(problem_instance* pi, search_parameters* par, solution* sol) @@ -138,14 +148,6 @@ class unidirectional_search Q* open_; [[no_unique_address]] L listeners_; - // no copy ctor - unidirectional_search(const unidirectional_search& other) { } - unidirectional_search& - operator=(const unidirectional_search& other) - { - return *this; - } - /** * Initialise a new 'search_node' for the ongoing search given the parent * node (@param current). @@ -315,6 +317,26 @@ class unidirectional_search } }; +// Keep for backward compatibility. +// Done as class instead of using to support user-defined deduction +template< + typename H, typename E, typename Q = util::pqueue_min, + typename L = std::tuple<>, + admissibility_criteria AC = admissibility_criteria::any, + feasibility_criteria FC = feasibility_criteria::until_exhaustion, + reopen_policy RP = reopen_policy::no> +class unidirectional_search + : public unidirectional_search_full< + H, E, Q, uds_traits> +{ +public: + using unidirectional_search_full = typename unidirectional_search_full< + H, E, Q, + uds_traits>::unidirectional_search_full; + + using unidirectional_search_full::unidirectional_search_full; +}; + template< typename H, typename E, typename Q = util::pqueue_min, typename L = std::tuple<>> diff --git a/include/warthog/util/template.h b/include/warthog/util/template.h index ce94e3d..47213c2 100644 --- a/include/warthog/util/template.h +++ b/include/warthog/util/template.h @@ -108,6 +108,13 @@ choose_integer_sequence(auto value, TemplateFunc&& tfunc) value, std::forward(tfunc)); } +template +concept same_as_rmref + = std::same_as, std::remove_reference_t>; +template +concept same_as_rmcvref + = std::same_as, std::remove_cvref_t>; + } // namespace warthog::util #endif // WARTHOG_UTIL_CAST_H diff --git a/src/io/observer.cpp b/src/io/observer.cpp new file mode 100644 index 0000000..92e1316 --- /dev/null +++ b/src/io/observer.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +namespace warthog::io +{ + +stream_observer::stream_observer( + const std::filesystem::path& filename, std::ios_base::openmode mode) +{ + shared_stream_ = std::make_shared(filename, mode); + stream_ = shared_stream_.get(); +} +stream_observer::stream_observer(std::ostream& stream) +{ + stream_ = &stream; +} +stream_observer::stream_observer(const shared_stream_t& stream) +{ + shared_stream_ = stream; + stream_ = shared_stream_.get(); +} +stream_observer::~stream_observer() = default; + +void +stream_observer::stream_open( + const std::filesystem::path& filename, std::ios_base::openmode mode) +{ + shared_stream_ = std::make_shared(filename, mode); + stream_ = shared_stream_.get(); +} +void +stream_observer::stream(std::ostream& stream) +{ + stream_ = &stream; + shared_stream_ = nullptr; +} +void +stream_observer::stream_share(const shared_stream_t& stream) +{ + shared_stream_ = stream; + stream_ = shared_stream_.get(); +} +void +stream_observer::stream_share(const stream_observer& stream) +{ + shared_stream_ = stream.shared_stream_; + stream_ = stream.stream_; +} +void +stream_observer::stream_stdout() +{ + shared_stream_ = nullptr; + stream_ = &std::cout; +} +void +stream_observer::stream_stderr() +{ + shared_stream_ = nullptr; + stream_ = &std::cerr; +} +void +stream_observer::clear_stream() +{ + shared_stream_ = nullptr; + stream_ = nullptr; +} + +void +posthoc_trace::print_posthoc_header() +{ + if(*this) + { + stream() << R"posthoc(version: 1.4.0 +events: +)posthoc"; + } +} + +} // namespace warthog::io diff --git a/src/io/traces.cpp b/src/io/traces.cpp new file mode 100644 index 0000000..47e8e21 --- /dev/null +++ b/src/io/traces.cpp @@ -0,0 +1,156 @@ +#include +#include +#include + +namespace warthog::io +{ + +void +grid_trace::print_posthoc_header() +{ + if(*this) + { + stream() << R"posthoc(version: 1.4.0 +views: + cell: + - $: rect + width: 1 + height: 1 + x: ${{$.x}} + y: ${{$.y}} + fill: ${{$.fill}} + clear: ${{ $.clear }} + main: + - $: cell + $if: ${{ $.type == 'source' }} + fill: green + clear: false + - $: cell + $if: ${{ $.type == 'destination' }} + fill: red + clear: false + - $: cell + $if: ${{ $.type == 'expand' }} + fill: cyan + clear: false + - $: cell + $if: ${{ $.type == 'expand' }} + fill: blue + clear: close + - $: cell + $if: ${{ $.type == 'generate' }} + fill: purple + clear: false + - $: cell + $if: ${{ $.type == 'generate' }} + fill: orange + clear: true +pivot: + x: ${{ $.x + 0.5 }} + y: ${{ $.y + 0.5 }} + scale: 1 +events: +)posthoc"; + } +} + +void +grid_trace::begin_search(int id, const search::search_problem_instance& pi) +{ + posthoc_trace::begin_search(id); + if(*this) + { + if(grid_ == nullptr) + { + throw std::logic_error("grid_trace::grid_ is null"); + } + uint32_t x, y; + grid_->to_unpadded_xy(pi.start_, x, y); + stream() << std::format( + " - {{ type: source, id: {}, x: {}, y: {} }}\n", pi.start_.id, x, + y); + grid_->to_unpadded_xy(pi.target_, x, y); + stream() << std::format( + " - {{ type: destination, id: {}, x: {}, y: {} }}\n", + pi.target_.id, x, y); + } +} + +void +grid_trace::expand_node(const node& current) const +{ + if(*this) + { + assert(grid_ != nullptr); + std::string pid; + if(auto cpid = current.get_parent(); !cpid.is_none()) + { + pid = std::format(", pId: {}", cpid.id); + } + uint32_t x, y; + grid_->to_unpadded_xy(current.get_id(), x, y); + stream() << std::format( + " - {{ type: expand, id: {}{}, x: {}, y: {}, f: {}, g: {} }}\n", + current.get_id().id, pid, x, y, current.get_f(), current.get_g()); + } +} + +void +grid_trace::relax_node(const node& current) const +{ + if(*this) + { + assert(grid_ != nullptr); + std::string pid; + if(auto cpid = current.get_parent(); !cpid.is_none()) + { + pid = std::format(", pId: {}", cpid.id); + } + uint32_t x, y; + grid_->to_unpadded_xy(current.get_id(), x, y); + stream() << std::format( + " - {{ type: relax, id: {}{}, x: {}, y: {}, f: {}, g: {} }}\n", + current.get_id().id, pid, x, y, current.get_f(), current.get_g()); + } +} + +void +grid_trace::close_node(const node& current) const +{ + if(*this) + { + assert(grid_ != nullptr); + std::string pid; + if(auto cpid = current.get_parent(); !cpid.is_none()) + { + pid = std::format(", pId: {}", cpid.id); + } + uint32_t x, y; + grid_->to_unpadded_xy(current.get_id(), x, y); + stream() << std::format( + " - {{ type: close, id: {}{}, x: {}, y: {}, f: {}, g: {} }}\n", + current.get_id().id, pid, x, y, current.get_f(), current.get_g()); + } +} + +void +grid_trace::generate_node( + const node* parent, const node& child, cost_t, uint32_t) const +{ + if(*this) + { + assert(grid_ != nullptr); + std::string pid; + if(parent != nullptr) + { + pid = std::format(", pId: {}", parent->get_id().id); + } + uint32_t x, y; + grid_->to_unpadded_xy(child.get_id(), x, y); + stream() << std::format( + " - {{ type: generate, id: {}{}, x: {}, y: {}, f: {}, g: {} }}\n", + child.get_id().id, pid, x, y, child.get_f(), child.get_g()); + } +} + +} // namespace warthog::io diff --git a/src/memory/node_pool.cpp b/src/memory/node_pool.cpp index d2df7a1..147bdae 100644 --- a/src/memory/node_pool.cpp +++ b/src/memory/node_pool.cpp @@ -5,16 +5,23 @@ namespace warthog::memory { -node_pool::node_pool(size_t num_nodes) : blocks_(0) +node_pool::node_pool() = default; +node_pool::node_pool(size_t num_nodes) { init(num_nodes); + set_type(); +} + +node_pool::~node_pool() +{ + clear(); } void node_pool::init(size_t num_nodes) { num_blocks_ = ((num_nodes) >> node_pool_ns::LOG2_NBS) + 1; - blocks_ = new search::search_node*[num_blocks_]; + blocks_ = std::make_unique(num_blocks_); for(size_t i = 0; i < num_blocks_; i++) { blocks_[i] = 0; @@ -25,26 +32,6 @@ node_pool::init(size_t num_nodes) // DEFAULT_CHUNK_SIZE and assign addresses // from that pool in order to generate blocks of nodes. when the pool is // full, cpool pre-allocates more, one chunk at a time. - size_t block_sz = node_pool_ns::NBS * sizeof(search::search_node); - blockspool_ = new cpool(block_sz, 1); -} - -node_pool::~node_pool() -{ - // delete [] node_init_; - - blockspool_->reclaim(); - delete blockspool_; - - for(size_t i = 0; i < num_blocks_; i++) - { - if(blocks_[i] != 0) - { - // std::cerr << "deleting block: "<> node_pool_ns::LOG2_NBS; sn_id_t list_id = sn_id_t{node_id} & node_pool_ns::NBS_MASK; - - // id outside the pool address range - if(block_id > num_blocks_) { return 0; } + assert(block_id < num_blocks_); // add a new block of nodes if necessary if(!blocks_[block_id]) { // std::cerr << "generating block: "<allocate()) - search::search_node[node_pool_ns::NBS]; - - // initialise memory - sn_id_t current_id = sn_id_t{node_id} - list_id; - for(uint32_t i = 0; i < node_pool_ns::NBS; i += 8) - { - new(&blocks_[block_id][i]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 1]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 2]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 3]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 4]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 5]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 6]) - search::search_node(pad_id{current_id++}); - new(&blocks_[block_id][i + 7]) - search::search_node(pad_id{current_id++}); - } + blocks_[block_id] + = reinterpret_cast(blockspool_->allocate()); + create_block_(blocks_[block_id], block_id, create_block_data_); } // return the node from its position in the assocated block - return &(blocks_[block_id][list_id]); + return reinterpret_cast( + blocks_[block_id] + list_id * block_type_sizes_); +} + +void +node_pool::release() +{ + num_blocks_ = 0; + blocks_ = nullptr; + blockspool_ = nullptr; + create_block_ = nullptr; } search::search_node* node_pool::get_ptr(pad_id node_id) { - sn_id_t block_id = sn_id_t{node_id} >> node_pool_ns::LOG2_NBS; - sn_id_t list_id = sn_id_t{node_id} & node_pool_ns::NBS_MASK; - - // id outside the pool address range - if(block_id > num_blocks_) { return 0; } - - if(!blocks_[block_id]) { return 0; } - return &(blocks_[block_id][list_id]); + assert((sn_id_t{node_id} >> node_pool_ns::LOG2_NBS) < num_blocks_); + sn_id_t block_id = static_cast(node_id) >> node_pool_ns::LOG2_NBS; + sn_id_t list_id = static_cast(node_id) & node_pool_ns::NBS_MASK; + assert(block_id < num_blocks_); + assert(blocks_[block_id] != nullptr); + return reinterpret_cast( + blocks_[block_id] + list_id * block_type_sizes_); } size_t @@ -112,4 +85,14 @@ node_pool::mem() return bytes; } +void +node_pool::clear() +{ + if(clear_) { (*clear_)(*this); } + blockspool_ = nullptr; + create_block_ = nullptr; + clear_ = nullptr; + create_block_data_ = nullptr; +} + } // namespace warthog::memory diff --git a/src/search/search_node.cpp b/src/search/search_node.cpp index 4e90feb..cae2985 100644 --- a/src/search/search_node.cpp +++ b/src/search/search_node.cpp @@ -1,6 +1,18 @@ #include -unsigned int warthog::search::search_node::refcount_ = 0; +namespace warthog::search +{ + +void +search_node::print(std::ostream& out) const +{ + out << "search_node id:" << get_id().id; + out << " p_id: "; + out << parent_id_.id; + out << " g: " << g_ << " f: " << this->get_f() << " ub: " << ub_ + << " expanded: " << get_expanded() << " " + << " search_number_: " << search_number_; +} std::ostream& operator<<(std::ostream& str, const warthog::search::search_node& sn) @@ -9,3 +21,5 @@ operator<<(std::ostream& str, const warthog::search::search_node& sn) return str; } + +} // namespace warthog::search