/* ntp_data_structures.c
*
* This file contains the data structures used by the ntp configuration
* code and the discrete event simulator.
*
* Written By: Sachin Kamboj
* University of Delaware
* Newark, DE 19711
* Copyright (c) 2006
*/
#include <stdlib.h> /* Needed for malloc */
#include "ntp_data_structures.h"
#include "ntp_stdlib.h"
/* Priority Queue
* --------------
* Define a priority queue in which the relative priority of the elements
* is determined by a function 'get_order' which is supplied to the
* priority_queue
*/
queue *create_priority_queue(int (*get_order)(void *, void *))
{
queue *my_queue = (queue *) emalloc(sizeof(queue));
my_queue->get_order = get_order;
my_queue->front = NULL;
my_queue->no_of_elements = 0;
return my_queue;
}
/* Define a function to "destroy" a priority queue, freeing-up
* all the allocated resources in the process
*/
void destroy_queue(queue *my_queue)
{
node *temp = NULL;
/* Empty out the queue elements if they are not already empty */
while (my_queue->front != NULL) {
temp = my_queue->front;
my_queue->front = my_queue->front->node_next;
free(temp);
}
/* Now free the queue */
free(my_queue);
}
/* Define a function to allocate memory for one element
* of the queue. The allocated memory consists of size
* bytes plus the number of bytes needed for bookkeeping
*/
void *get_node(size_t size)
{
node *new_node = emalloc(sizeof(*new_node) + size);
new_node->node_next = NULL;
return new_node + 1;
}
/* Define a function to free the allocated memory for a queue node */
void free_node(void *my_node)
{
node *old_node = my_node;
free(old_node - 1);
}
void *
next_node(
void *pv
)
{
node *pn;
pn = pv;
pn--;
if (pn->node_next == NULL)
return NULL;
return pn->node_next + 1;
}
/* Define a function to check if the queue is empty. */
int empty(queue *my_queue)
{
return (!my_queue || !my_queue->front);
}
void *
queue_head(
queue *q
)
{
if (NULL == q || NULL == q->front)
return NULL;
return q->front + 1;
}
/* Define a function to add an element to the priority queue.
* The element is added according to its priority -
* relative priority is given by the get_order function
*/
queue *enqueue(queue *my_queue, void *my_node)
{
node *new_node = ((node *) my_node) - 1;
node *i = NULL;
node *j = my_queue->front;
while (j != NULL && ((*my_queue->get_order)(new_node + 1, j + 1) > 0)) {
i = j;
j = j->node_next;
}
if (i == NULL) { /* Insert at beginning of the queue */
new_node->node_next = my_queue->front;
my_queue->front = new_node;
}
else { /* Insert Elsewhere, including the end */
new_node->node_next = i->node_next;
i->node_next = new_node;
}
++my_queue->no_of_elements;
return my_queue;
}
/* Define a function to dequeue the first element from the priority
* queue and return it
*/
void *dequeue(queue *my_queue)
{
node *my_node = my_queue->front;
if (my_node != NULL) {
my_queue->front = my_node->node_next;
--my_queue->no_of_elements;
return (void *)(my_node + 1);
}
else
return NULL;
}
/* Define a function that returns the number of elements in the
* priority queue
*/
int get_no_of_elements(queue *my_queue)
{
return my_queue->no_of_elements;
}
/* Define a function to append a queue onto another.
* Note: there is a faster way (O(1) as opposed to O(n))
* to do this for simple (FIFO) queues, but we can't rely on
* that for priority queues. (Given the current representation)
*
* I don't anticipate this to be a problem. If it does turn
* out to be a bottleneck, I will consider replacing the
* current implementation with a binomial or fibonacci heap.
*/
void append_queue(queue *q1, queue *q2)
{
while (!empty(q2))
enqueue(q1, dequeue(q2));
destroy_queue(q2);
}
/* FIFO Queue
* ----------
* Use the priority queue to create a traditional FIFO queue.
* The only extra function needed is the create_queue
*/
/* C is not Lisp and does not allow anonymous lambda functions :-(.
* So define a get_fifo_order function here
*/
int get_fifo_order(void *el1, void *el2)
{ return 1;
}
/* Define a function to create a FIFO queue */
queue *create_queue()
{ return create_priority_queue(get_fifo_order);
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>