/* Priority queue functions.
   Copyright (C) 2003 Yasuhiro Ohara

This file is part of GNU Zebra.

GNU Zebra 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 2, or (at your
option) any later version.

GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#include <zebra.h>

#include "pqueue.h"

/* priority queue using heap sort */

/* pqueue->cmp() controls the order of sorting (i.e, ascending or
   descending). If you want the left node to move upper of the heap
   binary tree, make cmp() to return less than 0.  for example, if cmp
   (10, 20) returns -1, the sorting is ascending order. if cmp (10,
   20) returns 1, the sorting is descending order. if cmp (10, 20)
   returns 0, this library does not do sorting (which will not be what
   you want).  To be brief, if the contents of cmp_func (left, right)
   is left - right, dequeue () returns the smallest node.  Otherwise
   (if the contents is right - left), dequeue () returns the largest
   node.  */

#define DATA_SIZE (sizeof (void *))
#define PARENT_OF(x) ((x - 1) / 2)
#define LEFT_OF(x)  (2 * x + 1)
#define RIGHT_OF(x) (2 * x + 2)
#define HAVE_CHILD(x,q) (x < (q)->size / 2)

static void
trickle_up (int index, struct pqueue *queue)
{
  void *tmp;

  /* Save current node as tmp node.  */
  tmp = queue->array[index];

  /* Continue until the node reaches top or the place where the parent
     node should be upper than the tmp node.  */
  while (index > 0 &&
         (*queue->cmp) (tmp, queue->array[PARENT_OF (index)]) < 0)
    {
      /* actually trickle up */
      queue->array[index] = queue->array[PARENT_OF (index)];
      if (queue->update != NULL)
	(*queue->update) (queue->array[index], index);
      index = PARENT_OF (index);
    }

  /* Restore the tmp node to appropriate place.  */
  queue->array[index] = tmp;
  if (queue->update != NULL)
    (*queue->update) (tmp, index);
}

void
trickle_down (int index, struct pqueue *queue)
{
  void *tmp;
  int which;

  /* Save current node as tmp node.  */
  tmp = queue->array[index];

  /* Continue until the node have at least one (left) child.  */
  while (HAVE_CHILD (index, queue))
    {
      /* If right child exists, and if the right child is more proper
         to be moved upper.  */
      if (RIGHT_OF (index) < queue->size &&
          (*queue->cmp) (queue->array[LEFT_OF (index)],
                         queue->array[RIGHT_OF (index)]) > 0)
        which = RIGHT_OF (index);
      else
        which = LEFT_OF (index);

      /* If the tmp node should be upper than the child, break.  */
      if ((*queue->cmp) (queue->array[which], tmp) > 0)
        break;

      /* Actually trickle down the tmp node.  */
      queue->array[index] = queue->array[which];
       if (queue->update != NULL)
	 (*queue->update) (queue->array[index], index);
      index = which;
    }

  /* Restore the tmp node to appropriate place.  */
  queue->array[index] = tmp;
  if (queue->update != NULL)
    (*queue->update) (tmp, index);
}

struct pqueue *
pqueue_create (void)
{
  struct pqueue *queue;

  queue = (struct pqueue *) malloc (sizeof (struct pqueue));
  memset (queue, 0, sizeof (struct pqueue));

  queue->array = (void **)
    malloc (DATA_SIZE * PQUEUE_INIT_ARRAYSIZE);
  memset (queue->array, 0, DATA_SIZE * PQUEUE_INIT_ARRAYSIZE);
  queue->array_size = PQUEUE_INIT_ARRAYSIZE;

  /* By default we want nothing to happen when a node changes. */
  queue->update = NULL;
  return queue;
}

void
pqueue_delete (struct pqueue *queue)
{
  free (queue->array);
  free (queue);
}

static int
pqueue_expand (struct pqueue *queue)
{
  void **newarray;

  newarray = (void **) malloc (queue->array_size * DATA_SIZE * 2);
  if (newarray == NULL)
    return 0;

  memset (newarray, 0, queue->array_size * DATA_SIZE * 2);
  memcpy (newarray, queue->array, queue->array_size * DATA_SIZE);

  free (queue->array);
  queue->array = newarray;
  queue->array_size *= 2;

  return 1;
}

void
pqueue_enqueue (void *data, struct pqueue *queue)
{
  if (queue->size + 2 >= queue->array_size && ! pqueue_expand (queue))
    return;

  queue->array[queue->size] = data;
  if (queue->update != NULL)
    (*queue->update) (data, queue->size);
  trickle_up (queue->size, queue);
  queue->size ++;
}

void *
pqueue_dequeue (struct pqueue *queue)
{
  void *data = queue->array[0];
  queue->array[0] =  queue->array[--queue->size];
  trickle_down (0, queue);
  return data;
}
