/* Fibonacci heap for GNU compiler.
   Copyright (C) 1998-2021 Free Software Foundation, Inc.
   Contributed by Daniel Berlin (dan@cgsoftware.com).
   Re-implemented in C++ by Martin Liska <mliska@suse.cz>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* Fibonacci heaps are somewhat complex, but, there's an article in
   DDJ that explains them pretty well:

   http://www.ddj.com/articles/1997/9701/9701o/9701o.htm?topic=algoritms

   Introduction to algorithms by Corman and Rivest also goes over them.

   The original paper that introduced them is "Fibonacci heaps and their
   uses in improved network optimization algorithms" by Tarjan and
   Fredman (JACM 34(3), July 1987).

   Amortized and real worst case time for operations:

   ExtractMin: O(lg n) amortized. O(n) worst case.
   DecreaseKey: O(1) amortized.  O(lg n) worst case.
   Insert: O(1) amortized.
   Union: O(1) amortized.  */

#ifndef GCC_FIBONACCI_HEAP_H
#define GCC_FIBONACCI_HEAP_H

/* Forward definition.  */

template<class K, class V>
class fibonacci_heap;

/* Fibonacci heap node class.  */

template<class K, class V>
class fibonacci_node
{
  typedef fibonacci_node<K,V> fibonacci_node_t;
  friend class fibonacci_heap<K,V>;

public:
  /* Default constructor.  */
  fibonacci_node (): m_parent (NULL), m_child (NULL), m_left (this),
    m_right (this), m_data (NULL), m_degree (0), m_mark (0)
  {
  }

  /* Constructor for a node with given KEY.  */
  fibonacci_node (K key, V *data = NULL): m_parent (NULL), m_child (NULL),
    m_left (this), m_right (this), m_key (key), m_data (data),
    m_degree (0), m_mark (0)
  {
  }

  /* Compare fibonacci node with OTHER node.  */
  int compare (fibonacci_node_t *other)
  {
    if (m_key < other->m_key)
      return -1;
    if (m_key > other->m_key)
      return 1;
    return 0;
  }

  /* Compare the node with a given KEY.  */
  int compare_data (K key)
  {
    return fibonacci_node_t (key).compare (this);
  }

  /* Remove fibonacci heap node.  */
  fibonacci_node_t *remove ();

  /* Link the node with PARENT.  */
  void link (fibonacci_node_t *parent);

  /* Return key associated with the node.  */
  K get_key ()
  {
    return m_key;
  }

  /* Return data associated with the node.  */
  V *get_data ()
  {
    return m_data;
  }

private:
  /* Put node B after this node.  */
  void insert_after (fibonacci_node_t *b);

  /* Insert fibonacci node B after this node.  */
  void insert_before (fibonacci_node_t *b)
  {
    m_left->insert_after (b);
  }

  /* Parent node.  */
  fibonacci_node *m_parent;
  /* Child node.  */
  fibonacci_node *m_child;
  /* Left sibling.  */
  fibonacci_node *m_left;
  /* Right node.  */
  fibonacci_node *m_right;
  /* Key associated with node.  */
  K m_key;
  /* Data associated with node.  */
  V *m_data;

#if defined (__GNUC__) && (!defined (SIZEOF_INT) || SIZEOF_INT < 4)
  /* Degree of the node.  */
  __extension__ unsigned long int m_degree : 31;
  /* Mark of the node.  */
  __extension__ unsigned long int m_mark : 1;
#else
  /* Degree of the node.  */
  unsigned int m_degree : 31;
  /* Mark of the node.  */
  unsigned int m_mark : 1;
#endif
};

/* Fibonacci heap class. */
template<class K, class V>
class fibonacci_heap
{
  typedef fibonacci_node<K,V> fibonacci_node_t;
  friend class fibonacci_node<K,V>;

public:
  /* Default constructor.  ALLOCATOR is optional and is primarily useful
     when heaps are going to be merged (in that case they need to be allocated
     in same alloc pool).  */
  fibonacci_heap (K global_min_key, pool_allocator *allocator = NULL):
    m_nodes (0), m_min (NULL), m_root (NULL),
    m_global_min_key (global_min_key),
    m_allocator (allocator), m_own_allocator (false)
  {
    if (!m_allocator)
      {
	m_allocator = new pool_allocator ("Fibonacci heap",
					    sizeof (fibonacci_node_t));
	m_own_allocator = true;
      }
  }

