update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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