From 31d95f9ac44cddc5370dab3b4e08ec3428fa933d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 4 Jan 2013 17:38:18 +0000 Subject: [PATCH] Added number of removed elements returned by rtree::remove(). [SVN r82353] --- .../geometry/extensions/index/rtree/rtree.hpp | 47 ++++++++---- .../index/rtree/visitors/remove.hpp | 6 +- test/rtree/test_rtree.hpp | 76 +++++++++++++++---- 3 files changed, 102 insertions(+), 27 deletions(-) diff --git a/include/boost/geometry/extensions/index/rtree/rtree.hpp b/include/boost/geometry/extensions/index/rtree/rtree.hpp index 142db8bcf..69c62db25 100644 --- a/include/boost/geometry/extensions/index/rtree/rtree.hpp +++ b/include/boost/geometry/extensions/index/rtree/rtree.hpp @@ -373,10 +373,12 @@ public: \note Exception-safety: basic \param value The value which will be removed from the container. + + \return 1 if the value was removed, 0 otherwise. */ - inline void remove(value_type const& value) + inline size_type remove(value_type const& value) { - this->raw_remove(value); + return this->raw_remove(value); } /*! @@ -386,12 +388,16 @@ public: \param first The beginning of the range of values. \param last The end of the range of values. + + \return The number of removed values. */ template - inline void remove(Iterator first, Iterator last) + inline size_type remove(Iterator first, Iterator last) { + size_type result = 0; for ( ; first != last ; ++first ) - this->raw_remove(*first); + result += this->raw_remove(*first); + return result; } /*! @@ -400,13 +406,17 @@ public: \note Exception-safety: basic \param rng The range of values. + + \return The number of removed values. */ template - inline void remove(Range const& rng) + inline size_type remove(Range const& rng) { + size_type result = 0; typedef typename boost::range_const_iterator::type It; for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) - this->raw_remove(*it); + result += this->raw_remove(*it); + return result; } /*! @@ -787,7 +797,7 @@ private: \param value The value which will be removed from the container. */ - inline void raw_remove(value_type const& value) + inline size_type raw_remove(value_type const& value) { // TODO: awulkiew - assert for correct value (indexable) ? BOOST_GEOMETRY_INDEX_ASSERT(m_root, "The root must exist"); @@ -806,6 +816,8 @@ private: // TODO // If exception is thrown, m_values_count may be invalid --m_values_count; + + return remove_v.is_value_removed() ? 1 : 0; } /*! @@ -1005,11 +1017,14 @@ Remove a value from the index. \param tree The spatial index. \param v The value which will be removed from the index. + +\return 1 if value was removed, 0 otherwise. */ template -inline void remove(rtree & tree, Value const& v) +inline typename rtree::size_type +remove(rtree & tree, Value const& v) { - tree.remove(v); + return tree.remove(v); } /*! @@ -1018,11 +1033,14 @@ Remove a range of values from the index. \param tree The spatial index. \param first The beginning of the range of values. \param last The end of the range of values. + +\return The number of removed values. */ template -inline void remove(rtree & tree, Iterator first, Iterator last) +inline typename rtree::size_type +remove(rtree & tree, Iterator first, Iterator last) { - tree.remove(first, last); + return tree.remove(first, last); } /*! @@ -1030,11 +1048,14 @@ Remove a range of values from the index. \param tree The spatial index. \param rng The range of values. + +\return The number of removed values. */ template -inline void remove(rtree & tree, Range const& rng) +inline typename rtree::size_type +remove(rtree & tree, Range const& rng) { - tree.remove(rng); + return tree.remove(rng); } /*! diff --git a/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp b/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp index 2f344a922..a11837c19 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/remove.hpp @@ -109,7 +109,6 @@ public: else { BOOST_GEOMETRY_INDEX_ASSERT(&n == rtree::get(m_root_node), "node must be the root"); - BOOST_GEOMETRY_INDEX_ASSERT(m_is_value_removed, "value not found"); // reinsert elements from removed nodes (underflows) reinsert_removed_nodes_elements(); // MAY THROW (V, E: alloc, copy, N: alloc) @@ -159,6 +158,11 @@ public: } } + bool is_value_removed() const + { + return m_is_value_removed; + } + private: typedef std::vector< std::pair > UnderflowNodes; diff --git a/test/rtree/test_rtree.hpp b/test/rtree/test_rtree.hpp index 07c9bc37e..0593c76c1 100644 --- a/test/rtree/test_rtree.hpp +++ b/test/rtree/test_rtree.hpp @@ -446,6 +446,42 @@ struct generate_input<3> } }; +// generate_value_outside + +template +struct generate_value_outside_impl +{}; + +template +struct generate_value_outside_impl +{ + static Value apply() + { + //TODO - for size > 1 in generate_input<> this won't be outside + return generate_value::apply(13, 26); + } +}; + +template +struct generate_value_outside_impl +{ + static Value apply() + { + //TODO - for size > 1 in generate_input<> this won't be outside + return generate_value::apply(13, 26, 13); + } +}; + +template +inline typename Rtree::value_type +generate_value_outside() +{ + typedef typename Rtree::value_type V; + typedef typename Rtree::indexable_type I; + + return generate_value_outside_impl::value>::apply(); +} + template void generate_rtree(bgi::rtree & tree, std::vector & input, Box & qbox) { @@ -1006,56 +1042,69 @@ void test_remove(bgi::rtree & tree, std::vector const& input std::vector expected_output; tree.spatial_query(bgi::disjoint(qbox), std::back_inserter(expected_output)); + size_t expected_removed_count = values_to_remove.size(); + // Add value which is not stored in the Rtree + Value outsider = generate_value_outside(); + values_to_remove.push_back(outsider); + { T t(tree); + size_t r = 0; BOOST_FOREACH(Value const& v, values_to_remove) - t.remove(v); + r += t.remove(v); + BOOST_CHECK( r == expected_removed_count ); std::vector output; t.spatial_query(bgi::disjoint(qbox), std::back_inserter(output)); - BOOST_CHECK( output.size() == tree.size() - values_to_remove.size() ); + BOOST_CHECK( output.size() == tree.size() - expected_removed_count ); test_compare_outputs(t, output, expected_output); } { T t(tree); - t.remove(values_to_remove.begin(), values_to_remove.end()); + size_t r = t.remove(values_to_remove.begin(), values_to_remove.end()); + BOOST_CHECK( r == expected_removed_count ); std::vector output; t.spatial_query(bgi::disjoint(qbox), std::back_inserter(output)); - BOOST_CHECK( output.size() == tree.size() - values_to_remove.size() ); + BOOST_CHECK( output.size() == tree.size() - expected_removed_count ); test_compare_outputs(t, output, expected_output); } { T t(tree); - t.remove(values_to_remove); + size_t r = t.remove(values_to_remove); + BOOST_CHECK( r == expected_removed_count ); std::vector output; t.spatial_query(bgi::disjoint(qbox), std::back_inserter(output)); - BOOST_CHECK( output.size() == tree.size() - values_to_remove.size() ); + BOOST_CHECK( output.size() == tree.size() - expected_removed_count ); test_compare_outputs(t, output, expected_output); } { T t(tree); + size_t r = 0; BOOST_FOREACH(Value const& v, values_to_remove) - bgi::remove(t, v); + r += bgi::remove(t, v); + BOOST_CHECK( r == expected_removed_count ); std::vector output; bgi::spatial_query(t, bgi::disjoint(qbox), std::back_inserter(output)); - BOOST_CHECK( output.size() == tree.size() - values_to_remove.size() ); + BOOST_CHECK( output.size() == tree.size() - expected_removed_count ); test_compare_outputs(t, output, expected_output); } { T t(tree); - bgi::remove(t, values_to_remove.begin(), values_to_remove.end()); + size_t r = bgi::remove(t, values_to_remove.begin(), values_to_remove.end()); + BOOST_CHECK( r == expected_removed_count ); std::vector output; bgi::spatial_query(t, bgi::disjoint(qbox), std::back_inserter(output)); - BOOST_CHECK( output.size() == tree.size() - values_to_remove.size() ); + BOOST_CHECK( output.size() == tree.size() - expected_removed_count ); test_compare_outputs(t, output, expected_output); } { T t(tree); - bgi::remove(t, values_to_remove); + size_t r = bgi::remove(t, values_to_remove); + BOOST_CHECK( r == expected_removed_count ); std::vector output; bgi::spatial_query(t, bgi::disjoint(qbox), std::back_inserter(output)); - BOOST_CHECK( output.size() == tree.size() - values_to_remove.size() ); + BOOST_CHECK( output.size() == tree.size() - expected_removed_count ); test_compare_outputs(t, output, expected_output); } } @@ -1222,9 +1271,10 @@ void test_count_rtree_values(Parameters const& parameters) BOOST_FOREACH(Value const& v, values_to_remove) { - t.remove(v); + size_t r = t.remove(v); --values_count; + BOOST_CHECK(1 == r); BOOST_CHECK(Value::counter() == values_count); BOOST_CHECK(t.size() + rest_count == values_count); }