  /* Destructor.  */
  ~fibonacci_heap ()
  {
    /* Actual memory will be released by the destructor of m_allocator.  */
    if (need_finalization_p<fibonacci_node_t> () || !m_own_allocator)
      while (m_min != NULL)
	{
	  fibonacci_node_t *n = extract_minimum_node ();
	  n->~fibonacci_node_t ();
	  if (!m_own_allocator)
	    m_allocator->remove (n);
	}
    if (m_own_allocator)
      delete m_allocator;
  }

  /* Insert new node given by KEY and DATA associated with the key.  */
  fibonacci_node_t *insert (K key, V *data);

  /* Return true if no entry is present.  */
  bool empty () const
  {
    return m_nodes == 0;
  }

  /* Return the number of nodes.  */
  size_t nodes () const
  {
    return m_nodes;
  }

  /* Return minimal key presented in the heap.  */
  K min_key () const
  {
    if (m_min == NULL)
      gcc_unreachable ();

    return m_min->m_key;
  }

  /* For given NODE, set new KEY value.  */
  K replace_key (fibonacci_node_t *node, K key)
  {
    K okey = node->m_key;

    replace_key_data (node, key, node->m_data);
    return okey;
  }

  /* For given NODE, decrease value to new KEY.  */
  K decrease_key (fibonacci_node_t *node, K key)
  {
    gcc_assert (key <= node->m_key);
    return replace_key (node, key);
  }

  /* For given NODE, set new KEY and DATA value.  */
  V *replace_key_data (fibonacci_node_t *node, K key, V *data);

  /* Extract minimum node in the heap. If RELEASE is specified,
     memory is released.  */
  V *extract_min (bool release = true);

  /* Return value associated with minimum node in the heap.  */
  V *min () const
  {
    if (m_min == NULL)
      return NULL;

    return m_min->m_data;
  }

  /* Replace data associated with NODE and replace it with DATA.  */
  V *replace_data (fibonacci_node_t *node, V *data)
  {
    return replace_key_data (node, node->m_key, data);
  }

  /* Delete NODE in the heap.  */
  V *delete_node (fibonacci_node_t *node, bool release = true);

  /* Union the heap with HEAPB.  */
  fibonacci_heap *union_with (fibonacci_heap *heapb);

private:
  /* Insert new NODE given by KEY and DATA associated with the key.  */
  fibonacci_node_t *insert (fibonacci_node_t *node, K key, V *data);

  /* Insert new NODE that has already filled key and value.  */
  fibonacci_node_t *insert_node (fibonacci_node_t *node);

  /* Insert it into the root list.  */
  void insert_root (fibonacci_node_t *node);

  /* Remove NODE from PARENT's child list.  */
  void cut (fibonacci_node_t *node, fibonacci_node_t *parent);

  /* Process cut of node Y and do it recursivelly.  */
  void cascading_cut (fibonacci_node_t *y);

  /* Extract minimum node from the heap.  */
  fibonacci_node_t * extract_minimum_node ();

  /* Remove root NODE from the heap.  */
  void remove_root (fibonacci_node_t *node);

  /* Consolidate heap.  */
  void consolidate ();

  /* Number of nodes.  */
  size_t m_nodes;
  /* Minimum node of the heap.  */
  fibonacci_node_t *m_min;
  /* Root node of the heap.  */
  fibonacci_node_t *m_root;
  /* Global minimum given in the heap construction.  */
  K m_global_min_key;

  /* Allocator used to hold nodes.  */
  pool_allocator *m_allocator;
  /* True if alocator is owned by the current heap only.  */
  bool m_own_allocator;
};

/* Remove fibonacci heap node.  */

template<class K, class V>
fibonacci_node<K,V> *
fibonacci_node<K,V>::remove ()
{
  fibonacci_node<K,V> *ret;

  if (this == m_left)
    ret = NULL;
  else
    ret = m_left;

  if (m_parent != NULL && m_parent->m_child == this)
    m_parent->m_child = ret;

  m_right->m_left = m_left;
  m_left->m_right = m_right;

  m_parent = NULL;
  m_left = this;
  m_right = this;

  return ret;
}

/* Link the node with PARENT.  */

template<class K, class V>
void
fibonacci_node<K,V>::link (fibonacci_node<K,V> *parent)
{
  if (parent->m_child == NULL)
    parent->m_child = this;
  else
    parent->m_child->insert_before (this);
  m_parent = parent;
  parent->m_degree++;
  m_mark = 0;
}

/* Put node B after this node.  */

