Annotation of embedaddon/ntp/ntpd/ntp_data_structures.c, revision 1.1

1.1     ! misho       1: /* ntp_data_structures.c
        !             2:  *
        !             3:  * This file contains the data structures used by the ntp configuration
        !             4:  * code and the discrete event simulator.
        !             5:  *
        !             6:  * Written By: Sachin Kamboj
        !             7:  *             University of Delaware
        !             8:  *             Newark, DE 19711
        !             9:  * Copyright (c) 2006
        !            10:  */
        !            11: 
        !            12: 
        !            13: #include <stdlib.h>    /* Needed for malloc */
        !            14: #include "ntp_data_structures.h"
        !            15: #include "ntp_stdlib.h"
        !            16: 
        !            17: /* Priority Queue
        !            18:  * --------------
        !            19:  * Define a priority queue in which the relative priority of the elements
        !            20:  * is determined by a function 'get_order' which is supplied to the
        !            21:  * priority_queue
        !            22:  */
        !            23: 
        !            24: 
        !            25: queue *create_priority_queue(int (*get_order)(void *, void *))
        !            26: {
        !            27:     queue *my_queue = (queue *) emalloc(sizeof(queue));
        !            28:     my_queue->get_order = get_order;
        !            29:     my_queue->front = NULL;
        !            30:     my_queue->no_of_elements = 0;
        !            31:     return my_queue;
        !            32: }
        !            33: 
        !            34: 
        !            35: /* Define a function to "destroy" a priority queue, freeing-up
        !            36:  * all the allocated resources in the process 
        !            37:  */
        !            38: 
        !            39: void destroy_queue(queue *my_queue)
        !            40: {
        !            41:     node *temp = NULL;
        !            42: 
        !            43:     /* Empty out the queue elements if they are not already empty */
        !            44:     while (my_queue->front != NULL) {
        !            45:         temp = my_queue->front;
        !            46:         my_queue->front = my_queue->front->node_next;
        !            47:         free(temp);
        !            48:     }
        !            49: 
        !            50:     /* Now free the queue */
        !            51:     free(my_queue);
        !            52: }
        !            53: 
        !            54: 
        !            55: /* Define a function to allocate memory for one element 
        !            56:  * of the queue. The allocated memory consists of size
        !            57:  * bytes plus the number of bytes needed for bookkeeping
        !            58:  */
        !            59: 
        !            60: void *get_node(size_t size)
        !            61: {
        !            62:     node *new_node = emalloc(sizeof(*new_node) + size);
        !            63:     new_node->node_next = NULL; 
        !            64:     return new_node + 1;
        !            65: }
        !            66: 
        !            67: /* Define a function to free the allocated memory for a queue node */
        !            68: void free_node(void *my_node)
        !            69: {
        !            70:     node *old_node = my_node;
        !            71:     free(old_node - 1);
        !            72: }
        !            73: 
        !            74: 
        !            75: void *
        !            76: next_node(
        !            77:        void *pv
        !            78:        )
        !            79: {
        !            80:        node *pn;
        !            81: 
        !            82:        pn = pv;
        !            83:        pn--;
        !            84: 
        !            85:        if (pn->node_next == NULL)
        !            86:                return NULL;
        !            87: 
        !            88:        return pn->node_next + 1;
        !            89: }
        !            90: 
        !            91: 
        !            92: /* Define a function to check if the queue is empty. */
        !            93: int empty(queue *my_queue)
        !            94: {
        !            95:     return (!my_queue || !my_queue->front);
        !            96: }
        !            97: 
        !            98: 
        !            99: void *
        !           100: queue_head(
        !           101:        queue *q
        !           102:        )
        !           103: {
        !           104:        if (NULL == q || NULL == q->front)
        !           105:                return NULL;
        !           106:                
        !           107:        return q->front + 1;
        !           108: }
        !           109: 
        !           110: 
        !           111: /* Define a function to add an element to the priority queue.
        !           112:  * The element is added according to its priority - 
        !           113:  * relative priority is given by the get_order function
        !           114:  */
        !           115: queue *enqueue(queue *my_queue, void *my_node)
        !           116: {
        !           117:     node *new_node = ((node *) my_node) - 1;
        !           118:     node *i = NULL;
        !           119:     node *j = my_queue->front;
        !           120: 
        !           121:     while (j != NULL && ((*my_queue->get_order)(new_node + 1, j + 1) > 0)) {
        !           122:         i = j;
        !           123:         j = j->node_next;
        !           124:     }
        !           125:     
        !           126:     if (i == NULL) {       /* Insert at beginning of the queue */
        !           127:         new_node->node_next = my_queue->front;
        !           128:         my_queue->front = new_node;
        !           129:     }
        !           130:     else {                /* Insert Elsewhere, including the end */
        !           131:         new_node->node_next = i->node_next;
        !           132:         i->node_next = new_node;
        !           133:     }
        !           134: 
        !           135:     ++my_queue->no_of_elements;    
        !           136:     return my_queue;
        !           137: }
        !           138: 
        !           139: 
        !           140: /* Define a function to dequeue the first element from the priority
        !           141:  * queue and return it
        !           142:  */
        !           143: 
        !           144: void *dequeue(queue *my_queue)
        !           145: {
        !           146:     node *my_node = my_queue->front;
        !           147:     if (my_node != NULL) {
        !           148:         my_queue->front = my_node->node_next;
        !           149:         --my_queue->no_of_elements;    
        !           150:         return (void *)(my_node + 1);
        !           151:     }
        !           152:     else
        !           153:         return NULL;
        !           154: }
        !           155: 
        !           156: /* Define a function that returns the number of elements in the 
        !           157:  * priority queue
        !           158:  */
        !           159: int get_no_of_elements(queue *my_queue)
        !           160: {
        !           161:     return my_queue->no_of_elements;
        !           162: }
        !           163: 
        !           164: /* Define a function to append a queue onto another.
        !           165:  * Note: there is a faster way (O(1) as opposed to O(n))
        !           166:  * to do this for simple (FIFO) queues, but we can't rely on
        !           167:  * that for priority queues. (Given the current representation)
        !           168:  * 
        !           169:  * I don't anticipate this to be a problem. If it does turn
        !           170:  * out to be a bottleneck, I will consider replacing the 
        !           171:  * current implementation with a binomial or fibonacci heap.
        !           172:  */
        !           173: 
        !           174: void append_queue(queue *q1, queue *q2) 
        !           175: {
        !           176:     while (!empty(q2))
        !           177:         enqueue(q1, dequeue(q2));
        !           178:     destroy_queue(q2);
        !           179: }
        !           180: 
        !           181: /* FIFO Queue
        !           182:  * ----------
        !           183:  * Use the priority queue to create a traditional FIFO queue.
        !           184:  * The only extra function needed is the create_queue 
        !           185:  */
        !           186: 
        !           187: /* C is not Lisp and does not allow anonymous lambda functions :-(. 
        !           188:  * So define a get_fifo_order function here
        !           189:  */
        !           190: 
        !           191: int get_fifo_order(void *el1, void *el2)
        !           192: {   return 1;
        !           193: }
        !           194: 
        !           195: /* Define a function to create a FIFO queue */
        !           196: 
        !           197: queue *create_queue()
        !           198: {    return create_priority_queue(get_fifo_order);
        !           199: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>