]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/geometry/algorithms/detail/overlay/traversal.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / overlay / traversal.hpp
index e0e1ee28d004995515ca53fd129c2c74038ffdc1..a6f8b2a9f526eaac4519ea4e5e09de4b4513863e 100644 (file)
@@ -2,8 +2,8 @@
 
 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
 
-// This file was modified by Oracle on 2017, 2018.
-// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017-2020.
+// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
 
 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
 
 #include <cstddef>
 #include <set>
 
-#include <boost/range.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/value_type.hpp>
 
 #include <boost/geometry/algorithms/detail/overlay/cluster_info.hpp>
+#include <boost/geometry/algorithms/detail/overlay/cluster_exits.hpp>
 #include <boost/geometry/algorithms/detail/overlay/is_self_turn.hpp>
 #include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
@@ -88,21 +91,6 @@ template
 struct traversal
 {
 private :
-    struct linked_turn_op_info
-    {
-        explicit linked_turn_op_info(signed_size_type ti = -1, int oi = -1,
-                    signed_size_type nti = -1)
-            : turn_index(ti)
-            , op_index(oi)
-            , next_turn_index(nti)
-            , rank_index(-1)
-        {}
-
-        signed_size_type turn_index;
-        int op_index;
-        signed_size_type next_turn_index;
-        signed_size_type rank_index;
-    };
 
     static const operation_type target_operation = operation_from_overlay<OverlayType>::value;
 
@@ -741,158 +729,6 @@ public :
         return false;
     }
 
-    inline signed_size_type get_rank(sbs_type const& sbs,
-            linked_turn_op_info const& info) const
-    {
-        for (std::size_t i = 0; i < sbs.m_ranked_points.size(); i++)
-        {
-            typename sbs_type::rp const& rp = sbs.m_ranked_points[i];
-            if (rp.turn_index == info.turn_index
-                    && rp.operation_index == info.op_index
-                    && rp.direction == sort_by_side::dir_to)
-            {
-                return rp.rank;
-            }
-        }
-        return -1;
-    }
-
-    // Function checks simple cases, such as a cluster with two turns,
-    // arriving at the first turn, first turn points to second turn,
-    // second turn points further.
-    inline bool select_turn_from_cluster_linked(signed_size_type& turn_index,
-            int& op_index,
-            std::set<signed_size_type> const& ids,
-            segment_identifier const& previous_seg_id) const
-    {
-        typedef typename std::set<signed_size_type>::const_iterator sit_type;
-
-        std::vector<linked_turn_op_info> possibilities;
-        std::vector<linked_turn_op_info> blocked;
-        for (sit_type it = ids.begin(); it != ids.end(); ++it)
-        {
-            signed_size_type cluster_turn_index = *it;
-            turn_type const& cluster_turn = m_turns[cluster_turn_index];
-            if (cluster_turn.discarded)
-            {
-                continue;
-            }
-            if (cluster_turn.both(target_operation))
-            {
-                // Not (yet) supported, can be cluster of u/u turns
-                return false;
-            }
-            for (int i = 0; i < 2; i++)
-            {
-                turn_operation_type const& op = cluster_turn.operations[i];
-                turn_operation_type const& other_op = cluster_turn.operations[1 - i];
-                signed_size_type const ni = op.enriched.get_next_turn_index();
-                if (op.operation == target_operation
-                    || op.operation == operation_continue)
-                {
-                    if (ni == cluster_turn_index)
-                    {
-                        // Not (yet) supported, traveling to itself, can be
-                        // hole
-                        return false;
-                    }
-                    possibilities.push_back(
-                        linked_turn_op_info(cluster_turn_index, i, ni));
-                }
-                else if (op.operation == operation_blocked
-                         && ! (ni == other_op.enriched.get_next_turn_index())
-                         && ids.count(ni) == 0)
-                {
-                    // Points to turn, not part of this cluster,
-                    // and that way is blocked. But if the other operation
-                    // points at the same turn, it is still fine.
-                    blocked.push_back(
-                        linked_turn_op_info(cluster_turn_index, i, ni));
-                }
-            }
-        }
-
-        typedef typename std::vector<linked_turn_op_info>::const_iterator const_it_type;
-
-        if (! blocked.empty())
-        {
-            sbs_type sbs(m_strategy);
-
-            if (! fill_sbs(sbs, turn_index, ids, previous_seg_id))
-            {
-                return false;
-            }
-
-            for (typename std::vector<linked_turn_op_info>::iterator it = possibilities.begin();
-                 it != possibilities.end(); ++it)
-            {
-                linked_turn_op_info& info = *it;
-                info.rank_index = get_rank(sbs, info);
-            }
-            for (typename std::vector<linked_turn_op_info>::iterator it = blocked.begin();
-                 it != blocked.end(); ++it)
-            {
-                linked_turn_op_info& info = *it;
-                info.rank_index = get_rank(sbs, info);
-            }
-
-
-            for (const_it_type it = possibilities.begin();
-                 it != possibilities.end(); ++it)
-            {
-                linked_turn_op_info const& lti = *it;
-                for (const_it_type bit = blocked.begin();
-                     bit != blocked.end(); ++bit)
-                {
-                    linked_turn_op_info const& blti = *bit;
-                    if (blti.next_turn_index == lti.next_turn_index
-                            && blti.rank_index == lti.rank_index)
-                    {
-                        return false;
-                    }
-                }
-            }
-        }
-
-        // Traversal can either enter the cluster in the first turn,
-        // or it can start halfway.
-        // If there is one (and only one) possibility pointing outside
-        // the cluster, take that one.
-        linked_turn_op_info target;
-        for (const_it_type it = possibilities.begin();
-             it != possibilities.end(); ++it)
-        {
-            linked_turn_op_info const& lti = *it;
-            if (ids.count(lti.next_turn_index) == 0)
-            {
-                if (target.turn_index >= 0
-                    && target.next_turn_index != lti.next_turn_index)
-                {
-                    // Points to different target
-                    return false;
-                }
-                if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)
-                    && target.turn_index > 0)
-                {
-                    // Target already assigned, so there are more targets
-                    // or more ways to the same target
-                    return false;
-                }
-
-                target = lti;
-            }
-        }
-        if (target.turn_index < 0)
-        {
-            return false;
-        }
-
-        turn_index = target.turn_index;
-        op_index = target.op_index;
-
-        return true;
-    }
-
     inline bool fill_sbs(sbs_type& sbs,
                          signed_size_type turn_index,
                          std::set<signed_size_type> const& ids,
@@ -945,11 +781,6 @@ public :
         cluster_info const& cinfo = mit->second;
         std::set<signed_size_type> const& ids = cinfo.turn_indices;
 
-        if (select_turn_from_cluster_linked(turn_index, op_index, ids, previous_seg_id))
-        {
-            return true;
-        }
-
         sbs_type sbs(m_strategy);
 
         if (! fill_sbs(sbs, turn_index, ids, previous_seg_id))
@@ -957,12 +788,24 @@ public :
             return false;
         }
 
+        cluster_exits<OverlayType, Turns, sbs_type> exits(m_turns, ids, sbs);
+
+        if (exits.apply(turn_index, op_index))
+        {
+            return true;
+        }
+
         bool result = false;
 
         if (is_union)
         {
             result = select_from_cluster_union(turn_index, op_index, sbs,
                 start_turn_index, start_op_index);
+            if (! result)
+            {
+               // There no way out found, try second pass in collected cluster exits
+               result = exits.apply(turn_index, op_index, false);
+            }
         }
         else
         {