template<class K, class V>
void
fibonacci_node<K,V>::insert_after (fibonacci_node<K,V> *b)
{
  fibonacci_node<K,V> *a = this;

  if (a == a->m_right)
    {
      a->m_right = b;
      a->m_left = b;
      b->m_right = a;
      b->m_left = a;
    }
  else
    {
      b->m_right = a->m_right;
      a->m_right->m_left = b;
      a->m_right = b;
      b->m_left = a;
    }
}

/* Insert new node given by KEY and DATA associated with the key.  */

template<class K, class V>
fibonacci_node<K,V>*
fibonacci_heap<K,V>::insert (K key, V *data)
{
  /* Create the new node.  */
  fibonacci_node<K,V> *node = new (m_allocator->allocate ())
				  fibonacci_node_t (key, data);

  return insert_node (node);
}

/* Insert new NODE given by DATA associated with the key.  */

template<class K, class V>
fibonacci_node<K,V>*
fibonacci_heap<K,V>::insert (fibonacci_node_t *node, K key, V *data)
{
  /* Set the node's data.  */
  node->m_data = data;
  node->m_key = key;

  return insert_node (node);
}

/* Insert new NODE that has already filled key and value.  */

template<class K, class V>
fibonacci_node<K,V>*
fibonacci_heap<K,V>::insert_node (fibonacci_node_t *node)
{
  /* Insert it into the root list.  */
  insert_root (node);

  /* If their was no minimum, or this key is less than the min,
     it's the new min.  */
  if (m_min == NULL || node->m_key < m_min->m_key)
    m_min = node;

  m_nodes++;

  return node;
}

/* For given NODE, set new KEY and DATA value.  */

template<class K, class V>
V*
fibonacci_heap<K,V>::replace_key_data (fibonacci_node<K,V> *node, K key,
				       V *data)
{
  K okey;
  fibonacci_node<K,V> *y;
  V *odata = node->m_data;

  /* If we wanted to, we do a real increase by redeleting and
     inserting.  */
  if (node->compare_data (key) > 0)
    {
      delete_node (node, false);

      node = new (node) fibonacci_node_t ();
      insert (node, key, data);

      return odata;
    }

  okey = node->m_key;
  node->m_data = data;
  node->m_key = key;
  y = node->m_parent;

  /* Short-circuit if the key is the same, as we then don't have to
     do anything.  Except if we're trying to force the new node to
     be the new minimum for delete.  */
  if (okey == key && okey != m_global_min_key)
    return odata;

  /* These two compares are specifically <= 0 to make sure that in the case
     of equality, a node we replaced the data on, becomes the new min.  This
     is needed so that delete's call to extractmin gets the right node.  */
  if (y != NULL && node->compare (y) <= 0)
    {
      cut (node, y);
      cascading_cut (y);
    }

  if (node->compare (m_min) <= 0)
    m_min = node;

  return odata;
}

/* Extract minimum node in the heap.  Delete fibonacci node if RELEASE
   is true.  */

template<class K, class V>
V*
fibonacci_heap<K,V>::extract_min (bool release)
{
  fibonacci_node<K,V> *z;
  V *ret = NULL;

  /* If we don't have a min set, it means we have no nodes.  */
  if (m_min != NULL)
    {
      /* Otherwise, extract the min node, free the node, and return the
       node's data.  */
      z = extract_minimum_node ();
      ret = z->m_data;

      if (release)
	{
	  z->~fibonacci_node_t ();
	  m_allocator->remove (z);
	}
    }

  return ret;
}

/* Delete NODE in the heap, if RELEASE is specified memory is released.  */

template<class K, class V>
V*
fibonacci_heap<K,V>::delete_node (fibonacci_node<K,V> *node, bool release)
{
  V *ret = node->m_data;

  /* To perform delete, we just make it the min key, and extract.  */
  replace_key (node, m_global_min_key);
  if (node != m_min)
    {
      fprintf (stderr, "Can't force minimum on fibheap.\n");
      abort ();
    }
  extract_min (release);

  return ret;
}

/* Union the heap with HEAPB.  One of the heaps is going to be deleted.  */

