statistics.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Boost.Geometry Index
  2. //
  3. // R-tree visitor collecting basic statistics
  4. //
  5. // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
  6. // Copyright (c) 2013 Mateusz Loskot, London, UK.
  7. //
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
  12. #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
  13. #include <algorithm>
  14. #include <boost/tuple/tuple.hpp>
  15. namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
  16. namespace visitors {
  17. template <typename Value, typename Options, typename Box, typename Allocators>
  18. struct statistics : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
  19. {
  20. typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
  21. typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
  22. inline statistics()
  23. : level(0)
  24. , levels(1) // count root
  25. , nodes(0)
  26. , leaves(0)
  27. , values(0)
  28. , values_min(0)
  29. , values_max(0)
  30. {}
  31. inline void operator()(internal_node const& n)
  32. {
  33. typedef typename rtree::elements_type<internal_node>::type elements_type;
  34. elements_type const& elements = rtree::elements(n);
  35. ++nodes; // count node
  36. size_t const level_backup = level;
  37. ++level;
  38. levels += level++ > levels ? 1 : 0; // count level (root already counted)
  39. for (typename elements_type::const_iterator it = elements.begin();
  40. it != elements.end(); ++it)
  41. {
  42. rtree::apply_visitor(*this, *it->second);
  43. }
  44. level = level_backup;
  45. }
  46. inline void operator()(leaf const& n)
  47. {
  48. typedef typename rtree::elements_type<leaf>::type elements_type;
  49. elements_type const& elements = rtree::elements(n);
  50. ++leaves; // count leaves
  51. std::size_t const v = elements.size();
  52. // count values spread per node and total
  53. values_min = (std::min)(values_min == 0 ? v : values_min, v);
  54. values_max = (std::max)(values_max, v);
  55. values += v;
  56. }
  57. std::size_t level;
  58. std::size_t levels;
  59. std::size_t nodes;
  60. std::size_t leaves;
  61. std::size_t values;
  62. std::size_t values_min;
  63. std::size_t values_max;
  64. };
  65. } // namespace visitors
  66. template <typename Rtree> inline
  67. boost::tuple<std::size_t, std::size_t, std::size_t, std::size_t, std::size_t, std::size_t>
  68. statistics(Rtree const& tree)
  69. {
  70. typedef utilities::view<Rtree> RTV;
  71. RTV rtv(tree);
  72. visitors::statistics<
  73. typename RTV::value_type,
  74. typename RTV::options_type,
  75. typename RTV::box_type,
  76. typename RTV::allocators_type
  77. > stats_v;
  78. rtv.apply_visitor(stats_v);
  79. return boost::make_tuple(stats_v.levels, stats_v.nodes, stats_v.leaves, stats_v.values, stats_v.values_min, stats_v.values_max);
  80. }
  81. }}}}}} // namespace boost::geometry::index::detail::rtree::utilities
  82. #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP