jabberd2  2.7.0
pqueue.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 /* priority queues */
22 
23 #include "pqueue.h"
24 
25 #include "pool.h"
26 
27 #include <stdio.h> /* to get NULL */
28 #include <assert.h>
29 
32  void *data;
33 
34  int priority;
35 
38 };
39 
40 struct _pqueue_st {
43 
46 
47  int size;
48 };
49 
51  pqueue_t q;
52 
53  q = (pqueue_t) pmalloco(p, sizeof(struct _pqueue_st));
54 
55  q->p = p;
56 
57  return q;
58 }
59 
60 void pqueue_push(pqueue_t q, void *data, int priority) {
61  _pqueue_node_t qn, scan;
62 
63  assert((q != NULL));
64 
65  q->size++;
66 
67  /* node from the cache, or make a new one */
68  qn = q->cache;
69  if(qn != NULL)
70  q->cache = qn->next;
71  else
72  qn = (_pqueue_node_t) pmalloc(q->p, sizeof(struct _pqueue_node_st));
73 
74  qn->data = data;
75  qn->priority = priority;
76 
77  qn->next = NULL;
78  qn->prev = NULL;
79 
80  /* first one */
81  if(q->back == NULL && q->front == NULL) {
82  q->back = qn;
83  q->front = qn;
84 
85  return;
86  }
87 
88  /* find the first node with priority <= to us */
89  for(scan = q->back; scan != NULL && scan->priority > priority; scan = scan->next);
90 
91  /* didn't find one, so we have top priority - push us on the front */
92  if(scan == NULL) {
93  qn->prev = q->front;
94  qn->prev->next = qn;
95  q->front = qn;
96 
97  return;
98  }
99 
100  /* push us in front of scan */
101  qn->next = scan;
102  qn->prev = scan->prev;
103 
104  if(scan->prev != NULL)
105  scan->prev->next = qn;
106  else
107  q->back = qn;
108 
109  scan->prev = qn;
110 }
111 
113  void *data;
114  _pqueue_node_t qn;
115 
116  assert((q != NULL));
117 
118  if(q->front == NULL)
119  return NULL;
120 
121  data = q->front->data;
122 
123  qn = q->front;
124 
125  if(qn->prev != NULL)
126  qn->prev->next = NULL;
127 
128  q->front = qn->prev;
129 
130  /* node to cache for later reuse */
131  qn->next = q->cache;
132  q->cache = qn;
133 
134  if(q->front == NULL)
135  q->back = NULL;
136 
137  q->size--;
138 
139  return data;
140 }
141 
143  return q->size;
144 }
_pqueue_node_t front
Definition: pqueue.c:44
void * pmalloc(pool_t p, int size)
Definition: pool.c:141
_pqueue_node_t prev
Definition: pqueue.c:37
_pqueue_node_t cache
Definition: pqueue.c:42
int pqueue_size(pqueue_t q)
Definition: pqueue.c:142
void * pmalloco(pool_t p, int size)
easy safety utility (for creating blank mem for structs, etc)
Definition: pool.c:183
priority queues
void * pqueue_pull(pqueue_t q)
Definition: pqueue.c:112
int size
Definition: pqueue.c:47
pool_t p
Definition: pqueue.c:41
void pqueue_push(pqueue_t q, void *data, int priority)
Definition: pqueue.c:60
pqueue_t pqueue_new(pool_t p)
Definition: pqueue.c:50
_pqueue_node_t back
Definition: pqueue.c:45
pool - base node for a pool.
Definition: pool.h:80
struct _pqueue_st * pqueue_t
Definition: pqueue.h:34
struct _pqueue_node_st * _pqueue_node_t
Definition: pqueue.c:30
_pqueue_node_t next
Definition: pqueue.c:36
int priority
Definition: pqueue.c:34
void * data
Definition: pqueue.c:32