are_counts_ok.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. // This file was modified by Oracle on 2019-2023.
  8. // Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
  9. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  10. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  11. //
  12. // Use, modification and distribution is subject to the Boost Software License,
  13. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  14. // http://www.boost.org/LICENSE_1_0.txt)
  15. #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
  16. #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
  17. #include <boost/geometry/index/detail/rtree/node/node.hpp>
  18. #include <boost/geometry/index/detail/rtree/utilities/view.hpp>
  19. namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
  20. namespace visitors {
  21. template <typename MembersHolder>
  22. class are_counts_ok
  23. : public MembersHolder::visitor_const
  24. {
  25. typedef typename MembersHolder::parameters_type parameters_type;
  26. typedef typename MembersHolder::internal_node internal_node;
  27. typedef typename MembersHolder::leaf leaf;
  28. public:
  29. inline are_counts_ok(parameters_type const& parameters, bool check_min = true)
  30. : result(true)
  31. , m_current_level(0)
  32. , m_parameters(parameters)
  33. , m_check_min(check_min)
  34. {}
  35. inline void operator()(internal_node const& n)
  36. {
  37. typedef typename rtree::elements_type<internal_node>::type elements_type;
  38. elements_type const& elements = rtree::elements(n);
  39. // root internal node shouldn't contain 0 elements
  40. if ( (elements.empty() && m_check_min)
  41. || !check_count(elements) )
  42. {
  43. result = false;
  44. return;
  45. }
  46. size_t current_level_backup = m_current_level;
  47. ++m_current_level;
  48. for ( typename elements_type::const_iterator it = elements.begin();
  49. it != elements.end() && result == true ;
  50. ++it)
  51. {
  52. rtree::apply_visitor(*this, *it->second);
  53. }
  54. m_current_level = current_level_backup;
  55. }
  56. inline void operator()(leaf const& n)
  57. {
  58. typedef typename rtree::elements_type<leaf>::type elements_type;
  59. elements_type const& elements = rtree::elements(n);
  60. // empty leaf in non-root node
  61. if ( (m_current_level > 0 && elements.empty() && m_check_min)
  62. || !check_count(elements) )
  63. {
  64. result = false;
  65. }
  66. }
  67. bool result;
  68. private:
  69. template <typename Elements>
  70. bool check_count(Elements const& elements)
  71. {
  72. // root may contain count < min but should never contain count > max
  73. return elements.size() <= m_parameters.get_max_elements()
  74. && ( elements.size() >= m_parameters.get_min_elements()
  75. || m_current_level == 0 || !m_check_min );
  76. }
  77. size_t m_current_level;
  78. parameters_type const& m_parameters;
  79. bool m_check_min;
  80. };
  81. } // namespace visitors
  82. template <typename Rtree> inline
  83. bool are_counts_ok(Rtree const& tree, bool check_min = true)
  84. {
  85. typedef utilities::view<Rtree> RTV;
  86. RTV rtv(tree);
  87. visitors::are_counts_ok<
  88. typename RTV::members_holder
  89. > v(tree.parameters(), check_min);
  90. rtv.apply_visitor(v);
  91. return v.result;
  92. }
  93. }}}}}} // namespace boost::geometry::index::detail::rtree::utilities
  94. #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP