|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84087 - in trunk/boost/geometry/index: . detail/rtree/rstar detail/rtree/visitors
From: adam.wulkiewicz_at_[hidden]
Date: 2013-04-29 16:50:02
Author: awulkiew
Date: 2013-04-29 16:50:00 EDT (Mon, 29 Apr 2013)
New Revision: 84087
URL: http://svn.boost.org/trac/boost/changeset/84087
Log:
geometry.index: edge values of some parameters handled more safely, changed order of rstar parameters.
Text files modified:
trunk/boost/geometry/index/detail/rtree/rstar/insert.hpp | 44 ++++++++++++++++++++++-------
trunk/boost/geometry/index/detail/rtree/visitors/insert.hpp | 2
trunk/boost/geometry/index/detail/rtree/visitors/remove.hpp | 4 ++
trunk/boost/geometry/index/parameters.hpp | 58 ++++++++++++++++++++++-----------------
4 files changed, 70 insertions(+), 38 deletions(-)
Modified: trunk/boost/geometry/index/detail/rtree/rstar/insert.hpp
==============================================================================
--- trunk/boost/geometry/index/detail/rtree/rstar/insert.hpp (original)
+++ trunk/boost/geometry/index/detail/rtree/rstar/insert.hpp 2013-04-29 16:50:00 EDT (Mon, 29 Apr 2013)
@@ -48,7 +48,7 @@
elements_type & elements = rtree::elements(n);
const size_t elements_count = parameters.get_max_elements() + 1;
- const size_t reinserted_elements_count = parameters.get_reinserted_elements();
+ const size_t reinserted_elements_count = (::std::min)(parameters.get_reinserted_elements(), elements_count - parameters.get_min_elements());
BOOST_GEOMETRY_INDEX_ASSERT(parent, "node shouldn't be the root node");
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected elements number");
@@ -466,14 +466,25 @@
{
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<internal_node>(*m_root), "current node should be the root");
- rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
- m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
+ // 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(
+ 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)
+ rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
- if ( !lins_v.result_elements.empty() )
+ if ( !lins_v.result_elements.empty() )
+ {
+ recursive_reinsert(lins_v.result_elements, lins_v.result_relative_level); // MAY THROW (V, E: alloc, copy, N: alloc)
+ }
+ }
+ else
{
- recursive_reinsert(lins_v.result_elements, lins_v.result_relative_level); // MAY THROW (V, E: alloc, copy, N: alloc)
+ visitors::insert<Element, Value, Options, Translator, Box, Allocators, 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);
}
}
@@ -481,13 +492,24 @@
{
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<leaf>(*m_root), "current node should be the root");
- rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
- m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
+ // 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(
+ 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)
- rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
+ // we're in the root, so root should be split and there should be no elements to reinsert
+ BOOST_GEOMETRY_INDEX_ASSERT(lins_v.result_elements.empty(), "unexpected state");
+ }
+ else
+ {
+ visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
+ m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
- // we're in the root, so root should be split and there should be no elements to reinsert
- BOOST_GEOMETRY_INDEX_ASSERT(lins_v.result_elements.empty(), "unexpected state");
+ rtree::apply_visitor(ins_v, *m_root);
+ }
}
private:
Modified: trunk/boost/geometry/index/detail/rtree/visitors/insert.hpp
==============================================================================
--- trunk/boost/geometry/index/detail/rtree/visitors/insert.hpp (original)
+++ trunk/boost/geometry/index/detail/rtree/visitors/insert.hpp 2013-04-29 16:50:00 EDT (Mon, 29 Apr 2013)
@@ -413,7 +413,7 @@
inline insert(node_pointer & root,
size_t & leafs_level,
- Element & element,
+ Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
Modified: trunk/boost/geometry/index/detail/rtree/visitors/remove.hpp
==============================================================================
--- trunk/boost/geometry/index/detail/rtree/visitors/remove.hpp (original)
+++ trunk/boost/geometry/index/detail/rtree/visitors/remove.hpp 2013-04-29 16:50:00 EDT (Mon, 29 Apr 2013)
@@ -145,8 +145,10 @@
// if value was removed
if ( m_is_value_removed )
{
+ BOOST_ASSERT_MSG(0 < m_parameters.get_min_elements(), "min number of elements is too small");
+
// calc underflow
- m_is_underflow = elements.size() < m_parameters.get_min_elements();
+ m_is_underflow = elements.size() < m_parameters.get_min_elements();
// n is not root - adjust aabb
if ( 0 != m_parent )
Modified: trunk/boost/geometry/index/parameters.hpp
==============================================================================
--- trunk/boost/geometry/index/parameters.hpp (original)
+++ trunk/boost/geometry/index/parameters.hpp 2013-04-29 16:50:00 EDT (Mon, 29 Apr 2013)
@@ -15,11 +15,13 @@
namespace boost { namespace geometry { namespace index {
-// TODO: awulkiew - implement those:
-//if ( m_min_elems_per_node < 1 )
-// m_min_elems_per_node = 1;
-//if ( m_max_elems_per_node < 2 )
-// m_max_elems_per_node = 2;
+// TODO: awulkiew - add asserts or exceptions?
+// 0 < MIN
+// 2 * MIN <= MAX
+// or rather MIN <= (MAX + 1) / 2 for classic variants
+// assuming that MAX is the number of elements without overflowing ones
+// and something like MIN <= (MAX + OVERFLOWING_NODES) / K for cR-tree
+// this implies 2 <= MAX for classic variants
/*!
\brief Linear r-tree creation algorithm parameters.
@@ -68,27 +70,30 @@
\tparam MaxElements Maximum number of elements in nodes.
\tparam MinElements Minimum number of elements in nodes.
-\tparam OverlapCostThreshold The number of leaf node children elements above which
- nearly minimum overlap cost is calculated instead of minimum
- overlap cost. If 0 minimum overlap cost is always calculated.
-\tparam ReinsertedElements Number of elements reinserted by forced reinsertions algorithm.
+\tparam ReinsertedElements The number of elements reinserted by forced reinsertions algorithm.
+ If 0 forced reinsertions are disabled. Maximum value is Max-Min+1.
+ Greater values are truncated.
+\tparam OverlapCostThreshold The number of most suitable leafs taken into account while choosing
+ the leaf node to which currently inserted value will be added. If
+ value is in range (0, MaxElements) - the algorithm calculates
+ nearly minimum overlap cost, otherwise all leafs are analyzed
+ and true minimum overlap cost is calculated.
*/
template <size_t MaxElements,
size_t MinElements,
- size_t OverlapCostThreshold = 0,
- size_t ReinsertedElements = detail::default_rstar_reinserted_elements_s<MaxElements>::value
- >
+ size_t ReinsertedElements = detail::default_rstar_reinserted_elements_s<MaxElements>::value,
+ size_t OverlapCostThreshold = 32>
struct rstar
{
static const size_t max_elements = MaxElements;
static const size_t min_elements = MinElements;
- static const size_t overlap_cost_threshold = OverlapCostThreshold;
static const size_t reinserted_elements = ReinsertedElements;
+ static const size_t overlap_cost_threshold = OverlapCostThreshold;
static size_t get_max_elements() { return MaxElements; }
static size_t get_min_elements() { return MinElements; }
- static size_t get_overlap_cost_threshold() { return OverlapCostThreshold; }
static size_t get_reinserted_elements() { return ReinsertedElements; }
+ static size_t get_overlap_cost_threshold() { return OverlapCostThreshold; }
};
//template <size_t MaxElements, size_t MinElements>
@@ -168,35 +173,38 @@
\param max_elements Maximum number of elements in nodes.
\param min_elements Minimum number of elements in nodes.
- \param overlap_cost_threshold The number of leaf node children elements above which
- nearly minimum overlap cost is calculated instead of minimum
- overlap cost. If 0 minimum overlap cost is always calculated.
- \param reinserted_elements Number of elements reinserted by forced reinsertions algorithm.
+ \param reinserted_elements The number of elements reinserted by forced reinsertions algorithm.
+ If 0 forced reinsertions are disabled. Maximum value is Max-Min+1.
+ Greater values are truncated.
+ \param overlap_cost_threshold The number of most suitable leafs taken into account while choosing
+ the leaf node to which currently inserted value will be added. If
+ value is in range (0, MaxElements) - the algorithm calculates
+ nearly minimum overlap cost, otherwise all leafs are analyzed
+ and true minimum overlap cost is calculated.
*/
dynamic_rstar(size_t max_elements,
size_t min_elements,
- size_t overlap_cost_threshold = 0,
- size_t reinserted_elements = detail::default_rstar_reinserted_elements_d())
+ size_t reinserted_elements = detail::default_rstar_reinserted_elements_d(),
+ size_t overlap_cost_threshold = 32)
: m_max_elements(max_elements)
, m_min_elements(min_elements)
- , m_overlap_cost_threshold(overlap_cost_threshold)
, m_reinserted_elements(
detail::default_rstar_reinserted_elements_d() == reinserted_elements ?
(max_elements * 3) / 10 :
- reinserted_elements
- )
+ reinserted_elements )
+ , m_overlap_cost_threshold(overlap_cost_threshold)
{}
size_t get_max_elements() const { return m_max_elements; }
size_t get_min_elements() const { return m_min_elements; }
- size_t get_overlap_cost_threshold() const { return m_overlap_cost_threshold; }
size_t get_reinserted_elements() const { return m_reinserted_elements; }
+ size_t get_overlap_cost_threshold() const { return m_overlap_cost_threshold; }
private:
size_t m_max_elements;
size_t m_min_elements;
- size_t m_overlap_cost_threshold;
size_t m_reinserted_elements;
+ size_t m_overlap_cost_threshold;
};
}}} // namespace boost::geometry::index
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk