pqueue.c revision 1.1.1.1 1 1.1 christos /*
2 1.1 christos * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved.
3 1.1 christos *
4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use
5 1.1 christos * this file except in compliance with the License. You can obtain a copy
6 1.1 christos * in the file LICENSE in the source distribution or at
7 1.1 christos * https://www.openssl.org/source/license.html
8 1.1 christos */
9 1.1 christos
10 1.1 christos #include "ssl_local.h"
11 1.1 christos #include <openssl/bn.h>
12 1.1 christos
13 1.1 christos struct pqueue_st {
14 1.1 christos pitem *items;
15 1.1 christos int count;
16 1.1 christos };
17 1.1 christos
18 1.1 christos pitem *pitem_new(unsigned char *prio64be, void *data)
19 1.1 christos {
20 1.1 christos pitem *item = OPENSSL_malloc(sizeof(*item));
21 1.1 christos
22 1.1 christos if (item == NULL)
23 1.1 christos return NULL;
24 1.1 christos
25 1.1 christos memcpy(item->priority, prio64be, sizeof(item->priority));
26 1.1 christos item->data = data;
27 1.1 christos item->next = NULL;
28 1.1 christos return item;
29 1.1 christos }
30 1.1 christos
31 1.1 christos void pitem_free(pitem *item)
32 1.1 christos {
33 1.1 christos OPENSSL_free(item);
34 1.1 christos }
35 1.1 christos
36 1.1 christos pqueue *pqueue_new(void)
37 1.1 christos {
38 1.1 christos pqueue *pq = OPENSSL_zalloc(sizeof(*pq));
39 1.1 christos
40 1.1 christos return pq;
41 1.1 christos }
42 1.1 christos
43 1.1 christos void pqueue_free(pqueue *pq)
44 1.1 christos {
45 1.1 christos OPENSSL_free(pq);
46 1.1 christos }
47 1.1 christos
48 1.1 christos pitem *pqueue_insert(pqueue *pq, pitem *item)
49 1.1 christos {
50 1.1 christos pitem *curr, *next;
51 1.1 christos
52 1.1 christos if (pq->items == NULL) {
53 1.1 christos pq->items = item;
54 1.1 christos return item;
55 1.1 christos }
56 1.1 christos
57 1.1 christos for (curr = NULL, next = pq->items;
58 1.1 christos next != NULL; curr = next, next = next->next) {
59 1.1 christos /*
60 1.1 christos * we can compare 64-bit value in big-endian encoding with memcmp:-)
61 1.1 christos */
62 1.1 christos int cmp = memcmp(next->priority, item->priority, 8);
63 1.1 christos if (cmp > 0) { /* next > item */
64 1.1 christos item->next = next;
65 1.1 christos
66 1.1 christos if (curr == NULL)
67 1.1 christos pq->items = item;
68 1.1 christos else
69 1.1 christos curr->next = item;
70 1.1 christos
71 1.1 christos return item;
72 1.1 christos }
73 1.1 christos
74 1.1 christos else if (cmp == 0) /* duplicates not allowed */
75 1.1 christos return NULL;
76 1.1 christos }
77 1.1 christos
78 1.1 christos item->next = NULL;
79 1.1 christos curr->next = item;
80 1.1 christos
81 1.1 christos return item;
82 1.1 christos }
83 1.1 christos
84 1.1 christos pitem *pqueue_peek(pqueue *pq)
85 1.1 christos {
86 1.1 christos return pq->items;
87 1.1 christos }
88 1.1 christos
89 1.1 christos pitem *pqueue_pop(pqueue *pq)
90 1.1 christos {
91 1.1 christos pitem *item = pq->items;
92 1.1 christos
93 1.1 christos if (pq->items != NULL)
94 1.1 christos pq->items = pq->items->next;
95 1.1 christos
96 1.1 christos return item;
97 1.1 christos }
98 1.1 christos
99 1.1 christos pitem *pqueue_find(pqueue *pq, unsigned char *prio64be)
100 1.1 christos {
101 1.1 christos pitem *next;
102 1.1 christos pitem *found = NULL;
103 1.1 christos
104 1.1 christos if (pq->items == NULL)
105 1.1 christos return NULL;
106 1.1 christos
107 1.1 christos for (next = pq->items; next->next != NULL; next = next->next) {
108 1.1 christos if (memcmp(next->priority, prio64be, 8) == 0) {
109 1.1 christos found = next;
110 1.1 christos break;
111 1.1 christos }
112 1.1 christos }
113 1.1 christos
114 1.1 christos /* check the one last node */
115 1.1 christos if (memcmp(next->priority, prio64be, 8) == 0)
116 1.1 christos found = next;
117 1.1 christos
118 1.1 christos if (!found)
119 1.1 christos return NULL;
120 1.1 christos
121 1.1 christos return found;
122 1.1 christos }
123 1.1 christos
124 1.1 christos pitem *pqueue_iterator(pqueue *pq)
125 1.1 christos {
126 1.1 christos return pqueue_peek(pq);
127 1.1 christos }
128 1.1 christos
129 1.1 christos pitem *pqueue_next(piterator *item)
130 1.1 christos {
131 1.1 christos pitem *ret;
132 1.1 christos
133 1.1 christos if (item == NULL || *item == NULL)
134 1.1 christos return NULL;
135 1.1 christos
136 1.1 christos /* *item != NULL */
137 1.1 christos ret = *item;
138 1.1 christos *item = (*item)->next;
139 1.1 christos
140 1.1 christos return ret;
141 1.1 christos }
142 1.1 christos
143 1.1 christos size_t pqueue_size(pqueue *pq)
144 1.1 christos {
145 1.1 christos pitem *item = pq->items;
146 1.1 christos size_t count = 0;
147 1.1 christos
148 1.1 christos while (item != NULL) {
149 1.1 christos count++;
150 1.1 christos item = item->next;
151 1.1 christos }
152 1.1 christos return count;
153 1.1 christos }
154