update boost
This commit is contained in:
@@ -4,6 +4,10 @@
|
||||
//
|
||||
// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// This file was modified by Oracle on 2019-2021.
|
||||
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -23,25 +27,28 @@
|
||||
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/rtree/node/node.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/options.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
namespace detail { namespace rtree {
|
||||
|
||||
template <typename Value, typename Options, typename Box, typename Allocators>
|
||||
class choose_next_node<Value, Options, Box, Allocators, choose_by_overlap_diff_tag>
|
||||
template <typename MembersHolder>
|
||||
class choose_next_node<MembersHolder, choose_by_overlap_diff_tag>
|
||||
{
|
||||
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
|
||||
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
||||
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
||||
typedef typename MembersHolder::box_type box_type;
|
||||
typedef typename MembersHolder::parameters_type parameters_type;
|
||||
|
||||
typedef typename MembersHolder::node node;
|
||||
typedef typename MembersHolder::internal_node internal_node;
|
||||
typedef typename MembersHolder::leaf leaf;
|
||||
|
||||
typedef typename rtree::elements_type<internal_node>::type children_type;
|
||||
typedef typename children_type::value_type child_type;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
|
||||
typedef typename index::detail::default_content_result<Box>::type content_type;
|
||||
typedef typename index::detail::default_content_result<box_type>::type content_type;
|
||||
|
||||
public:
|
||||
template <typename Indexable>
|
||||
@@ -53,15 +60,20 @@ public:
|
||||
::boost::ignore_unused(parameters);
|
||||
|
||||
children_type & children = rtree::elements(n);
|
||||
|
||||
|
||||
// children are leafs
|
||||
if ( node_relative_level <= 1 )
|
||||
{
|
||||
return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
|
||||
return choose_by_minimum_overlap_cost(children, indexable,
|
||||
parameters.get_overlap_cost_threshold(),
|
||||
index::detail::get_strategy(parameters));
|
||||
}
|
||||
// children are internal nodes
|
||||
else
|
||||
return choose_by_minimum_content_cost(children, indexable);
|
||||
{
|
||||
return choose_by_minimum_content_cost(children, indexable,
|
||||
index::detail::get_strategy(parameters));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -79,10 +91,11 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indexable>
|
||||
template <typename Indexable, typename Strategy>
|
||||
static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
|
||||
Indexable const& indexable,
|
||||
size_t overlap_cost_threshold)
|
||||
size_t overlap_cost_threshold,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
const size_t children_count = children.size();
|
||||
|
||||
@@ -99,8 +112,8 @@ private:
|
||||
child_type const& ch_i = children[i];
|
||||
|
||||
// expanded child node's box
|
||||
Box box_exp(ch_i.first);
|
||||
geometry::expand(box_exp, indexable);
|
||||
box_type box_exp(ch_i.first);
|
||||
index::detail::expand(box_exp, indexable, strategy);
|
||||
|
||||
// areas difference
|
||||
content_type content = index::detail::content(box_exp);
|
||||
@@ -131,7 +144,11 @@ private:
|
||||
}
|
||||
|
||||
// calculate minimum or nearly minimum overlap cost
|
||||
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable, first_n_children_count, children_count, children_contents);
|
||||
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable,
|
||||
first_n_children_count,
|
||||
children_count,
|
||||
children_contents,
|
||||
strategy);
|
||||
}
|
||||
|
||||
return choosen_index;
|
||||
@@ -143,12 +160,13 @@ private:
|
||||
|| (p1.content_diff == p2.content_diff && (p1.content) < (p2.content));
|
||||
}
|
||||
|
||||
template <typename Indexable, typename ChildrenContents>
|
||||
template <typename Indexable, typename ChildrenContents, typename Strategy>
|
||||
static inline size_t choose_by_minimum_overlap_cost_first_n(children_type const& children,
|
||||
Indexable const& indexable,
|
||||
size_t const first_n_children_count,
|
||||
size_t const children_count,
|
||||
ChildrenContents const& children_contents)
|
||||
ChildrenContents const& children_contents,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(first_n_children_count <= children_count, "unexpected value");
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements");
|
||||
@@ -168,9 +186,9 @@ private:
|
||||
|
||||
child_type const& ch_i = children[i];
|
||||
|
||||
Box box_exp(ch_i.first);
|
||||
box_type box_exp(ch_i.first);
|
||||
// calculate expanded box of child node ch_i
|
||||
geometry::expand(box_exp, indexable);
|
||||
index::detail::expand(box_exp, indexable, strategy);
|
||||
|
||||
content_type overlap_diff = 0;
|
||||
|
||||
@@ -181,10 +199,10 @@ private:
|
||||
{
|
||||
child_type const& ch_j = children[j];
|
||||
|
||||
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
|
||||
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first, strategy);
|
||||
if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
|
||||
{
|
||||
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
|
||||
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first, strategy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,8 +223,10 @@ private:
|
||||
return choosen_index;
|
||||
}
|
||||
|
||||
template <typename Indexable>
|
||||
static inline size_t choose_by_minimum_content_cost(children_type const& children, Indexable const& indexable)
|
||||
template <typename Indexable, typename Strategy>
|
||||
static inline size_t choose_by_minimum_content_cost(children_type const& children,
|
||||
Indexable const& indexable,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
size_t children_count = children.size();
|
||||
|
||||
@@ -221,8 +241,8 @@ private:
|
||||
child_type const& ch_i = children[i];
|
||||
|
||||
// expanded child node's box
|
||||
Box box_exp(ch_i.first);
|
||||
geometry::expand(box_exp, indexable);
|
||||
box_type box_exp(ch_i.first);
|
||||
index::detail::expand(box_exp, indexable, strategy);
|
||||
|
||||
// areas difference
|
||||
content_type content = index::detail::content(box_exp);
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
//
|
||||
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// This file was modified by Oracle on 2019-2023.
|
||||
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -11,9 +16,17 @@
|
||||
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
|
||||
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/centroid.hpp>
|
||||
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/content.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
|
||||
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
@@ -21,15 +34,47 @@ namespace detail { namespace rtree { namespace visitors {
|
||||
|
||||
namespace rstar {
|
||||
|
||||
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
// Utility to distinguish between default and non-default index strategy
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
struct comparable_distance
|
||||
{
|
||||
typedef typename geometry::comparable_distance_result
|
||||
<
|
||||
Point1, Point2, Strategy
|
||||
>::type result_type;
|
||||
|
||||
static inline result_type call(Point1 const& p1, Point2 const& p2, Strategy const& s)
|
||||
{
|
||||
return geometry::comparable_distance(p1, p2, s);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct comparable_distance<Point1, Point2, default_strategy>
|
||||
{
|
||||
typedef typename geometry::default_comparable_distance_result
|
||||
<
|
||||
Point1, Point2
|
||||
>::type result_type;
|
||||
|
||||
static inline result_type call(Point1 const& p1, Point2 const& p2, default_strategy const& )
|
||||
{
|
||||
return geometry::comparable_distance(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MembersHolder>
|
||||
class remove_elements_to_reinsert
|
||||
{
|
||||
public:
|
||||
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
|
||||
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
||||
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
||||
typedef typename MembersHolder::box_type box_type;
|
||||
typedef typename MembersHolder::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::translator_type translator_type;
|
||||
typedef typename MembersHolder::allocators_type allocators_type;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::node node;
|
||||
typedef typename MembersHolder::internal_node internal_node;
|
||||
typedef typename MembersHolder::leaf leaf;
|
||||
|
||||
//typedef typename Allocators::internal_node_pointer internal_node_pointer;
|
||||
typedef internal_node * internal_node_pointer;
|
||||
@@ -40,16 +85,19 @@ public:
|
||||
internal_node_pointer parent,
|
||||
size_t current_child_index,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators)
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators)
|
||||
{
|
||||
typedef typename rtree::elements_type<Node>::type elements_type;
|
||||
typedef typename elements_type::value_type element_type;
|
||||
typedef typename geometry::point_type<Box>::type point_type;
|
||||
typedef typename geometry::point_type<box_type>::type point_type;
|
||||
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
|
||||
// TODO: awulkiew - change second point_type to the point type of the Indexable?
|
||||
typedef typename
|
||||
geometry::default_comparable_distance_result<point_type>::type
|
||||
comparable_distance_type;
|
||||
typedef rstar::comparable_distance
|
||||
<
|
||||
point_type, point_type, strategy_type
|
||||
> comparable_distance_pp;
|
||||
typedef typename comparable_distance_pp::result_type comparable_distance_type;
|
||||
|
||||
elements_type & elements = rtree::elements(n);
|
||||
|
||||
@@ -60,9 +108,12 @@ public:
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected elements number");
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(0 < reinserted_elements_count, "wrong value of elements to reinsert");
|
||||
|
||||
auto const& strategy = index::detail::get_strategy(parameters);
|
||||
|
||||
// calculate current node's center
|
||||
point_type node_center;
|
||||
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center);
|
||||
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center,
|
||||
strategy);
|
||||
|
||||
// fill the container of centers' distances of children from current node's center
|
||||
typedef typename index::detail::rtree::container_from_elements_type<
|
||||
@@ -73,14 +124,15 @@ public:
|
||||
sorted_elements_type sorted_elements;
|
||||
// If constructor is used instead of resize() MS implementation leaks here
|
||||
sorted_elements.reserve(elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
|
||||
|
||||
|
||||
for ( typename elements_type::const_iterator it = elements.begin() ;
|
||||
it != elements.end() ; ++it )
|
||||
{
|
||||
point_type element_center;
|
||||
geometry::centroid( rtree::element_indexable(*it, translator), element_center);
|
||||
geometry::centroid(rtree::element_indexable(*it, translator), element_center,
|
||||
strategy);
|
||||
sorted_elements.push_back(std::make_pair(
|
||||
geometry::comparable_distance(node_center, element_center),
|
||||
comparable_distance_pp::call(node_center, element_center, strategy),
|
||||
*it)); // MAY THROW (V, E: copy)
|
||||
}
|
||||
|
||||
@@ -118,7 +170,7 @@ public:
|
||||
for ( typename sorted_elements_type::iterator it = sorted_elements.begin() ;
|
||||
it != sorted_elements.end() ; ++it )
|
||||
{
|
||||
destroy_element<Value, Options, Translator, Box, Allocators>::apply(it->second, allocators);
|
||||
destroy_element<MembersHolder>::apply(it->second, allocators);
|
||||
}
|
||||
|
||||
BOOST_RETHROW // RETHROW
|
||||
@@ -136,7 +188,7 @@ private:
|
||||
{
|
||||
return d1.first < d2.first;
|
||||
}
|
||||
|
||||
|
||||
template <typename Distance, typename El>
|
||||
static inline bool distances_dsc(
|
||||
std::pair<Distance, El> const& d1,
|
||||
@@ -146,48 +198,69 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Box, typename Allocators>
|
||||
template
|
||||
<
|
||||
size_t InsertIndex,
|
||||
typename Element,
|
||||
typename MembersHolder,
|
||||
bool IsValue = std::is_same<Element, typename MembersHolder::value_type>::value
|
||||
>
|
||||
struct level_insert_elements_type
|
||||
{
|
||||
typedef typename rtree::elements_type<
|
||||
typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type
|
||||
typename rtree::internal_node<
|
||||
typename MembersHolder::value_type,
|
||||
typename MembersHolder::parameters_type,
|
||||
typename MembersHolder::box_type,
|
||||
typename MembersHolder::allocators_type,
|
||||
typename MembersHolder::node_tag
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename Value, typename Options, typename Box, typename Allocators>
|
||||
struct level_insert_elements_type<0, Value, Value, Options, Box, Allocators>
|
||||
template <typename Value, typename MembersHolder>
|
||||
struct level_insert_elements_type<0, Value, MembersHolder, true>
|
||||
{
|
||||
typedef typename rtree::elements_type<
|
||||
typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type
|
||||
typename rtree::leaf<
|
||||
typename MembersHolder::value_type,
|
||||
typename MembersHolder::parameters_type,
|
||||
typename MembersHolder::box_type,
|
||||
typename MembersHolder::allocators_type,
|
||||
typename MembersHolder::node_tag
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
template <size_t InsertIndex, typename Element, typename MembersHolder>
|
||||
struct level_insert_base
|
||||
: public detail::insert<Element, Value, Options, Translator, Box, Allocators>
|
||||
: public detail::insert<Element, MembersHolder>
|
||||
{
|
||||
typedef detail::insert<Element, Value, Options, Translator, Box, Allocators> base;
|
||||
typedef detail::insert<Element, MembersHolder> base;
|
||||
typedef typename base::node node;
|
||||
typedef typename base::internal_node internal_node;
|
||||
typedef typename base::leaf leaf;
|
||||
|
||||
typedef typename level_insert_elements_type<InsertIndex, Element, Value, Options, Box, Allocators>::type elements_type;
|
||||
typedef typename level_insert_elements_type<InsertIndex, Element, MembersHolder>::type elements_type;
|
||||
typedef typename index::detail::rtree::container_from_elements_type<
|
||||
elements_type,
|
||||
typename elements_type::value_type
|
||||
>::type result_elements_type;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::box_type box_type;
|
||||
typedef typename MembersHolder::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::translator_type translator_type;
|
||||
typedef typename MembersHolder::allocators_type allocators_type;
|
||||
|
||||
typedef typename Allocators::node_pointer node_pointer;
|
||||
typedef typename Allocators::size_type size_type;
|
||||
typedef typename allocators_type::node_pointer node_pointer;
|
||||
typedef typename allocators_type::size_type size_type;
|
||||
|
||||
inline level_insert_base(node_pointer & root,
|
||||
size_type & leafs_level,
|
||||
Element const& element,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators,
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators,
|
||||
size_type relative_level)
|
||||
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
|
||||
, result_relative_level(0)
|
||||
@@ -208,7 +281,7 @@ struct level_insert_base
|
||||
{
|
||||
// NOTE: exception-safety
|
||||
// After an exception result_elements may contain garbage, don't use it
|
||||
rstar::remove_elements_to_reinsert<Value, Options, Translator, Box, Allocators>::apply(
|
||||
rstar::remove_elements_to_reinsert<MembersHolder>::apply(
|
||||
result_elements, n,
|
||||
base::m_traverse_data.parent, base::m_traverse_data.current_child_index,
|
||||
base::m_parameters, base::m_translator, base::m_allocators); // MAY THROW, BASIC (V, E: alloc, copy)
|
||||
@@ -246,39 +319,51 @@ struct level_insert_base
|
||||
inline void recalculate_aabb(Node const& n) const
|
||||
{
|
||||
base::m_traverse_data.current_element().first =
|
||||
elements_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
|
||||
elements_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
|
||||
base::m_translator,
|
||||
index::detail::get_strategy(base::m_parameters));
|
||||
}
|
||||
|
||||
inline void recalculate_aabb(leaf const& n) const
|
||||
{
|
||||
base::m_traverse_data.current_element().first =
|
||||
values_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
|
||||
values_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
|
||||
base::m_translator,
|
||||
index::detail::get_strategy(base::m_parameters));
|
||||
}
|
||||
|
||||
size_type result_relative_level;
|
||||
result_elements_type result_elements;
|
||||
};
|
||||
|
||||
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
template
|
||||
<
|
||||
size_t InsertIndex,
|
||||
typename Element,
|
||||
typename MembersHolder,
|
||||
bool IsValue = std::is_same<Element, typename MembersHolder::value_type>::value
|
||||
>
|
||||
struct level_insert
|
||||
: public level_insert_base<InsertIndex, Element, Value, Options, Translator, Box, Allocators>
|
||||
: public level_insert_base<InsertIndex, Element, MembersHolder>
|
||||
{
|
||||
typedef level_insert_base<InsertIndex, Element, Value, Options, Translator, Box, Allocators> base;
|
||||
typedef level_insert_base<InsertIndex, Element, MembersHolder> base;
|
||||
typedef typename base::node node;
|
||||
typedef typename base::internal_node internal_node;
|
||||
typedef typename base::leaf leaf;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename base::parameters_type parameters_type;
|
||||
typedef typename base::translator_type translator_type;
|
||||
typedef typename base::allocators_type allocators_type;
|
||||
|
||||
typedef typename Allocators::node_pointer node_pointer;
|
||||
typedef typename Allocators::size_type size_type;
|
||||
typedef typename base::node_pointer node_pointer;
|
||||
typedef typename base::size_type size_type;
|
||||
|
||||
inline level_insert(node_pointer & root,
|
||||
size_type & leafs_level,
|
||||
Element const& element,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators,
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators,
|
||||
size_type relative_level)
|
||||
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
|
||||
{}
|
||||
@@ -317,8 +402,7 @@ struct level_insert
|
||||
// NOTE: exception-safety
|
||||
// if the insert fails above, the element won't be stored in the tree, so delete it
|
||||
|
||||
rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(base::m_element.second, base::m_allocators);
|
||||
rtree::apply_visitor(del_v, *base::m_element.second);
|
||||
rtree::visitors::destroy<MembersHolder>::apply(base::m_element.second, base::m_allocators);
|
||||
|
||||
BOOST_RETHROW // RETHROW
|
||||
}
|
||||
@@ -345,26 +429,29 @@ struct level_insert
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t InsertIndex, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocators>
|
||||
: public level_insert_base<InsertIndex, Value, Value, Options, Translator, Box, Allocators>
|
||||
template <size_t InsertIndex, typename Value, typename MembersHolder>
|
||||
struct level_insert<InsertIndex, Value, MembersHolder, true>
|
||||
: public level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder>
|
||||
{
|
||||
typedef level_insert_base<InsertIndex, Value, Value, Options, Translator, Box, Allocators> base;
|
||||
typedef level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder> base;
|
||||
typedef typename base::node node;
|
||||
typedef typename base::internal_node internal_node;
|
||||
typedef typename base::leaf leaf;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::value_type value_type;
|
||||
typedef typename base::parameters_type parameters_type;
|
||||
typedef typename base::translator_type translator_type;
|
||||
typedef typename base::allocators_type allocators_type;
|
||||
|
||||
typedef typename Allocators::node_pointer node_pointer;
|
||||
typedef typename Allocators::size_type size_type;
|
||||
typedef typename base::node_pointer node_pointer;
|
||||
typedef typename base::size_type size_type;
|
||||
|
||||
inline level_insert(node_pointer & root,
|
||||
size_type & leafs_level,
|
||||
Value const& v,
|
||||
value_type const& v,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators,
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators,
|
||||
size_type relative_level)
|
||||
: base(root, leafs_level, v, parameters, translator, allocators, relative_level)
|
||||
{}
|
||||
@@ -378,7 +465,7 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
|
||||
base::traverse(*this, n); // MAY THROW (V, E: alloc, copy, N: alloc)
|
||||
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(0 < base::m_level, "illegal level value, level shouldn't be the root level for 0 < InsertIndex");
|
||||
|
||||
|
||||
if ( base::m_traverse_data.current_level == base::m_level - 1 )
|
||||
{
|
||||
base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (E: alloc, copy, N: alloc)
|
||||
@@ -394,33 +481,36 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
|
||||
base::m_level == (std::numeric_limits<size_t>::max)(),
|
||||
"unexpected level");
|
||||
|
||||
|
||||
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
|
||||
|
||||
base::handle_possible_split(n); // MAY THROW (V: alloc, copy, N: alloc)
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
|
||||
: public level_insert_base<0, Value, Value, Options, Translator, Box, Allocators>
|
||||
template <typename Value, typename MembersHolder>
|
||||
struct level_insert<0, Value, MembersHolder, true>
|
||||
: public level_insert_base<0, typename MembersHolder::value_type, MembersHolder>
|
||||
{
|
||||
typedef level_insert_base<0, Value, Value, Options, Translator, Box, Allocators> base;
|
||||
typedef level_insert_base<0, typename MembersHolder::value_type, MembersHolder> base;
|
||||
typedef typename base::node node;
|
||||
typedef typename base::internal_node internal_node;
|
||||
typedef typename base::leaf leaf;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::value_type value_type;
|
||||
typedef typename base::parameters_type parameters_type;
|
||||
typedef typename base::translator_type translator_type;
|
||||
typedef typename base::allocators_type allocators_type;
|
||||
|
||||
typedef typename Allocators::node_pointer node_pointer;
|
||||
typedef typename Allocators::size_type size_type;
|
||||
typedef typename base::node_pointer node_pointer;
|
||||
typedef typename base::size_type size_type;
|
||||
|
||||
inline level_insert(node_pointer & root,
|
||||
size_type & leafs_level,
|
||||
Value const& v,
|
||||
value_type const& v,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators,
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators,
|
||||
size_type relative_level)
|
||||
: base(root, leafs_level, v, parameters, translator, allocators, relative_level)
|
||||
{}
|
||||
@@ -449,7 +539,7 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
|
||||
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
|
||||
|
||||
base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (V: alloc, copy, N: alloc)
|
||||
|
||||
|
||||
base::recalculate_aabb_if_necessary(n);
|
||||
}
|
||||
};
|
||||
@@ -460,26 +550,28 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
|
||||
// After passing the Element to insert visitor the Element is managed by the tree
|
||||
// I.e. one should not delete the node passed to the insert visitor after exception is thrown
|
||||
// because this visitor may delete it
|
||||
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
class insert<Element, Value, Options, Translator, Box, Allocators, insert_reinsert_tag>
|
||||
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
|
||||
template <typename Element, typename MembersHolder>
|
||||
class insert<Element, MembersHolder, insert_reinsert_tag>
|
||||
: public MembersHolder::visitor
|
||||
{
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::translator_type translator_type;
|
||||
typedef typename MembersHolder::allocators_type allocators_type;
|
||||
|
||||
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
|
||||
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
||||
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
||||
typedef typename MembersHolder::node node;
|
||||
typedef typename MembersHolder::internal_node internal_node;
|
||||
typedef typename MembersHolder::leaf leaf;
|
||||
|
||||
typedef typename Allocators::node_pointer node_pointer;
|
||||
typedef typename Allocators::size_type size_type;
|
||||
typedef typename allocators_type::node_pointer node_pointer;
|
||||
typedef typename allocators_type::size_type size_type;
|
||||
|
||||
public:
|
||||
inline insert(node_pointer & root,
|
||||
size_type & leafs_level,
|
||||
Element const& element,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators,
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators,
|
||||
size_type relative_level = 0)
|
||||
: m_root(root), m_leafs_level(leafs_level), m_element(element)
|
||||
, m_parameters(parameters), m_translator(translator)
|
||||
@@ -494,7 +586,7 @@ public:
|
||||
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
|
||||
if ( m_parameters.get_reinserted_elements() > 0 )
|
||||
{
|
||||
rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
|
||||
rstar::level_insert<0, Element, MembersHolder> lins_v(
|
||||
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
|
||||
|
||||
rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
|
||||
@@ -506,10 +598,10 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
|
||||
visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
|
||||
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
|
||||
|
||||
rtree::apply_visitor(ins_v, *m_root);
|
||||
rtree::apply_visitor(ins_v, *m_root);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,7 +613,7 @@ public:
|
||||
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
|
||||
if ( m_parameters.get_reinserted_elements() > 0 )
|
||||
{
|
||||
rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
|
||||
rstar::level_insert<0, Element, MembersHolder> lins_v(
|
||||
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
|
||||
|
||||
rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
|
||||
@@ -531,10 +623,10 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
|
||||
visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
|
||||
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
|
||||
|
||||
rtree::apply_visitor(ins_v, *m_root);
|
||||
rtree::apply_visitor(ins_v, *m_root);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,7 +640,7 @@ private:
|
||||
typename Elements::reverse_iterator it = elements.rbegin();
|
||||
for ( ; it != elements.rend() ; ++it)
|
||||
{
|
||||
rstar::level_insert<1, element_type, Value, Options, Translator, Box, Allocators> lins_v(
|
||||
rstar::level_insert<1, element_type, MembersHolder> lins_v(
|
||||
m_root, m_leafs_level, *it, m_parameters, m_translator, m_allocators, relative_level);
|
||||
|
||||
BOOST_TRY
|
||||
@@ -559,7 +651,7 @@ private:
|
||||
{
|
||||
++it;
|
||||
for ( ; it != elements.rend() ; ++it)
|
||||
rtree::destroy_element<Value, Options, Translator, Box, Allocators>::apply(*it, m_allocators);
|
||||
rtree::destroy_element<MembersHolder>::apply(*it, m_allocators);
|
||||
BOOST_RETHROW // RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
@@ -579,11 +671,11 @@ private:
|
||||
Element const& m_element;
|
||||
|
||||
parameters_type const& m_parameters;
|
||||
Translator const& m_translator;
|
||||
translator_type const& m_translator;
|
||||
|
||||
size_type m_relative_level;
|
||||
|
||||
Allocators & m_allocators;
|
||||
allocators_type & m_allocators;
|
||||
};
|
||||
|
||||
}}} // namespace detail::rtree::visitors
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
//
|
||||
// R-tree R*-tree split algorithm implementation
|
||||
//
|
||||
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
// Copyright (c) 2011-2022 Adam Wulkiewicz, Lodz, Poland.
|
||||
//
|
||||
// This file was modified by Oracle on 2019-2020.
|
||||
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
//
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -13,6 +17,8 @@
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
#include <boost/geometry/core/static_assert.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/algorithms/intersection_content.hpp>
|
||||
#include <boost/geometry/index/detail/algorithms/margin.hpp>
|
||||
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
|
||||
@@ -30,37 +36,43 @@ namespace detail { namespace rtree {
|
||||
|
||||
namespace rstar {
|
||||
|
||||
template <typename Element, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
|
||||
template <typename Element, typename Parameters, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
|
||||
class element_axis_corner_less
|
||||
{
|
||||
typedef typename rtree::element_indexable_type<Element, Translator>::type indexable_type;
|
||||
typedef typename geometry::point_type<indexable_type>::type point_type;
|
||||
typedef geometry::model::box<point_type> bounds_type;
|
||||
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
|
||||
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
|
||||
typedef index::detail::bounded_view
|
||||
<
|
||||
indexable_type, bounds_type, strategy_type
|
||||
> bounded_view_type;
|
||||
|
||||
public:
|
||||
element_axis_corner_less(Translator const& tr)
|
||||
: m_tr(tr)
|
||||
element_axis_corner_less(Translator const& tr, strategy_type const& strategy)
|
||||
: m_tr(tr), m_strategy(strategy)
|
||||
{}
|
||||
|
||||
bool operator()(Element const& e1, Element const& e2) const
|
||||
{
|
||||
bounded_view_type bounded_ind1(rtree::element_indexable(e1, m_tr));
|
||||
bounded_view_type bounded_ind2(rtree::element_indexable(e2, m_tr));
|
||||
|
||||
return geometry::get<Corner, AxisIndex>(bounded_ind1)
|
||||
< geometry::get<Corner, AxisIndex>(bounded_ind2);
|
||||
indexable_type const& ind1 = rtree::element_indexable(e1, m_tr);
|
||||
indexable_type const& ind2 = rtree::element_indexable(e2, m_tr);
|
||||
return geometry::get<Corner, AxisIndex>(bounded_view_type(ind1, m_strategy))
|
||||
< geometry::get<Corner, AxisIndex>(bounded_view_type(ind2, m_strategy));
|
||||
}
|
||||
|
||||
private:
|
||||
Translator const& m_tr;
|
||||
strategy_type const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
|
||||
class element_axis_corner_less<Element, Translator, box_tag, Corner, AxisIndex>
|
||||
template <typename Element, typename Parameters, typename Translator, size_t Corner, size_t AxisIndex>
|
||||
class element_axis_corner_less<Element, Parameters, Translator, box_tag, Corner, AxisIndex>
|
||||
{
|
||||
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
|
||||
|
||||
public:
|
||||
element_axis_corner_less(Translator const& tr)
|
||||
element_axis_corner_less(Translator const& tr, strategy_type const&)
|
||||
: m_tr(tr)
|
||||
{}
|
||||
|
||||
@@ -74,11 +86,13 @@ private:
|
||||
Translator const& m_tr;
|
||||
};
|
||||
|
||||
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
|
||||
class element_axis_corner_less<Element, Translator, point_tag, Corner, AxisIndex>
|
||||
template <typename Element, typename Parameters, typename Translator, size_t Corner, size_t AxisIndex>
|
||||
class element_axis_corner_less<Element, Parameters, Translator, point_tag, Corner, AxisIndex>
|
||||
{
|
||||
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
|
||||
|
||||
public:
|
||||
element_axis_corner_less(Translator const& tr)
|
||||
element_axis_corner_less(Translator const& tr, strategy_type const& )
|
||||
: m_tr(tr)
|
||||
{}
|
||||
|
||||
@@ -113,14 +127,20 @@ struct choose_split_axis_and_index_for_corner
|
||||
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == parameters.get_max_elements() + 1, "wrong number of elements");
|
||||
|
||||
typename index::detail::strategy_type<Parameters>::type const&
|
||||
strategy = index::detail::get_strategy(parameters);
|
||||
|
||||
// copy elements
|
||||
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
|
||||
|
||||
|
||||
size_t const index_first = parameters.get_min_elements();
|
||||
size_t const index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
|
||||
|
||||
// sort elements
|
||||
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
|
||||
element_axis_corner_less
|
||||
<
|
||||
element_type, Parameters, Translator, indexable_tag, Corner, AxisIndex
|
||||
> elements_less(translator, strategy);
|
||||
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
|
||||
// {
|
||||
// typename Elements::iterator f = elements_copy.begin() + index_first;
|
||||
@@ -143,12 +163,14 @@ struct choose_split_axis_and_index_for_corner
|
||||
// TODO - awulkiew: may be optimized - box of group 1 may be initialized with
|
||||
// box of min_elems number of elements and expanded for each iteration by another element
|
||||
|
||||
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i, translator);
|
||||
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(), translator);
|
||||
|
||||
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i,
|
||||
translator, strategy);
|
||||
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(),
|
||||
translator, strategy);
|
||||
|
||||
sum_of_margins += index::detail::comparable_margin(box1) + index::detail::comparable_margin(box2);
|
||||
|
||||
content_type ovl = index::detail::intersection_content(box1, box2);
|
||||
content_type ovl = index::detail::intersection_content(box1, box2, strategy);
|
||||
content_type con = index::detail::content(box1) + index::detail::content(box2);
|
||||
|
||||
// TODO - shouldn't here be < instead of <= ?
|
||||
@@ -167,7 +189,7 @@ struct choose_split_axis_and_index_for_corner
|
||||
//template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
|
||||
//struct choose_split_axis_and_index_for_axis
|
||||
//{
|
||||
// BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
|
||||
// BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Not implemented for this Tag type.", ElementIndexableTag);
|
||||
//};
|
||||
|
||||
template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
|
||||
@@ -337,14 +359,15 @@ struct nth_element
|
||||
BOOST_STATIC_ASSERT(0 < Dimension);
|
||||
BOOST_STATIC_ASSERT(I < Dimension);
|
||||
|
||||
template <typename Elements, typename Translator>
|
||||
static inline void apply(Elements & elements, const size_t axis, const size_t index, Translator const& tr)
|
||||
template <typename Elements, typename Parameters, typename Translator>
|
||||
static inline void apply(Elements & elements, Parameters const& parameters,
|
||||
const size_t axis, const size_t index, Translator const& tr)
|
||||
{
|
||||
//BOOST_GEOMETRY_INDEX_ASSERT(axis < Dimension, "unexpected axis value");
|
||||
|
||||
if ( axis != I )
|
||||
{
|
||||
nth_element<Corner, Dimension, I + 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
|
||||
nth_element<Corner, Dimension, I + 1>::apply(elements, parameters, axis, index, tr); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -352,7 +375,13 @@ struct nth_element
|
||||
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
|
||||
typedef typename tag<indexable_type>::type indexable_tag;
|
||||
|
||||
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, I> less(tr);
|
||||
typename index::detail::strategy_type<Parameters>::type
|
||||
strategy = index::detail::get_strategy(parameters);
|
||||
|
||||
element_axis_corner_less
|
||||
<
|
||||
element_type, Parameters, Translator, indexable_tag, Corner, I
|
||||
> less(tr, strategy);
|
||||
index::detail::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
}
|
||||
@@ -361,40 +390,44 @@ struct nth_element
|
||||
template <size_t Corner, size_t Dimension>
|
||||
struct nth_element<Corner, Dimension, Dimension>
|
||||
{
|
||||
template <typename Elements, typename Translator>
|
||||
static inline void apply(Elements & /*elements*/, const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
|
||||
template <typename Elements, typename Parameters, typename Translator>
|
||||
static inline void apply(Elements & /*elements*/, Parameters const& /*parameters*/,
|
||||
const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace rstar
|
||||
|
||||
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
|
||||
struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_tag>
|
||||
template <typename MembersHolder>
|
||||
struct redistribute_elements<MembersHolder, rstar_tag>
|
||||
{
|
||||
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
|
||||
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
||||
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
||||
typedef typename MembersHolder::box_type box_type;
|
||||
typedef typename MembersHolder::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::translator_type translator_type;
|
||||
typedef typename MembersHolder::allocators_type allocators_type;
|
||||
|
||||
typedef typename Options::parameters_type parameters_type;
|
||||
typedef typename MembersHolder::node node;
|
||||
typedef typename MembersHolder::internal_node internal_node;
|
||||
typedef typename MembersHolder::leaf leaf;
|
||||
|
||||
static const size_t dimension = geometry::dimension<Box>::value;
|
||||
static const size_t dimension = geometry::dimension<box_type>::value;
|
||||
|
||||
typedef typename index::detail::default_margin_result<Box>::type margin_type;
|
||||
typedef typename index::detail::default_content_result<Box>::type content_type;
|
||||
typedef typename index::detail::default_margin_result<box_type>::type margin_type;
|
||||
typedef typename index::detail::default_content_result<box_type>::type content_type;
|
||||
|
||||
template <typename Node>
|
||||
static inline void apply(
|
||||
Node & n,
|
||||
Node & second_node,
|
||||
Box & box1,
|
||||
Box & box2,
|
||||
box_type & box1,
|
||||
box_type & box2,
|
||||
parameters_type const& parameters,
|
||||
Translator const& translator,
|
||||
Allocators & allocators)
|
||||
translator_type const& translator,
|
||||
allocators_type & allocators)
|
||||
{
|
||||
typedef typename rtree::elements_type<Node>::type elements_type;
|
||||
typedef typename elements_type::value_type element_type;
|
||||
|
||||
|
||||
elements_type & elements1 = rtree::elements(n);
|
||||
elements_type & elements2 = rtree::elements(second_node);
|
||||
|
||||
@@ -417,7 +450,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
|
||||
// and again, the same below calling partial_sort/nth_element
|
||||
// It would be even possible to not re-sort/find nth_element if the axis/corner
|
||||
// was found for the last sorting - last combination of axis/corner
|
||||
rstar::choose_split_axis_and_index<Box, dimension>
|
||||
rstar::choose_split_axis_and_index<box_type, dimension>
|
||||
::apply(elements_copy,
|
||||
split_axis, split_corner, split_index,
|
||||
smallest_sum_of_margins, smallest_overlap, smallest_content,
|
||||
@@ -432,23 +465,28 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
|
||||
if ( split_corner == static_cast<size_t>(min_corner) )
|
||||
{
|
||||
rstar::nth_element<min_corner, dimension>
|
||||
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
::apply(elements_copy, parameters, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
else
|
||||
{
|
||||
rstar::nth_element<max_corner, dimension>
|
||||
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
::apply(elements_copy, parameters, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
|
||||
}
|
||||
|
||||
BOOST_TRY
|
||||
{
|
||||
typename index::detail::strategy_type<parameters_type>::type const&
|
||||
strategy = index::detail::get_strategy(parameters);
|
||||
|
||||
// copy elements to nodes
|
||||
elements1.assign(elements_copy.begin(), elements_copy.begin() + split_index); // MAY THROW, BASIC
|
||||
elements2.assign(elements_copy.begin() + split_index, elements_copy.end()); // MAY THROW, BASIC
|
||||
|
||||
// calculate boxes
|
||||
box1 = rtree::elements_box<Box>(elements1.begin(), elements1.end(), translator);
|
||||
box2 = rtree::elements_box<Box>(elements2.begin(), elements2.end(), translator);
|
||||
box1 = rtree::elements_box<box_type>(elements1.begin(), elements1.end(),
|
||||
translator, strategy);
|
||||
box2 = rtree::elements_box<box_type>(elements2.begin(), elements2.end(),
|
||||
translator, strategy);
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
@@ -456,7 +494,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
|
||||
elements1.clear();
|
||||
elements2.clear();
|
||||
|
||||
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_backup, allocators);
|
||||
rtree::destroy_elements<MembersHolder>::apply(elements_backup, allocators);
|
||||
//elements_backup.clear();
|
||||
|
||||
BOOST_RETHROW // RETHROW, BASIC
|
||||
|
||||
Reference in New Issue
Block a user