[Bf-blender-cvs] [416dbb46689] temp-inplace-priority-queue: support changing priorities

Jacques Lucke noreply at git.blender.org
Tue Dec 15 23:03:40 CET 2020


Commit: 416dbb466893cd4ce263b917b4ba9e7b12bbc3ae
Author: Jacques Lucke
Date:   Tue Dec 15 21:36:10 2020 +0100
Branches: temp-inplace-priority-queue
https://developer.blender.org/rB416dbb466893cd4ce263b917b4ba9e7b12bbc3ae

support changing priorities

===================================================================

M	source/blender/blenlib/BLI_inplace_priority_queue.hh

===================================================================

diff --git a/source/blender/blenlib/BLI_inplace_priority_queue.hh b/source/blender/blenlib/BLI_inplace_priority_queue.hh
index 0252891f4ec..c00c6dd5340 100644
--- a/source/blender/blenlib/BLI_inplace_priority_queue.hh
+++ b/source/blender/blenlib/BLI_inplace_priority_queue.hh
@@ -28,14 +28,17 @@ namespace blender {
 template<typename DataArray> class InplacePriorityQueue {
  private:
   DataArray &data_;
-  Array<int64_t> index_map_;
+  Array<int64_t> heap_to_orig_;
+  Array<int64_t> orig_to_heap_;
   int64_t heap_size_ = 0;
 
  public:
-  InplacePriorityQueue(DataArray &data) : data_(data), index_map_(data_.size())
+  InplacePriorityQueue(DataArray &data)
+      : data_(data), heap_to_orig_(data_.size()), orig_to_heap_(data_.size())
   {
-    for (const int64_t i : index_map_.index_range()) {
-      index_map_[i] = i;
+    for (const int64_t i : IndexRange(data_.size())) {
+      heap_to_orig_[i] = i;
+      orig_to_heap_[i] = i;
     }
   }
 
@@ -63,42 +66,59 @@ template<typename DataArray> class InplacePriorityQueue {
   int64_t peek_top() const
   {
     BLI_assert(!this->is_empty());
-    return index_map_[0];
+    return heap_to_orig_[0];
   }
 
   int64_t pop_top()
   {
     BLI_assert(!this->is_empty());
-    const int64_t top_index = index_map_[0];
+    const int64_t top_index_orig = heap_to_orig_[0];
     heap_size_--;
     if (heap_size_ > 1) {
       this->swap_indices(0, heap_size_);
       this->heapify(0, heap_size_);
     }
-    return top_index;
+    return top_index_orig;
   }
 
-  std::string all_to_dot() const
+  void priority_decreased(const int64_t index)
   {
-    return this->partial_to_dot(data_.size());
+    const int64_t heap_index = orig_to_heap_[index];
+    BLI_assert(heap_index < heap_size_);
+    this->heapify(heap_index, heap_size_);
   }
 
-  std::string partial_to_dot(const int size) const
+  void priority_increased(const int64_t index)
   {
-    dot::DirectedGraph digraph;
-    Array<dot::Node *> dot_nodes(size);
-    for (const int i : IndexRange(size)) {
-      const std::string name = this->data_.get_value_string(index_map_[i]);
-      dot::Node &node = digraph.new_node(name);
-      node.set_shape(dot::Attr_shape::Rectangle);
-      node.attributes.set("ordering", "out");
-      dot_nodes[i] = &node;
-      if (i > 0) {
-        const int64_t parent = this->get_parent(i);
-        digraph.new_edge(*dot_nodes[parent], node);
+    int64_t current = orig_to_heap_[index];
+    BLI_assert(current < heap_size_);
+    while (true) {
+      if (current == 0) {
+        break;
+      }
+      const int64_t parent = this->get_parent(current);
+      if (this->is_higher_priority(parent, current)) {
+        break;
       }
+      this->swap_indices(current, parent);
+      current = parent;
     }
-    return digraph.to_dot_string();
+  }
+
+  void priority_changed(const int64_t index)
+  {
+    this->priority_increased(index);
+    this->priority_decreased(index);
+  }
+
+  std::string all_to_dot() const
+  {
+    return this->partial_to_dot(data_.size());
+  }
+
+  std::string active_to_dot() const
+  {
+    return this->partial_to_dot(heap_size_);
   }
 
   DataArray &data()
@@ -109,12 +129,14 @@ template<typename DataArray> class InplacePriorityQueue {
  private:
   bool is_higher_priority(const int64_t a, const int64_t b)
   {
-    return data_.is_higher_priority(index_map_[a], index_map_[b]);
+    return data_.is_higher_priority(heap_to_orig_[a], heap_to_orig_[b]);
   }
 
   void swap_indices(const int64_t a, const int64_t b)
   {
-    std::swap(index_map_[a], index_map_[b]);
+    std::swap(heap_to_orig_[a], heap_to_orig_[b]);
+    orig_to_heap_[heap_to_orig_[a]] = a;
+    orig_to_heap_[heap_to_orig_[b]] = b;
   }
 
   void heapify(const int64_t index, const int64_t heap_size)
@@ -149,6 +171,24 @@ template<typename DataArray> class InplacePriorityQueue {
   {
     return parent * 2 + 2;
   }
+
+  std::string partial_to_dot(const int size) const
+  {
+    dot::DirectedGraph digraph;
+    Array<dot::Node *> dot_nodes(size);
+    for (const int i : IndexRange(size)) {
+      const std::string name = this->data_.get_value_string(heap_to_orig_[i]);
+      dot::Node &node = digraph.new_node(name);
+      node.set_shape(dot::Attr_shape::Rectangle);
+      node.attributes.set("ordering", "out");
+      dot_nodes[i] = &node;
+      if (i > 0) {
+        const int64_t parent = this->get_parent(i);
+        digraph.new_edge(*dot_nodes[parent], node);
+      }
+    }
+    return digraph.to_dot_string();
+  }
 };
 
 }  // namespace blender



More information about the Bf-blender-cvs mailing list