diff --git a/include/boost/geometry/extensions/index/rtree/filters.hpp b/include/boost/geometry/extensions/index/rtree/filters.hpp index dcdfbf59c..1c63b0fa4 100644 --- a/include/boost/geometry/extensions/index/rtree/filters.hpp +++ b/include/boost/geometry/extensions/index/rtree/filters.hpp @@ -18,11 +18,11 @@ namespace boost { namespace geometry { namespace index { -template +template class rtree; -template -class query_filter< index::rtree > +template +class query_filter< index::rtree > { public: typedef std::vector result_type; @@ -31,7 +31,7 @@ public: template inline query_filter( - index::rtree const& rtree, + index::rtree const& rtree, Predicates const& pred ) { @@ -47,8 +47,8 @@ private: result_type m_result; }; -template -class nearest_filter< index::rtree > +template +class nearest_filter< index::rtree > { public: typedef std::vector result_type; @@ -57,7 +57,7 @@ public: template inline nearest_filter( - index::rtree const& rtree, + index::rtree const& rtree, DistancesPredicates const& dpred, size_t k, Predicates const& pred diff --git a/include/boost/geometry/extensions/index/rtree/node/node_default.hpp b/include/boost/geometry/extensions/index/rtree/node/node_default.hpp index c32e1f983..48131a1e3 100644 --- a/include/boost/geometry/extensions/index/rtree/node/node_default.hpp +++ b/include/boost/geometry/extensions/index/rtree/node/node_default.hpp @@ -167,36 +167,6 @@ element_indexable( return el.first; } -// create leaf node - -template -inline typename node::type * -create_node(leaf_poly const& l) -{ - typedef typename node::type node; - node * n = new leaf_poly(l); - return n; -} - -// create internal node - -template -inline typename node::type * -create_node(internal_node_poly const& in) -{ - typedef typename node::type node; - node * n = new internal_node_poly(in); - return n; -} - -// default node - -template -inline void delete_node(node_poly * n) -{ - delete n; -} - // nodes elements template @@ -237,6 +207,106 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr) return result; } +// allocators + +template +struct allocators +{ + typedef Allocator allocator_type; + typedef typename allocator_type::size_type size_type; + + typedef typename allocator_type::template rebind< + typename internal_node::type + >::other internal_node_allocator_type; + + typedef typename allocator_type::template rebind< + typename leaf::type + >::other leaf_allocator_type; + + inline explicit allocators(Allocator alloc) + : allocator(alloc) + , internal_node_allocator(allocator) + , leaf_allocator(allocator) + {} + + allocator_type allocator; + internal_node_allocator_type internal_node_allocator; + leaf_allocator_type leaf_allocator; +}; + +// create_node + +template +struct create_node +{ + BOOST_MPL_ASSERT_MSG( + (false), + NOT_IMPLEMENTED_FOR_THIS_NODE_TYPE, + (create_node)); +}; + +template +struct create_node< + Allocators, + internal_node_poly +> +{ + static inline typename node::type * apply(Allocators & allocators) + { + return new internal_node_poly(); + } +}; + +template +struct create_node< + Allocators, + leaf_poly +> +{ + static inline typename node::type * apply(Allocators & allocators) + { + return new leaf_poly(); + } +}; + +// destroy_node + +template +struct destroy_node +{ + BOOST_MPL_ASSERT_MSG( + (false), + NOT_IMPLEMENTED_FOR_THIS_NODE_TYPE, + (destroy_node)); +}; + +template +struct destroy_node< + Allocators, + internal_node_poly +> +{ + static inline void apply(Allocators & allocators, typename node::type * n) + { + delete n; + } +}; + +template +struct destroy_node< + Allocators, + leaf_poly +> +{ + static inline void apply(Allocators & allocators, typename node::type * n) + { + delete n; + } +}; + +// To delete variant node one must pass node * +// To delete poly node one must pass internal_node or leaf + }} // namespace detail::rtree }}} // namespace boost::geometry::index diff --git a/include/boost/geometry/extensions/index/rtree/node/node_default_variant.hpp b/include/boost/geometry/extensions/index/rtree/node/node_default_variant.hpp index 747ee0adf..f98a91a37 100644 --- a/include/boost/geometry/extensions/index/rtree/node/node_default_variant.hpp +++ b/include/boost/geometry/extensions/index/rtree/node/node_default_variant.hpp @@ -147,38 +147,59 @@ element_indexable(std::pair< return el.first; } -// create leaf node +// create_node -template -inline typename node::type * -create_node(leaf_variant const& l) +template +struct create_node< + Allocators, + internal_node_variant +> { - typedef typename node::type node; - node * n = new node(l); - return n; -} + static inline typename node::type * apply(Allocators & allocators) + { + return new typename node::type( + internal_node_variant() ); + } +}; -// create internal node - -template -inline typename node::type * -create_node(internal_node_variant const& in) +template +struct create_node< + Allocators, + leaf_variant +> { - typedef typename node::type node; - node * n = new node(in); - return n; -} + static inline typename node::type * apply(Allocators & allocators) + { + return new typename node::type( + leaf_variant() ); + } +}; -// default node +// destroy_node -template -inline void delete_node(boost::variant< - leaf_variant, - internal_node_variant - > * n) +template +struct destroy_node< + Allocators, + internal_node_variant +> { - delete n; -} + static inline void apply(Allocators & allocators, typename node::type * n) + { + delete n; + } +}; + +template +struct destroy_node< + Allocators, + leaf_variant +> +{ + static inline void apply(Allocators & allocators, typename node::type * n) + { + delete n; + } +}; }} // namespace detail::rtree diff --git a/include/boost/geometry/extensions/index/rtree/rstar/insert.hpp b/include/boost/geometry/extensions/index/rtree/rstar/insert.hpp index 73632c124..2130c9bfc 100644 --- a/include/boost/geometry/extensions/index/rtree/rstar/insert.hpp +++ b/include/boost/geometry/extensions/index/rtree/rstar/insert.hpp @@ -119,11 +119,11 @@ struct level_insert_elements_type<0, Value, Value, Options, Box> >::type type; }; -template +template struct level_insert_base - : public detail::insert + : public detail::insert { - typedef detail::insert base; + typedef detail::insert base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; @@ -135,8 +135,9 @@ struct level_insert_base size_t & leafs_level, Element const& element, Translator const& tr, + Allocators & allocators, size_t relative_level) - : base(root, leafs_level, element, tr, relative_level) + : base(root, leafs_level, element, tr, allocators, relative_level) , result_relative_level(0) {} @@ -192,11 +193,11 @@ struct level_insert_base elements_type result_elements; }; -template +template struct level_insert - : public level_insert_base + : public level_insert_base { - typedef level_insert_base base; + typedef level_insert_base base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; @@ -205,8 +206,9 @@ struct level_insert size_t & leafs_level, Element const& element, Translator const& tr, + Allocators & allocators, size_t relative_level) - : base(root, leafs_level, element, tr, relative_level) + : base(root, leafs_level, element, tr, allocators, relative_level) {} inline void operator()(internal_node & n) @@ -257,11 +259,11 @@ struct level_insert } }; -template -struct level_insert - : public level_insert_base +template +struct level_insert + : public level_insert_base { - typedef level_insert_base base; + typedef level_insert_base base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; @@ -270,8 +272,9 @@ struct level_insert size_t & leafs_level, Value const& v, Translator const& t, + Allocators & allocators, size_t relative_level) - : base(root, leafs_level, v, t, relative_level) + : base(root, leafs_level, v, t, allocators, relative_level) {} inline void operator()(internal_node & n) @@ -303,11 +306,11 @@ struct level_insert } }; -template -struct level_insert<0, Value, Value, Options, Translator, Box> - : public level_insert_base<0, Value, Value, Options, Translator, Box> +template +struct level_insert<0, Value, Value, Options, Translator, Box, Allocators> + : public level_insert_base<0, Value, Value, Options, Translator, Box, Allocators> { - typedef level_insert_base<0, Value, Value, Options, Translator, Box> base; + typedef level_insert_base<0, Value, Value, Options, Translator, Box, Allocators> base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; @@ -316,8 +319,9 @@ struct level_insert<0, Value, Value, Options, Translator, Box> size_t & leafs_level, Value const& v, Translator const& t, + Allocators & allocators, size_t relative_level) - : base(root, leafs_level, v, t, relative_level) + : base(root, leafs_level, v, t, allocators, relative_level) {} inline void operator()(internal_node & n) @@ -349,8 +353,8 @@ struct level_insert<0, Value, Value, Options, Translator, Box> } // namespace detail // R*-tree insert visitor -template -class insert +template +class insert : public rtree::visitor::type , index::nonassignable { @@ -364,17 +368,18 @@ public: size_t & leafs_level, Element const& element, Translator const& tr, + Allocators & allocators, size_t relative_level = 0) : m_root(root), m_leafs_level(leafs_level), m_element(element) - , m_tr(tr), m_relative_level(relative_level) + , m_tr(tr), m_relative_level(relative_level), m_allocators(allocators) {} inline void operator()(internal_node & BOOST_GEOMETRY_INDEX_ASSERT_UNUSED_PARAM(n)) { BOOST_GEOMETRY_INDEX_ASSERT(&n == rtree::get(m_root), "current node should be the root"); - detail::rstar::level_insert<0, Element, Value, Options, Translator, Box> lins_v( - m_root, m_leafs_level, m_element, m_tr, m_relative_level); + detail::rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v( + m_root, m_leafs_level, m_element, m_tr, m_allocators, m_relative_level); rtree::apply_visitor(lins_v, *m_root); @@ -388,8 +393,8 @@ public: { BOOST_GEOMETRY_INDEX_ASSERT(&n == rtree::get(m_root), "current node should be the root"); - detail::rstar::level_insert<0, Element, Value, Options, Translator, Box> lins_v( - m_root, m_leafs_level, m_element, m_tr, m_relative_level); + detail::rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v( + m_root, m_leafs_level, m_element, m_tr, m_allocators, m_relative_level); rtree::apply_visitor(lins_v, *m_root); @@ -407,8 +412,8 @@ private: for ( typename Elements::const_reverse_iterator it = elements.rbegin(); it != elements.rend(); ++it) { - detail::rstar::level_insert<1, element_type, Value, Options, Translator, Box> lins_v( - m_root, m_leafs_level, *it, m_tr, relative_level); + detail::rstar::level_insert<1, element_type, Value, Options, Translator, Box, Allocators> lins_v( + m_root, m_leafs_level, *it, m_tr, m_allocators, relative_level); rtree::apply_visitor(lins_v, *m_root); @@ -427,6 +432,8 @@ private: Element const& m_element; Translator const& m_tr; size_t m_relative_level; + + Allocators m_allocators; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/extensions/index/rtree/rtree.hpp b/include/boost/geometry/extensions/index/rtree/rtree.hpp index 06c77cf67..5cbd99d26 100644 --- a/include/boost/geometry/extensions/index/rtree/rtree.hpp +++ b/include/boost/geometry/extensions/index/rtree/rtree.hpp @@ -64,7 +64,8 @@ namespace boost { namespace geometry { namespace index { template < typename Value, typename Parameters, - typename Translator = translator::def + typename Translator = translator::def, + typename Allocator = std::allocator > class rtree : public boost::noncopyable @@ -82,17 +83,22 @@ public: typedef typename detail::rtree::internal_node::type internal_node; typedef typename detail::rtree::leaf::type leaf; - inline explicit rtree(translator_type const& translator = translator_type()) + typedef Allocator allocator_type; + typedef detail::rtree::allocators allocators_type; + typedef typename allocators_type::size_type size_type; + + inline explicit rtree(translator_type const& translator = translator_type(), Allocator allocator = std::allocator()) : m_values_count(0) , m_root(0) , m_leafs_level(0) , m_translator(translator) + , m_allocators(allocator) { create(); } template - inline explicit rtree(Iterator first, Iterator last, translator_type const& translator = translator_type()) + inline explicit rtree(Iterator first, Iterator last, translator_type const& translator = translator_type(), Allocator allocator = std::allocator()) : m_values_count(0) , m_root(0) , m_leafs_level(0) @@ -108,6 +114,7 @@ public: } inline rtree(rtree const& src) + : m_allocators(src.m_allocators) { copy(src, *this); } @@ -118,6 +125,8 @@ public: return *this; destroy(*this); + + m_allocators = src.m_allocators; copy(src, *this); return *this; @@ -133,8 +142,9 @@ public: options_type, translator_type, box_type, + allocators_type, typename options_type::insert_tag - > insert_v(m_root, m_leafs_level, value, m_translator); + > insert_v(m_root, m_leafs_level, value, m_translator, m_allocators); detail::rtree::apply_visitor(insert_v, *m_root); @@ -158,8 +168,9 @@ public: value_type, options_type, translator_type, - box_type - > remove_v(m_root, m_leafs_level, value, m_translator); + box_type, + allocators_type + > remove_v(m_root, m_leafs_level, value, m_translator, m_allocators); detail::rtree::apply_visitor(remove_v, *m_root); @@ -174,7 +185,7 @@ public: } template - inline size_t query(Predicates const& pred, OutIter out_it) const + inline size_type query(Predicates const& pred, OutIter out_it) const { detail::rtree::visitors::query find_v(m_translator, pred, out_it); @@ -185,30 +196,30 @@ public: } template - inline size_t nearest(DistancePredicate const& dpred, value_type & v) const + inline size_type nearest(DistancePredicate const& dpred, value_type & v) const { return nearest_one(dpred, detail::empty(), v); } template - inline size_t nearest(DistancePredicate const& dpred, Predicates const& pred, value_type & v) const + inline size_type nearest(DistancePredicate const& dpred, Predicates const& pred, value_type & v) const { return nearest_one(dpred, pred, v); } template - inline size_t nearest(DistancePredicate const& dpred, size_t k, OutIter out_it) const + inline size_type nearest(DistancePredicate const& dpred, size_t k, OutIter out_it) const { return nearest_k(dpred, k, detail::empty(), out_it); } template - inline size_t nearest(DistancePredicate const& dpred, size_t k, Predicates const& pred, OutIter out_it) const + inline size_type nearest(DistancePredicate const& dpred, size_t k, Predicates const& pred, OutIter out_it) const { return nearest_k(dpred, k, pred, out_it); } - inline size_t size() const + inline size_type size() const { return m_values_count; } @@ -252,12 +263,12 @@ public: return m_translator; } - inline size_t values_count() const + inline size_type values_count() const { return m_values_count; } - inline size_t depth() const + inline size_type depth() const { return m_leafs_level; } @@ -265,16 +276,15 @@ public: private: inline void create() { - m_root = detail::rtree::create_node(leaf()); + m_root = detail::rtree::create_node::apply(m_allocators); m_values_count = 0; m_leafs_level = 0; } inline void destroy(rtree & t) { - detail::rtree::visitors::destroy del_v; + detail::rtree::visitors::destroy del_v(t.m_root, t.m_allocators); detail::rtree::apply_visitor(del_v, *t.m_root); - detail::rtree::delete_node(t.m_root); t.m_root = 0; t.m_values_count = 0; @@ -283,7 +293,9 @@ private: inline void copy(rtree const& src, rtree & dst) const { - detail::rtree::visitors::copy copy_v; + //dst.m_allocators = src.m_allocators; + + detail::rtree::visitors::copy copy_v(dst.m_allocators); detail::rtree::apply_visitor(copy_v, *src.m_root); dst.m_root = copy_v.result; @@ -293,7 +305,7 @@ private: } template - inline size_t nearest_one(DistancesPredicates const& dpred, Predicates const& pred, value_type & v) const + inline size_type nearest_one(DistancesPredicates const& dpred, Predicates const& pred, value_type & v) const { typedef typename detail::point_relation::type point_relation; typedef typename detail::relation::value_type point_type; @@ -322,7 +334,7 @@ private: } template - inline size_t nearest_k(DistancesPredicates const& dpred, size_t k, Predicates const& pred, OutIter out_it) const + inline size_type nearest_k(DistancesPredicates const& dpred, size_t k, Predicates const& pred, OutIter out_it) const { typedef typename detail::point_relation::type point_relation; typedef typename detail::relation::value_type point_type; @@ -350,87 +362,88 @@ private: return result.get(out_it); } - size_t m_values_count; + size_type m_values_count; node *m_root; - size_t m_leafs_level; + size_type m_leafs_level; translator_type m_translator; + allocators_type m_allocators; }; -template -inline void insert(rtree & tree, Value const& v) +template +inline void insert(rtree & tree, Value const& v) { tree.insert(v); } -template -inline void insert(rtree & tree, Iterator first, Iterator last) +template +inline void insert(rtree & tree, Iterator first, Iterator last) { tree.insert(first, last); } -template -inline void remove(rtree & tree, Value const& v) +template +inline void remove(rtree & tree, Value const& v) { tree.remove(v); } -template -inline void remove(rtree & tree, Iterator first, Iterator last) +template +inline void remove(rtree & tree, Iterator first, Iterator last) { tree.remove(first, last); } -template -inline size_t query(rtree const& tree, Predicates const& pred, OutIter out_it) +template +inline size_t query(rtree const& tree, Predicates const& pred, OutIter out_it) { return tree.query(pred, out_it); } -template -inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, Value & v) +template +inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, Value & v) { return tree.nearest(dpred, v); } -template -inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, Predicates const& pred, Value & v) +template +inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, Predicates const& pred, Value & v) { return tree.nearest(dpred, pred, v); } -template -inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, size_t k, OutIter out_it) +template +inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, size_t k, OutIter out_it) { return tree.nearest(dpred, k, out_it); } -template -inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, size_t k, Predicates const& pred, OutIter out_it) +template +inline size_t nearest(rtree const& tree, DistancesPredicates const& dpred, size_t k, Predicates const& pred, OutIter out_it) { return tree.nearest(dpred, k, pred, out_it); } -template -inline void clear(rtree & tree) +template +inline void clear(rtree & tree) { return tree.clear(); } -template -inline size_t size(rtree const& tree) +template +inline size_t size(rtree const& tree) { return tree.size(); } -template -inline bool empty(rtree const& tree) +template +inline bool empty(rtree const& tree) { return tree.empty(); } -template -inline typename rtree::box_type -box(rtree const& tree) +template +inline typename rtree::box_type +box(rtree const& tree) { return tree.box(); } diff --git a/include/boost/geometry/extensions/index/rtree/visitors/copy.hpp b/include/boost/geometry/extensions/index/rtree/visitors/copy.hpp index 26bdd8737..31ea2b783 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/copy.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/copy.hpp @@ -16,21 +16,24 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template -struct copy +template +class copy : public rtree::visitor::type + , boost::noncopyable { +public: typedef typename rtree::node::type node; typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; - explicit inline copy() + explicit inline copy(Allocators & allocators) : result(0) + , m_allocators(allocators) {} inline void operator()(internal_node & n) { - node * new_node = rtree::create_node(internal_node()); + node * new_node = rtree::create_node::apply(m_allocators); typedef typename rtree::elements_type::type elements_type; elements_type & elements = rtree::elements(n); @@ -50,7 +53,7 @@ struct copy inline void operator()(leaf & l) { - node * new_node = rtree::create_node(leaf()); + node * new_node = rtree::create_node::apply(m_allocators); typedef typename rtree::elements_type::type elements_type; elements_type & elements = rtree::elements(l); @@ -67,6 +70,9 @@ struct copy } node * result; + +private: + Allocators & m_allocators; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/extensions/index/rtree/visitors/destroy.hpp b/include/boost/geometry/extensions/index/rtree/visitors/destroy.hpp index d5a16f4ba..15fe5b126 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/destroy.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/destroy.hpp @@ -16,28 +16,50 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template -struct destroy : public rtree::visitor::type +template +class destroy + : public rtree::visitor::type + , boost::noncopyable { +public: + typedef typename rtree::node::type node; typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; + inline destroy(node * root_node, Allocators & allocators) + : m_current_node(root_node) + , m_allocators(allocators) + {} + inline void operator()(internal_node & n) { + BOOST_GEOMETRY_INDEX_ASSERT(&n == rtree::get(m_current_node), "invalid pointers"); + + node * node_to_destroy = m_current_node; + typedef typename rtree::elements_type::type elements_type; elements_type & elements = rtree::elements(n); for (typename elements_type::iterator it = elements.begin(); it != elements.end(); ++it) { - rtree::apply_visitor(*this, *it->second); - rtree::delete_node(it->second); + m_current_node = it->second; + rtree::apply_visitor(*this, *m_current_node); } + + rtree::destroy_node::apply(m_allocators, node_to_destroy); } - inline void operator()(leaf &n) + inline void operator()(leaf & l) { + BOOST_GEOMETRY_INDEX_ASSERT(&l == rtree::get(m_current_node), "invalid pointers"); + + rtree::destroy_node::apply(m_allocators, m_current_node); } + +private: + node * m_current_node; + Allocators & m_allocators; }; }}} // namespace detail::rtree::visitors diff --git a/include/boost/geometry/extensions/index/rtree/visitors/insert.hpp b/include/boost/geometry/extensions/index/rtree/visitors/insert.hpp index e42ff494d..c164186c3 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/insert.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/insert.hpp @@ -101,16 +101,17 @@ protected: typedef typename Options::parameters_type parameters_type; public: - template + template static inline void apply(node* & root_node, size_t & leafs_level, Node & n, internal_node *parent_node, size_t current_child_index, - Translator const& tr) + Translator const& tr, + Allocators & allocators) { // create additional node - node * second_node = rtree::create_node(Node()); + node * second_node = rtree::create_node::apply(allocators); Node & n2 = rtree::get(*second_node); // redistribute elements @@ -140,7 +141,7 @@ public: BOOST_GEOMETRY_INDEX_ASSERT(&n == rtree::get(root_node), "node should be the root"); // create new root and add nodes - node * new_root = rtree::create_node(internal_node()); + node * new_root = rtree::create_node::apply(allocators); rtree::elements(rtree::get(*new_root)).push_back(std::make_pair(box1, root_node)); rtree::elements(rtree::get(*new_root)).push_back(std::make_pair(box2, second_node)); @@ -154,7 +155,7 @@ public: // ----------------------------------------------------------------------- // // Default insert visitor -template +template class insert : public rtree::visitor::type , index::nonassignable @@ -170,6 +171,7 @@ protected: size_t & leafs_level, Element const& element, Translator const& t, + Allocators & allocators, size_t relative_level = 0 ) : m_element(element) @@ -181,6 +183,7 @@ protected: , m_parent(0) , m_current_child_index(0) , m_current_level(0) + , m_allocators(allocators) { BOOST_GEOMETRY_INDEX_ASSERT(m_relative_level <= leafs_level, "unexpected level value"); BOOST_GEOMETRY_INDEX_ASSERT(m_level <= m_leafs_level, "unexpected level value"); @@ -245,7 +248,7 @@ protected: template inline void split(Node & n) const { - detail::split::apply(m_root_node, m_leafs_level, n, m_parent, m_current_child_index, m_tr); + detail::split::apply(m_root_node, m_leafs_level, n, m_parent, m_current_child_index, m_tr, m_allocators); } // TODO: awulkiew - implement dispatchable split::apply to enable additional nodes creation @@ -262,20 +265,22 @@ protected: internal_node *m_parent; size_t m_current_child_index; size_t m_current_level; + + Allocators & m_allocators; }; } // namespace detail // Insert visitor forward declaration -template +template struct insert; // Default insert visitor used for nodes elements -template -struct insert - : public detail::insert +template +struct insert + : public detail::insert { - typedef detail::insert base; + typedef detail::insert base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; @@ -284,9 +289,10 @@ struct insert size_t & leafs_level, Element const& element, Translator const& tr, + Allocators & allocators, size_t relative_level = 0 ) - : base(root, leafs_level, element, tr, relative_level) + : base(root, leafs_level, element, tr, allocators, relative_level) {} inline void operator()(internal_node & n) @@ -316,11 +322,11 @@ struct insert }; // Default insert visitor specialized for Values elements -template -struct insert - : public detail::insert +template +struct insert + : public detail::insert { - typedef detail::insert base; + typedef detail::insert base; typedef typename base::node node; typedef typename base::internal_node internal_node; typedef typename base::leaf leaf; @@ -329,9 +335,10 @@ struct insert size_t & leafs_level, Value const& v, Translator const& t, + Allocators & allocators, size_t relative_level = 0 ) - : base(root, leafs_level, v, t, relative_level) + : base(root, leafs_level, v, t, allocators, relative_level) {} inline void operator()(internal_node & n) diff --git a/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp b/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp index 326a5a050..3a743585e 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp @@ -21,7 +21,7 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { // Default remove algorithm -template +template class remove : public rtree::visitor::type , index::nonassignable @@ -36,9 +36,11 @@ public: inline remove(node* & root, size_t & leafs_level, Value const& v, - Translator const& t) + Translator const& t, + Allocators & allocators) : m_value(v) , m_tr(t) + , m_allocators(allocators) , m_root_node(root) , m_leafs_level(leafs_level) , m_is_value_removed(false) @@ -115,16 +117,27 @@ public: is_leaf ilv; rtree::apply_visitor(ilv, *it->second); if ( ilv.result ) + { reinsert_elements(rtree::get(*it->second), it->first); + + rtree::destroy_node::apply(m_allocators, it->second); + } else + { reinsert_elements(rtree::get(*it->second), it->first); + + rtree::destroy_node::apply(m_allocators, it->second); + } } // shorten the tree if ( rtree::elements(n).size() == 1 ) { + node * root_to_destroy = m_root_node; m_root_node = rtree::elements(n)[0].second; --m_leafs_level; + + rtree::destroy_node::apply(m_allocators, root_to_destroy); } } } @@ -190,11 +203,20 @@ private: for ( typename elements_type::iterator it = elements.begin(); it != elements.end() ; ++it ) { - visitors::insert insert_v( + visitors::insert< + typename elements_type::value_type, + Value, + Options, + Translator, + Box, + Allocators, + typename Options::insert_tag + > insert_v( m_root_node, m_leafs_level, *it, m_tr, + m_allocators, node_relative_level - 1); rtree::apply_visitor(insert_v, *m_root_node); @@ -203,6 +225,7 @@ private: Value const& m_value; Translator const& m_tr; + Allocators & m_allocators; node* & m_root_node; size_t & m_leafs_level; diff --git a/tests/rtree_function.hpp b/tests/rtree_function.hpp index 3eb92a484..0d73289e4 100644 --- a/tests/rtree_function.hpp +++ b/tests/rtree_function.hpp @@ -228,7 +228,7 @@ Box values_box(Iter first, Iter last, Translator const& tr) } // namespace helpers template -void random_query_check(Rtree const& t, Rtree const& t_copy, Cont const& c, size_t n, Randomizer r) +void random_query_check(Rtree const& t, Cont const& c, size_t n, Randomizer r) { namespace bg = boost::geometry; namespace bgi = bg::index; @@ -237,32 +237,28 @@ void random_query_check(Rtree const& t, Rtree const& t_copy, Cont const& c, size { Predicate pred = Predicate(r()); - std::vector res1, res2, res3; + std::vector res1, res2; bgi::query(t, pred, std::back_inserter(res1)); - bgi::query(t_copy, pred, std::back_inserter(res2)); for ( typename Cont::const_iterator it = c.begin() ; it != c.end() ; ++it ) { if ( bgi::predicates_check(pred, *it, t.translator()(*it)) ) - res3.push_back(*it); + res2.push_back(*it); } std::stringstream ss; ss << "\nPredicate: " << typeid(Predicate).name() << "\n" << "res1: " << res1.size() - << ", res2: " << res2.size() - << ", res3: " << res3.size() << '\n'; + << ", res2: " << res2.size()<< '\n'; BOOST_CHECK_MESSAGE( helpers::results_compare(res1, res2, t.translator()), ss.str()); - BOOST_CHECK_MESSAGE( helpers::results_compare(res1, res3, t.translator()), ss.str()); } } template void random_nearest_check( Rtree const& t, - Rtree const& t_copy, Cont const& c, size_t n, PointRandomizer const& pr, @@ -277,36 +273,32 @@ void random_nearest_check( typename PointRandomizer::value_type pt = pr(); Predicate pred = Predicate(r()); - std::vector res1, res2, res3; + std::vector res1, res2; bgi::nearest(t, pt, k, pred, std::back_inserter(res1)); - bgi::nearest(t_copy, pt, k, pred, std::back_inserter(res2)); - for ( typename Cont::const_iterator it = c.begin() ; it != c.end() ; ++it ) { if ( bgi::predicates_check(pred, *it, t.translator()(*it)) ) - res3.push_back(*it); + res2.push_back(*it); } std::sort( - res3.begin(), - res3.end(), + res2.begin(), + res2.end(), helpers::val_mindist_cmp< typename PointRandomizer::value_type, typename Rtree::translator_type >(pt, t.translator()) ); - if ( k < res3.size() ) - res3.resize(k); + if ( k < res2.size() ) + res2.resize(k); std::stringstream ss; ss << "\nPredicate: " << typeid(Predicate).name() << "\n" << "res1: " << res1.size() - << ", res2: " << res2.size() - << ", res3: " << res3.size() << '\n'; + << ", res2: " << res2.size() << '\n'; BOOST_CHECK_MESSAGE(helpers::nearest_results_compare(pt, res1, res2, t.translator()), ss.str()); - BOOST_CHECK_MESSAGE(helpers::nearest_results_compare(pt, res1, res3, t.translator()), ss.str()); } } @@ -317,26 +309,26 @@ template struct tests_rtree_function_queries { template - inline static void apply(Rtree const& t, Rtree const& t_copy, Cont const& v) + inline static void apply(Rtree const& t, Cont const& v) { namespace bgi = boost::geometry::index; - random_query_check(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); + random_query_check(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); - random_nearest_check(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, bgi::empty); - random_nearest_check(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check(t, v, 5, helpers::value_randomizer

(10, 0), 3, bgi::empty); + random_nearest_check(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); } }; @@ -344,29 +336,29 @@ template struct tests_rtree_function_queries { template - inline static void apply(Rtree const& t, Rtree const& t_copy, Cont const& v) + inline static void apply(Rtree const& t, Cont const& v) { namespace bgi = boost::geometry::index; - random_query_check(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); - random_query_check >(t, t_copy, v, 5, helpers::value_randomizer(10, 5)); + random_query_check(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); + random_query_check >(t, v, 5, helpers::value_randomizer(10, 5)); - random_nearest_check(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, bgi::empty); - random_nearest_check(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); - random_nearest_check >(t, t_copy, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check(t, v, 5, helpers::value_randomizer

(10, 0), 3, bgi::empty); + random_nearest_check(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); + random_nearest_check >(t, v, 5, helpers::value_randomizer

(10, 0), 3, helpers::value_randomizer(10, 5)); } }; @@ -395,7 +387,7 @@ void tests_rtree_function(Translator const& tr = Translator()) B bv = helpers::values_box(v.begin(), v.end(), tr); BOOST_CHECK(bg::equals(bt, bv)); - tests_rtree_function_queries::type>::apply(t, t_copy, v); + tests_rtree_function_queries::type>::apply(t, v); bgi::clear(t); BOOST_CHECK(bgi::empty(t)); @@ -403,6 +395,12 @@ void tests_rtree_function(Translator const& tr = Translator()) B be; bg::assign_inverse(be); BOOST_CHECK(bg::equals(be, bt)); + + for ( size_t i = 3 ; i < 10 ; ++i ) + bgi::remove(t_copy, v[i]); + v.erase(v.begin() + 3, v.end()); + + tests_rtree_function_queries::type>::apply(t_copy, v); } BOOST_AUTO_TEST_CASE(tests_rtree_function_box3f)