/*
 *
 *	$Header: /net/virgo/virgo/rucklidg/src/ADT/RCS/priq.h,v 1.3 1991/06/03 23:02:29 rucklidg Exp $
 *
 */
/*
 * priq.h - header file for the priority queue module
 */
#ifndef PRIQ_H
#define PRIQ_H

#if      0
BEGIN DOCUMENTATION


/*
 *	priq.c - Priority Queues
 *
 * This module handles generic priority queues.
 *
 * Exports:
 *	type PriQ
 *
 *	constant PriQ NULLPRIQ
 *	constant ListNode NULLLISTNODE
 *
 *	PriQ pqNew(boolean (*compareGT)()) - create a new, empty priority queue
 *
 *	void pqFree(PriQ p) - free priority queue p
 *
 *	PriQNode pqFirst(PriQ p) - return and remove the first entry in p
 *
 *	PriQNode pqAdd(PriQ p, char *userdata) - add a node containing
 *		userdata to p
 *
 *	void pqRem(PriQNode pqn) - remove pqn from the queue containing it
 *
 *	char *pqGet(PriQNode pqn) - return pqn's userdata
 *
 * An object of type PriQ is used as a handle on a priority queue.
 *	Each element of the queue contains a char *
 *	field, which is used for whatever data the user wishes to attach
 *	to that node. It is standard C idiom that (void *) pointers can
 *	be cast to and from any other type of pointer without error or loss,
 *	but the DECStation C compiler chokes on them, so I am using (char *)
 *	instead.
 *
 * A PriQNode refers to an entry in a priority queue.
 *
 * pqNew creates an empty queue. If this is not possible, it returns NULLPRIQ.
 *	The function which it takes is used as the comparison function to
 *	sort the queue. It should be declared as
 *	boolean compareGT(a, b)
 *	char *a;
 *	char *b;
 *	and it returns FALSE if "a" <= "b" and TRUE if "a" > "b".
 *	It does not compare the pointers themselves (priq could do that
 *	itself), but rather compares the user data values associated with
 *	those pointers in whatever way the user desires (which should be
 *	a total order). It will be called as required to ensure that
 *	pqRem returns the smallest valued entry.
 *
 * pqFree frees the storage associated with a priority queue.
 *	Note that it does not free the userdata; the user
 *	must do this before freeing the queue structure.
 *
 * pqFirst returns the first (smallest) entry of the given queue.
 *	It does not guarantee any order among equal elements.
 *	If the queue is empty, it returns NULLPRIQNODE.
 *
 * pqAdd adds an entry to the given priority queue. It returns the new
 *	PriQNode. If it could not allocate needed storage, it returns
 *	NULLPRIQNODE.
 *
 * pqRem removes the given PriQNode from its PriQ. The PriQNode is then
 *	invalid.
 *
 * pqGet returns the userdata value of some PriQNode.
 *
 * Changing the values pointed to by the userdata pointers may result
 *	in pqFirst not returning the smallest current value. To change these,
 *	perform a pqRem and a pqAdd.
 *
 * pqAdd, pqRem and other operations involving PriQNodes may be arbitrarily
 *	interleaved. A PriQNode is valid from the moment pqAdd first returns
 *	it until it is passed into pqRem, or its containing PriQ is passed
 *	to pqFree.
 *
 */

END DOCUMENTATION
#endif   




/*
 * Types. These types are opaque. You can't see these, really...
 */
typedef struct {
    struct _PriQIntNode *root, *last;
    boolean (*compareGT)();
    } *PriQ;

typedef struct _PriQIntNode {
    struct _PriQIntNode *left, *right, *parent, *next, *prev;
    struct _PriQNode *owner;
    char *userdata;
    } *PriQIntNode;

typedef struct _PriQNode {
    PriQIntNode val;
    PriQ owner;
    } *PriQNode;

/*
 * Constants
 */
#define	NULLPRIQ	((PriQ)NULL)
#define	NULLPRIQNODE	((PriQNode)NULL)

/*
 * Functions
 */
extern PriQ pqNew(boolean (*compareGT)());
extern void pqFree(PriQ p);
extern PriQNode pqFirst(PriQ p);
extern PriQNode pqAdd(PriQ p, char *userdata);
extern void pqRem(PriQNode pqn);
extern char *pqGet(PriQNode pqn);

#endif
