[index] Fix dangling references when Indexable is returned by value by IndexableGetter.

This commit is contained in:
Adam Wulkiewicz 2022-11-01 20:11:07 +01:00
parent 938f6f6bc1
commit 7ee08ef98d
3 changed files with 38 additions and 36 deletions

View File

@ -3,7 +3,7 @@
// R-tree linear split algorithm implementation
//
// Copyright (c) 2008 Federico J. Fernandez.
// Copyright (c) 2011-2014 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.
@ -114,50 +114,52 @@ struct find_greatest_normalized_separation
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
typename index::detail::strategy_type<Parameters>::type const&
strategy = index::detail::get_strategy(parameters);
auto const& strategy = index::detail::get_strategy(parameters);
// find the lowest low, highest high
bounded_view_type bounded_indexable_0(rtree::element_indexable(elements[0], translator),
strategy);
indexable_type const& indexable_0 = rtree::element_indexable(elements[0], translator);
bounded_view_type const bounded_indexable_0(indexable_0, strategy);
coordinate_type lowest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_0);
coordinate_type highest_high = geometry::get<max_corner, DimensionIndex>(bounded_indexable_0);
// and the lowest high
coordinate_type lowest_high = highest_high;
size_t lowest_high_index = 0;
for ( size_t i = 1 ; i < elements_count ; ++i )
for (size_t i = 1 ; i < elements_count ; ++i)
{
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator),
strategy);
indexable_type const& indexable_i = rtree::element_indexable(elements[i], translator);
bounded_view_type const bounded_indexable(indexable_i, strategy);
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
coordinate_type max_coord = geometry::get<max_corner, DimensionIndex>(bounded_indexable);
if ( max_coord < lowest_high )
if (max_coord < lowest_high)
{
lowest_high = max_coord;
lowest_high_index = i;
}
if ( min_coord < lowest_low )
if (min_coord < lowest_low)
{
lowest_low = min_coord;
}
if ( highest_high < max_coord )
if (highest_high < max_coord)
{
highest_high = max_coord;
}
}
// find the highest low
size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
bounded_view_type bounded_indexable_hl(rtree::element_indexable(elements[highest_low_index], translator),
strategy);
indexable_type const& indexable_hl = rtree::element_indexable(elements[highest_low_index], translator);
bounded_view_type const bounded_indexable_hl(indexable_hl, strategy);
coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_hl);
for ( size_t i = highest_low_index ; i < elements_count ; ++i )
for (size_t i = highest_low_index ; i < elements_count ; ++i)
{
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator),
strategy);
indexable_type const& indexable = rtree::element_indexable(elements[i], translator);
bounded_view_type const bounded_indexable(indexable, strategy);
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
if ( highest_low < min_coord &&
i != lowest_high_index )
if (highest_low < min_coord && i != lowest_high_index)
{
highest_low = min_coord;
highest_low_index = i;
@ -169,8 +171,10 @@ struct find_greatest_normalized_separation
// highest_low - lowest_high
separation = difference<separation_type>(lowest_high, highest_low);
// BOOST_GEOMETRY_INDEX_ASSERT(0 <= width);
if ( std::numeric_limits<coordinate_type>::epsilon() < width )
if (std::numeric_limits<coordinate_type>::epsilon() < width)
{
separation /= width;
}
seed1 = highest_low_index;
seed2 = lowest_high_index;

View File

@ -2,7 +2,7 @@
//
// 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.
@ -55,11 +55,10 @@ public:
bool operator()(Element const& e1, Element const& e2) const
{
bounded_view_type bounded_ind1(rtree::element_indexable(e1, m_tr), m_strategy);
bounded_view_type bounded_ind2(rtree::element_indexable(e2, m_tr), m_strategy);
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:

View File

@ -137,10 +137,9 @@ Predefined algorithms with run-time parameters are:
\li \c boost::geometry::index::dynamic_rstar.
\par IndexableGetter
The object of IndexableGetter type translates from Value to Indexable each time
r-tree requires it. This means that this operation is done for each Value
access. Therefore the IndexableGetter should return the Indexable by
a reference type. The Indexable should not be calculated since it could harm
An object of IndexableGetter type translates from Value to Indexable each time
r-tree requires it. This operation is done for each Value access.
The Indexable should not be calculated each time since it could harm
the performance. The default IndexableGetter can translate all types adapted
to Point, Box or Segment concepts (called Indexables). Furthermore, it can
handle <tt>std::pair<Indexable, T></tt>, <tt>std::tuple<Indexable, ...></tt>
@ -606,7 +605,7 @@ public:
/*!
\brief The copy constructor.
It uses parameters, translator and allocator from the source tree.
It uses parameters, observers and allocator from the source tree.
\param src The rtree which content will be copied.
@ -627,7 +626,7 @@ public:
/*!
\brief The copy constructor.
It uses Parameters and translator from the source tree.
It uses parameters and observers from the source tree.
\param src The rtree which content will be copied.
\param allocator The allocator which will be used.
@ -648,7 +647,7 @@ public:
/*!
\brief The moving constructor.
It uses parameters, translator and allocator from the source tree.
It uses parameters, observers and allocator from the source tree.
\param src The rtree which content will be moved.
@ -669,7 +668,7 @@ public:
/*!
\brief The moving constructor.
It uses parameters and translator from the source tree.
It uses parameters and observers from the source tree.
\param src The rtree which content will be moved.
\param allocator The allocator.
@ -700,7 +699,7 @@ public:
/*!
\brief The assignment operator.
It uses parameters and translator from the source tree.
It uses parameters and observers from the source tree.
\param src The rtree which content will be copied.
@ -738,7 +737,7 @@ public:
/*!
\brief The moving assignment.
It uses parameters and translator from the source tree.
It uses parameters and observers from the source tree.
\param src The rtree which content will be moved.
@ -790,7 +789,7 @@ public:
/*!
\brief Swaps contents of two rtrees.
Parameters, translator and allocators are swapped as well.
Parameters, observers and allocators are swapped as well.
\param other The rtree which content will be swapped with this rtree content.