Merge pull request #5894 from xlaussel/avoid_samelookup_in_heap_map

Avoid samelookup in heap map
This commit is contained in:
Denis Chapligin
2020-12-20 22:17:49 +02:00
committed by GitHub
7 changed files with 292 additions and 236 deletions
+60 -14
View File
@@ -3,6 +3,7 @@
#include <boost/assert.hpp>
#include <boost/heap/d_ary_heap.hpp>
#include <boost/optional.hpp>
#include <algorithm>
#include <limits>
@@ -194,10 +195,26 @@ template <typename NodeID,
typename IndexStorage = ArrayStorage<NodeID, NodeID>>
class QueryHeap
{
private:
using HeapData = std::pair<Weight, Key>;
using HeapContainer = boost::heap::d_ary_heap<HeapData,
boost::heap::arity<4>,
boost::heap::mutable_<true>,
boost::heap::compare<std::greater<HeapData>>>;
using HeapHandle = typename HeapContainer::handle_type;
public:
using WeightType = Weight;
using DataType = Data;
struct HeapNode
{
HeapHandle handle;
NodeID node;
Weight weight;
Data data;
};
template <typename... StorageArgs> explicit QueryHeap(StorageArgs... args) : node_index(args...)
{
Clear();
@@ -230,6 +247,13 @@ class QueryHeap
return inserted_nodes[index].data;
}
HeapNode &getHeapNode(NodeID node)
{
const auto index = node_index.peek_index(node);
BOOST_ASSERT((int)index >= 0 && (int)index < (int)inserted_nodes.size());
return inserted_nodes[index];
}
Data const &GetData(NodeID node) const
{
const auto index = node_index.peek_index(node);
@@ -269,6 +293,28 @@ class QueryHeap
return inserted_nodes[index].node == node;
}
boost::optional<HeapNode &> GetHeapNodeIfWasInserted(const NodeID node)
{
const auto index = node_index.peek_index(node);
if (index >= static_cast<decltype(index)>(inserted_nodes.size()) ||
inserted_nodes[index].node != node)
{
return {};
}
return inserted_nodes[index];
}
boost::optional<const HeapNode &> GetHeapNodeIfWasInserted(const NodeID node) const
{
const auto index = node_index.peek_index(node);
if (index >= static_cast<decltype(index)>(inserted_nodes.size()) ||
inserted_nodes[index].node != node)
{
return {};
}
return inserted_nodes[index];
}
NodeID Min() const
{
BOOST_ASSERT(!heap.empty());
@@ -290,6 +336,15 @@ class QueryHeap
return inserted_nodes[removedIndex].node;
}
HeapNode &DeleteMinGetHeapNode()
{
BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().second;
heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex];
}
void DeleteAll()
{
auto const none_handle = heap.s_handle_from_iterator(heap.end());
@@ -308,22 +363,13 @@ class QueryHeap
heap.increase(reference.handle, std::make_pair(weight, index));
}
private:
using HeapData = std::pair<Weight, Key>;
using HeapContainer = boost::heap::d_ary_heap<HeapData,
boost::heap::arity<4>,
boost::heap::mutable_<true>,
boost::heap::compare<std::greater<HeapData>>>;
using HeapHandle = typename HeapContainer::handle_type;
struct HeapNode
void DecreaseKey(const HeapNode &heapNode)
{
HeapHandle handle;
NodeID node;
Weight weight;
Data data;
};
BOOST_ASSERT(!WasRemoved(heapNode.node));
heap.increase(heapNode.handle, std::make_pair(heapNode.weight, (*heapNode.handle).second));
}
private:
std::vector<HeapNode> inserted_nodes;
HeapContainer heap;
IndexStorage node_index;