9
3

are_counts_ok.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Boost.Geometry Index
  2. //
  3. // R-tree nodes elements numbers validating visitor implementation
  4. //
  5. // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
  6. //
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
  11. #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
  12. #include <boost/geometry/index/detail/rtree/node/node.hpp>
  13. namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
  14. namespace visitors {
  15. template <typename Value, typename Options, typename Box, typename Allocators>
  16. class are_counts_ok
  17. : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
  18. {
  19. typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
  20. typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
  21. typedef typename Options::parameters_type parameters_type;
  22. public:
  23. inline are_counts_ok(parameters_type const& parameters)
  24. : result(true), m_current_level(0), m_parameters(parameters)
  25. {}
  26. inline void operator()(internal_node const& n)
  27. {
  28. typedef typename rtree::elements_type<internal_node>::type elements_type;
  29. elements_type const& elements = rtree::elements(n);
  30. // root internal node shouldn't contain 0 elements
  31. if ( elements.empty()
  32. || !check_count(elements) )
  33. {
  34. result = false;
  35. return;
  36. }
  37. size_t current_level_backup = m_current_level;
  38. ++m_current_level;
  39. for ( typename elements_type::const_iterator it = elements.begin();
  40. it != elements.end() && result == true ;
  41. ++it)
  42. {
  43. rtree::apply_visitor(*this, *it->second);
  44. }
  45. m_current_level = current_level_backup;
  46. }
  47. inline void operator()(leaf const& n)
  48. {
  49. typedef typename rtree::elements_type<leaf>::type elements_type;
  50. elements_type const& elements = rtree::elements(n);
  51. // empty leaf in non-root node
  52. if ( ( m_current_level > 0 && elements.empty() )
  53. || !check_count(elements) )
  54. {
  55. result = false;
  56. }
  57. }
  58. bool result;
  59. private:
  60. template <typename Elements>
  61. bool check_count(Elements const& elements)
  62. {
  63. // root may contain count < min but should never contain count > max
  64. return elements.size() <= m_parameters.get_max_elements()
  65. && ( elements.size() >= m_parameters.get_min_elements()
  66. || m_current_level == 0 );
  67. }
  68. size_t m_current_level;
  69. parameters_type const& m_parameters;
  70. };
  71. } // namespace visitors
  72. template <typename Rtree> inline
  73. bool are_counts_ok(Rtree const& tree)
  74. {
  75. typedef utilities::view<Rtree> RTV;
  76. RTV rtv(tree);
  77. visitors::are_counts_ok<
  78. typename RTV::value_type,
  79. typename RTV::options_type,
  80. typename RTV::box_type,
  81. typename RTV::allocators_type
  82. > v(tree.parameters());
  83. rtv.apply_visitor(v);
  84. return v.result;
  85. }
  86. }}}}}} // namespace boost::geometry::index::detail::rtree::utilities
  87. #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP