mirror of
https://github.com/boostorg/geometry.git
synced 2026-01-29 19:42:10 +00:00
[index] Rewrite predicate checks in query visitors.
This commit is contained in:
@@ -84,11 +84,10 @@ public:
|
||||
inline distance_query_result(size_type k)
|
||||
: m_count(k)
|
||||
{
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(0 < m_count, "Number of neighbors should be greater than 0");
|
||||
|
||||
m_neighbors.reserve(m_count);
|
||||
}
|
||||
|
||||
// NOTE: Do not call if max_count() == 0
|
||||
inline void store(DistanceType const& distance, const Value * value_ptr)
|
||||
{
|
||||
if (m_neighbors.size() < m_count)
|
||||
@@ -109,6 +108,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Do not call if max_count() == 0
|
||||
inline bool ignore_branch(DistanceType const& distance) const
|
||||
{
|
||||
return m_neighbors.size() == m_count
|
||||
@@ -127,6 +127,11 @@ public:
|
||||
return m_neighbors.size();
|
||||
}
|
||||
|
||||
size_type max_count() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
private:
|
||||
size_type m_count;
|
||||
neighbors_type m_neighbors;
|
||||
@@ -184,28 +189,29 @@ public:
|
||||
};
|
||||
|
||||
inline distance_query(parameters_type const& parameters, translator_type const& translator, Predicates const& pred)
|
||||
: m_parameters(parameters), m_translator(translator)
|
||||
: m_tr(translator)
|
||||
, m_pred(pred)
|
||||
, m_result(nearest_predicate_access::get(m_pred).count)
|
||||
, m_strategy(index::detail::get_strategy(parameters))
|
||||
{
|
||||
//m_branches.reserve(m_parameters.get_max_elements() * levels_count); ?
|
||||
//m_branches.reserve(parameters.get_max_elements() * levels_count); ?
|
||||
}
|
||||
|
||||
template <typename OutIter>
|
||||
size_type apply(node_pointer root, OutIter out_it)
|
||||
{
|
||||
if (m_result.max_count() <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_level = 1;
|
||||
rtree::apply_visitor(*this, *root);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (m_branches.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_result.ignore_branch(m_branches.top().distance))
|
||||
if (m_branches.empty()
|
||||
|| m_result.ignore_branch(m_branches.top().distance))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -226,30 +232,18 @@ public:
|
||||
// fill array of nodes meeting predicates
|
||||
for (auto const& p : rtree::elements(n))
|
||||
{
|
||||
// if current node meets predicates
|
||||
// 0 - dummy value
|
||||
if (! id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node_distance_type node_distance; // for distance predicate
|
||||
|
||||
// calculate node's distance(s) for distance predicate
|
||||
node_distance_type node_distance;
|
||||
// if distance isn't ok - move to the next node
|
||||
if (! calculate_node_distance::apply(predicate(), p.first,
|
||||
m_strategy, node_distance))
|
||||
// if current node meets predicates (0 is dummy value)
|
||||
if (id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy)
|
||||
// and if distance is ok
|
||||
&& calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance)
|
||||
// and if current node is closer than the furthest neighbor
|
||||
&& ! m_result.ignore_branch(node_distance))
|
||||
{
|
||||
continue;
|
||||
// add current node's data into the list
|
||||
m_branches.push(branch_data(node_distance, m_level, p.second));
|
||||
}
|
||||
|
||||
// if current node is further than found neighbors - don't analyze it
|
||||
if (m_result.ignore_branch(node_distance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// add current node's data into the list
|
||||
m_branches.push(branch_data(node_distance, m_level, p.second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,23 +254,16 @@ public:
|
||||
// search leaf for closest value meeting predicates
|
||||
for (auto const& v : rtree::elements(n))
|
||||
{
|
||||
value_distance_type value_distance; // for distance predicate
|
||||
|
||||
// if value meets predicates
|
||||
if (! id::predicates_check<id::value_tag>(m_pred, v, m_translator(v), m_strategy))
|
||||
if (id::predicates_check<id::value_tag>(m_pred, v, m_tr(v), m_strategy)
|
||||
// and if distance is ok
|
||||
&& calculate_value_distance::apply(predicate(), m_tr(v), m_strategy, value_distance))
|
||||
{
|
||||
continue;
|
||||
// store value
|
||||
m_result.store(value_distance, boost::addressof(v));
|
||||
}
|
||||
|
||||
// calculate values distance for distance predicate
|
||||
value_distance_type value_distance;
|
||||
// if distance is ok
|
||||
if (! calculate_value_distance::apply(predicate(), m_translator(v),
|
||||
m_strategy, value_distance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// store value
|
||||
m_result.store(value_distance, boost::addressof(v));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,10 +273,10 @@ private:
|
||||
return nearest_predicate_access::get(m_pred);
|
||||
}
|
||||
|
||||
parameters_type const& m_parameters;
|
||||
translator_type const& m_translator;
|
||||
translator_type const& m_tr;
|
||||
|
||||
Predicates m_pred;
|
||||
|
||||
distance_query_result<value_distance_type, value_type> m_result;
|
||||
priority_queue<branch_data, branch_data_comp> m_branches;
|
||||
size_type m_level;
|
||||
@@ -340,7 +327,7 @@ public:
|
||||
using neighbors_type = priority_dequeue<neighbor_data, pair_first_greater>;
|
||||
|
||||
inline distance_query_incremental()
|
||||
: m_translator(nullptr)
|
||||
: m_tr(nullptr)
|
||||
// , m_pred()
|
||||
, m_neighbors_count(0)
|
||||
, m_neighbor_ptr(nullptr)
|
||||
@@ -348,7 +335,7 @@ public:
|
||||
{}
|
||||
|
||||
inline distance_query_incremental(parameters_type const& params, translator_type const& translator, Predicates const& pred)
|
||||
: m_translator(::boost::addressof(translator))
|
||||
: m_tr(::boost::addressof(translator))
|
||||
, m_pred(pred)
|
||||
, m_neighbors_count(0)
|
||||
, m_neighbor_ptr(nullptr)
|
||||
@@ -407,8 +394,7 @@ public:
|
||||
BOOST_GEOMETRY_INDEX_ASSERT(m_neighbors_count + m_neighbors.size() <= max_count(), "unexpected neighbors count");
|
||||
|
||||
// if there is enough neighbors and there is no closer branch
|
||||
if (m_neighbors_count + m_neighbors.size() == max_count()
|
||||
&& (m_neighbors.empty() || m_neighbors.bottom().first <= closest_branch.first))
|
||||
if (ignore_branch_or_value(closest_branch.first))
|
||||
{
|
||||
m_branches.clear();
|
||||
continue;
|
||||
@@ -444,30 +430,18 @@ public:
|
||||
// fill active branch list array of nodes meeting predicates
|
||||
for (auto const& p : rtree::elements(n))
|
||||
{
|
||||
// if current node doesn't meet predicates
|
||||
// 0 - dummy value
|
||||
if (! id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node_distance_type node_distance; // for distance predicate
|
||||
|
||||
// calculate node's distance(s) for distance predicate
|
||||
node_distance_type node_distance;
|
||||
// if distance isn't ok
|
||||
if (! calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance))
|
||||
// if current node meets predicates (0 is dummy value)
|
||||
if (id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy)
|
||||
// and if distance is ok
|
||||
&& calculate_node_distance::apply(predicate(), p.first, m_strategy, node_distance)
|
||||
// and if current node is closer than the furthest neighbor
|
||||
&& ! ignore_branch_or_value(node_distance))
|
||||
{
|
||||
continue;
|
||||
// add current node into the queue
|
||||
m_branches.push(std::make_pair(node_distance, p.second));
|
||||
}
|
||||
|
||||
// if there is enough neighbors and there is no closer branch
|
||||
if (m_neighbors_count + m_neighbors.size() == max_count()
|
||||
&& (m_neighbors.empty() || m_neighbors.bottom().first <= node_distance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// add current node into the queue
|
||||
m_branches.push(std::make_pair(node_distance, p.second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,38 +455,35 @@ public:
|
||||
// search leaf for closest value meeting predicates
|
||||
for (auto const& v : rtree::elements(n))
|
||||
{
|
||||
// if value doesn't meet predicates
|
||||
if (! id::predicates_check<id::value_tag>(m_pred, v, (*m_translator)(v), m_strategy))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate values distance for distance predicate
|
||||
value_distance_type value_distance;
|
||||
// if distance isn't ok
|
||||
if (! calculate_value_distance::apply(predicate(), (*m_translator)(v),
|
||||
m_strategy, value_distance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
value_distance_type value_distance; // for distance predicate
|
||||
|
||||
// if there is enough neighbors and there is no closer neighbor
|
||||
if (m_neighbors_count + m_neighbors.size() == max_count()
|
||||
&& (m_neighbors.empty() || m_neighbors.bottom().first <= value_distance))
|
||||
// if value meets predicates
|
||||
if (id::predicates_check<id::value_tag>(m_pred, v, (*m_tr)(v), m_strategy)
|
||||
// and if distance is ok
|
||||
&& calculate_value_distance::apply(predicate(), (*m_tr)(v), m_strategy, value_distance)
|
||||
// and if current value is closer than the furthest neighbor
|
||||
&& ! ignore_branch_or_value(value_distance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// add current value into the queue
|
||||
m_neighbors.push(std::make_pair(value_distance, boost::addressof(v)));
|
||||
|
||||
// add current value into the queue
|
||||
m_neighbors.push(std::make_pair(value_distance, boost::addressof(v)));
|
||||
if (m_neighbors_count + m_neighbors.size() > max_count())
|
||||
{
|
||||
m_neighbors.pop_bottom();
|
||||
// remove unneeded value
|
||||
if (m_neighbors_count + m_neighbors.size() > max_count())
|
||||
{
|
||||
m_neighbors.pop_bottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Distance>
|
||||
inline bool ignore_branch_or_value(Distance const& distance)
|
||||
{
|
||||
return m_neighbors_count + m_neighbors.size() == max_count()
|
||||
&& (m_neighbors.empty() || m_neighbors.bottom().first <= distance);
|
||||
}
|
||||
|
||||
inline std::size_t max_count() const
|
||||
{
|
||||
return nearest_predicate_access::get(m_pred).count;
|
||||
@@ -523,7 +494,7 @@ private:
|
||||
return nearest_predicate_access::get(m_pred);
|
||||
}
|
||||
|
||||
const translator_type * m_translator;
|
||||
const translator_type * m_tr;
|
||||
|
||||
Predicates m_pred;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ struct spatial_query
|
||||
typedef typename allocators_type::size_type size_type;
|
||||
|
||||
inline spatial_query(parameters_type const& par, translator_type const& t, Predicates const& p, OutIter out_it)
|
||||
: tr(t), pred(p), out_iter(out_it), found_count(0), strategy(index::detail::get_strategy(par))
|
||||
: m_tr(t), m_pred(p), m_out_iter(out_it), m_found_count(0), m_strategy(index::detail::get_strategy(par))
|
||||
{}
|
||||
|
||||
size_type apply(node_pointer root)
|
||||
@@ -58,7 +58,7 @@ struct spatial_query
|
||||
rtree::apply_visitor(*this, *ptr);
|
||||
}
|
||||
|
||||
return found_count;
|
||||
return m_found_count;
|
||||
}
|
||||
|
||||
inline void operator()(internal_node const& n)
|
||||
@@ -68,9 +68,8 @@ struct spatial_query
|
||||
// traverse nodes meeting predicates
|
||||
for (auto const& p : rtree::elements(n))
|
||||
{
|
||||
// if node meets predicates
|
||||
// 0 - dummy value
|
||||
if (id::predicates_check<id::bounds_tag>(pred, 0, p.first, strategy))
|
||||
// if node meets predicates (0 is dummy value)
|
||||
if (id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy))
|
||||
{
|
||||
m_internal_stack.push_back(p.second);
|
||||
}
|
||||
@@ -85,27 +84,26 @@ struct spatial_query
|
||||
for (auto const& v : rtree::elements(n))
|
||||
{
|
||||
// if value meets predicates
|
||||
if (id::predicates_check<id::value_tag>(pred, v, tr(v), strategy))
|
||||
if (id::predicates_check<id::value_tag>(m_pred, v, m_tr(v), m_strategy))
|
||||
{
|
||||
*out_iter = v;
|
||||
++out_iter;
|
||||
|
||||
++found_count;
|
||||
*m_out_iter = v;
|
||||
++m_out_iter;
|
||||
++m_found_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
translator_type const& tr;
|
||||
translator_type const& m_tr;
|
||||
|
||||
Predicates pred;
|
||||
Predicates m_pred;
|
||||
|
||||
std::vector<node_pointer> m_internal_stack;
|
||||
|
||||
OutIter out_iter;
|
||||
size_type found_count;
|
||||
OutIter m_out_iter;
|
||||
size_type m_found_count;
|
||||
|
||||
strategy_type strategy;
|
||||
strategy_type m_strategy;
|
||||
};
|
||||
|
||||
template <typename MembersHolder, typename Predicates>
|
||||
|
||||
Reference in New Issue
Block a user