Home | History | Annotate | Download | only in pqueue
      1 /* crypto/pqueue/pqueue.c */
      2 /*
      3  * DTLS implementation written by Nagendra Modadugu
      4  * (nagendra (at) cs.stanford.edu) for the OpenSSL project 2005.
      5  */
      6 /* ====================================================================
      7  * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  *
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  *
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in
     18  *    the documentation and/or other materials provided with the
     19  *    distribution.
     20  *
     21  * 3. All advertising materials mentioning features or use of this
     22  *    software must display the following acknowledgment:
     23  *    "This product includes software developed by the OpenSSL Project
     24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     25  *
     26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     27  *    endorse or promote products derived from this software without
     28  *    prior written permission. For written permission, please contact
     29  *    openssl-core (at) OpenSSL.org.
     30  *
     31  * 5. Products derived from this software may not be called "OpenSSL"
     32  *    nor may "OpenSSL" appear in their names without prior written
     33  *    permission of the OpenSSL Project.
     34  *
     35  * 6. Redistributions of any form whatsoever must retain the following
     36  *    acknowledgment:
     37  *    "This product includes software developed by the OpenSSL Project
     38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     51  * OF THE POSSIBILITY OF SUCH DAMAGE.
     52  * ====================================================================
     53  *
     54  * This product includes cryptographic software written by Eric Young
     55  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     56  * Hudson (tjh (at) cryptsoft.com).
     57  *
     58  */
     59 
     60 #include "cryptlib.h"
     61 #include <openssl/bn.h>
     62 #include "pqueue.h"
     63 
     64 typedef struct _pqueue
     65 	{
     66 	pitem *items;
     67 	int count;
     68 	} pqueue_s;
     69 
     70 pitem *
     71 pitem_new(PQ_64BIT priority, void *data)
     72 	{
     73 	pitem *item = (pitem *) OPENSSL_malloc(sizeof(pitem));
     74 	if (item == NULL) return NULL;
     75 
     76 	pq_64bit_init(&(item->priority));
     77 	pq_64bit_assign(&item->priority, &priority);
     78 
     79 	item->data = data;
     80 	item->next = NULL;
     81 
     82 	return item;
     83 	}
     84 
     85 void
     86 pitem_free(pitem *item)
     87 	{
     88 	if (item == NULL) return;
     89 
     90 	pq_64bit_free(&(item->priority));
     91 	OPENSSL_free(item);
     92 	}
     93 
     94 pqueue_s *
     95 pqueue_new()
     96 	{
     97 	pqueue_s *pq = (pqueue_s *) OPENSSL_malloc(sizeof(pqueue_s));
     98 	if (pq == NULL) return NULL;
     99 
    100 	memset(pq, 0x00, sizeof(pqueue_s));
    101 	return pq;
    102 	}
    103 
    104 void
    105 pqueue_free(pqueue_s *pq)
    106 	{
    107 	if (pq == NULL) return;
    108 
    109 	OPENSSL_free(pq);
    110 	}
    111 
    112 pitem *
    113 pqueue_insert(pqueue_s *pq, pitem *item)
    114 	{
    115 	pitem *curr, *next;
    116 
    117 	if (pq->items == NULL)
    118 		{
    119 		pq->items = item;
    120 		return item;
    121 		}
    122 
    123 	for(curr = NULL, next = pq->items;
    124 		next != NULL;
    125 		curr = next, next = next->next)
    126 		{
    127 		if (pq_64bit_gt(&(next->priority), &(item->priority)))
    128 			{
    129 			item->next = next;
    130 
    131 			if (curr == NULL)
    132 				pq->items = item;
    133 			else
    134 				curr->next = item;
    135 
    136 			return item;
    137 			}
    138 		/* duplicates not allowed */
    139 		if (pq_64bit_eq(&(item->priority), &(next->priority)))
    140 			return NULL;
    141 		}
    142 
    143 	item->next = NULL;
    144 	curr->next = item;
    145 
    146 	return item;
    147 	}
    148 
    149 pitem *
    150 pqueue_peek(pqueue_s *pq)
    151 	{
    152 	return pq->items;
    153 	}
    154 
    155 pitem *
    156 pqueue_pop(pqueue_s *pq)
    157 	{
    158 	pitem *item = pq->items;
    159 
    160 	if (pq->items != NULL)
    161 		pq->items = pq->items->next;
    162 
    163 	return item;
    164 	}
    165 
    166 pitem *
    167 pqueue_find(pqueue_s *pq, PQ_64BIT priority)
    168 	{
    169 	pitem *next, *prev = NULL;
    170 	pitem *found = NULL;
    171 
    172 	if ( pq->items == NULL)
    173 		return NULL;
    174 
    175 	for ( next = pq->items; next->next != NULL;
    176 		  prev = next, next = next->next)
    177 		{
    178 		if ( pq_64bit_eq(&(next->priority), &priority))
    179 			{
    180 			found = next;
    181 			break;
    182 			}
    183 		}
    184 
    185 	/* check the one last node */
    186 	if ( pq_64bit_eq(&(next->priority), &priority))
    187 		found = next;
    188 
    189 	if ( ! found)
    190 		return NULL;
    191 
    192 #if 0 /* find works in peek mode */
    193 	if ( prev == NULL)
    194 		pq->items = next->next;
    195 	else
    196 		prev->next = next->next;
    197 #endif
    198 
    199 	return found;
    200 	}
    201 
    202 #if PQ_64BIT_IS_INTEGER
    203 void
    204 pqueue_print(pqueue_s *pq)
    205 	{
    206 	pitem *item = pq->items;
    207 
    208 	while(item != NULL)
    209 		{
    210 		printf("item\t" PQ_64BIT_PRINT "\n", item->priority);
    211 		item = item->next;
    212 		}
    213 	}
    214 #endif
    215 
    216 pitem *
    217 pqueue_iterator(pqueue_s *pq)
    218 	{
    219 	return pqueue_peek(pq);
    220 	}
    221 
    222 pitem *
    223 pqueue_next(pitem **item)
    224 	{
    225 	pitem *ret;
    226 
    227 	if ( item == NULL || *item == NULL)
    228 		return NULL;
    229 
    230 
    231 	/* *item != NULL */
    232 	ret = *item;
    233 	*item = (*item)->next;
    234 
    235 	return ret;
    236 	}
    237 
    238 int
    239 pqueue_size(pqueue_s *pq)
    240 {
    241 	pitem *item = pq->items;
    242 	int count = 0;
    243 
    244 	while(item != NULL)
    245 	{
    246 		count++;
    247 		item = item->next;
    248 	}
    249 	return count;
    250 }
    251