/* Vector API for GNU compiler.
   Copyright (C) 1998-2016 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_degree (0), m_mark (0)
  {
  }

  /* Constructor for a node with given KEY.  */
  fibonacci_node (K key): m_parent (NULL), m_child (NULL), m_left (this),
    m_right (this), m_key (key),
    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.  */
  fibonacci_heap (K global_min_key): m_nodes (0), m_min (NULL), m_root (NULL),
    m_global_min_key (global_min_key)
  {
  }

  /* Destructor.  */
  ~fibonacci_heap ()
  {
    while (m_min != NULL)
      delete (extract_minimum_node ());
  }

  /* 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 ()
  {
    return m_nodes == 0;
  }

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

  /* Return minimal key presented in the heap.  */
  K min_key ()
  {
    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 ()
  {
    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 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;
};

/* 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 fibonacci_node_t ();

  return insert (node, key, data);
}

/* 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 (fibonacci_node_t *node, K key, V *data)
{
  /* Set the node's data.  */
  node->m_data = data;
  node->m_key = key;

  /* 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.  */
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)
        delete (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.  */

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;

  /* 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->min->compare (heapa->min) < 0)
    heapa->m_min = heapb->m_min;

  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 ()
{
  int D = 1 + 8 * sizeof (long);
  auto_vec<fibonacci_node<K,V> *> a (D);
  a.safe_grow_cleared (D);
  fibonacci_node<K,V> *w, *x, *y;
  int i, d;

  while ((w = m_root) != NULL)
    {
      x = w;
      remove_root (w);
      d = x->m_degree;
      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