template<class K, class V>
fibonacci_heap<K,V>*
fibonacci_heap<K,V>::union_with (fibonacci_heap<K,V> *heapb)
{
  fibonacci_heap<K,V> *heapa = this;

  fibonacci_node<K,V> *a_root, *b_root;

  /* Both heaps must share allocator.  */
  gcc_checking_assert (m_allocator == heapb->m_allocator);

  /* If one of the heaps is empty, the union is just the other heap.  */
  if ((a_root = heapa->m_root) == NULL)
    {
      delete (heapa);
      return heapb;
    }
  if ((b_root = heapb->m_root) == NULL)
    {
      delete (heapb);
      return heapa;
    }

  /* Merge them to the next nodes on the opposite chain.  */
  a_root->m_left->m_right = b_root;
  b_root->m_left->m_right = a_root;
  std::swap (a_root->m_left, b_root->m_left);
  heapa->m_nodes += heapb->m_nodes;

  /* And set the new minimum, if it's changed.  */
  if (heapb->m_min->compare (heapa->m_min) < 0)
    heapa->m_min = heapb->m_min;

  /* Set m_min to NULL to not to delete live fibonacci nodes.  */
  heapb->m_min = NULL;
  delete (heapb);

  return heapa;
}

/* Insert it into the root list.  */

template<class K, class V>
void
fibonacci_heap<K,V>::insert_root (fibonacci_node_t *node)
{
  /* If the heap is currently empty, the new node becomes the singleton
     circular root list.  */
  if (m_root == NULL)
    {
      m_root = node;
      node->m_left = node;
      node->m_right = node;
      return;
    }

  /* Otherwise, insert it in the circular root list between the root
     and it's right node.  */
  m_root->insert_after (node);
}

/* Remove NODE from PARENT's child list.  */

template<class K, class V>
void
fibonacci_heap<K,V>::cut (fibonacci_node<K,V> *node,
			  fibonacci_node<K,V> *parent)
{
  node->remove ();
  parent->m_degree--;
  insert_root (node);
  node->m_parent = NULL;
  node->m_mark = 0;
}

/* Process cut of node Y and do it recursivelly.  */

template<class K, class V>
void
fibonacci_heap<K,V>::cascading_cut (fibonacci_node<K,V> *y)
{
  fibonacci_node<K,V> *z;

  while ((z = y->m_parent) != NULL)
    {
      if (y->m_mark == 0)
	{
	  y->m_mark = 1;
	  return;
	}
      else
	{
	  cut (y, z);
	  y = z;
	}
    }
}

/* Extract minimum node from the heap.  */

template<class K, class V>
fibonacci_node<K,V>*
fibonacci_heap<K,V>::extract_minimum_node ()
{
  fibonacci_node<K,V> *ret = m_min;
  fibonacci_node<K,V> *x, *y, *orig;

  /* Attach the child list of the minimum node to the root list of the heap.
     If there is no child list, we don't do squat.  */
  for (x = ret->m_child, orig = NULL; x != orig && x != NULL; x = y)
    {
      if (orig == NULL)
	orig = x;
      y = x->m_right;
      x->m_parent = NULL;
      insert_root (x);
    }

  /* Remove the old root.  */
  remove_root (ret);
  m_nodes--;

  /* If we are left with no nodes, then the min is NULL.  */
  if (m_nodes == 0)
    m_min = NULL;
  else
    {
      /* Otherwise, consolidate to find new minimum, as well as do the reorg
       work that needs to be done.  */
      m_min = ret->m_right;
      consolidate ();
    }

  return ret;
}

/* Remove root NODE from the heap.  */

template<class K, class V>
void
fibonacci_heap<K,V>::remove_root (fibonacci_node<K,V> *node)
{
  if (node->m_left == node)
    m_root = NULL;
  else
    m_root = node->remove ();
}

/* Consolidate heap.  */

template<class K, class V>
void fibonacci_heap<K,V>::consolidate ()
{
  const int D = 1 + 8 * sizeof (long);
  fibonacci_node<K,V> *a[D];
  fibonacci_node<K,V> *w, *x, *y;
  int i, d;

  memset (a, 0, sizeof (a));

  while ((w = m_root) != NULL)
    {
      x = w;
      remove_root (w);
      d = x->m_degree;
      gcc_checking_assert (d < D);
      while (a[d] != NULL)
	{
	  y = a[d];
	  if (x->compare (y) > 0)
	    std::swap (x, y);
	  y->link (x);
	  a[d] = NULL;
	  d++;
	}
      a[d] = x;
    }
  m_min = NULL;
  for (i = 0; i < D; i++)
    if (a[i] != NULL)
      {
	insert_root (a[i]);
	if (m_min == NULL || a[i]->compare (m_min) < 0)
	  m_min = a[i];
      }
}

#endif  // GCC_FIBONACCI_HEAP_H
