jabberd2  2.2.16
util/jqueue.c
Go to the documentation of this file.
00001 /*
00002  * jabberd - Jabber Open Source Server
00003  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
00004  *                    Ryan Eatmon, Robert Norris
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
00019  */
00020 
00021 /* priority jqueues */
00022 
00023 #include "util.h"
00024 
00025 jqueue_t jqueue_new(void) {
00026     pool_t p;
00027     jqueue_t q;
00028 
00029     p = pool_new();
00030     q = (jqueue_t) pmalloco(p, sizeof(struct _jqueue_st));
00031 
00032     q->p = p;
00033     q->init_time = time(NULL);
00034 
00035     return q;
00036 }
00037 
00038 void jqueue_free(jqueue_t q) {
00039     assert((int) (q != NULL));
00040 
00041     pool_free(q->p);
00042 }
00043 
00044 void jqueue_push(jqueue_t q, void *data, int priority) {
00045     _jqueue_node_t qn, scan;
00046 
00047     assert((int) (q != NULL));
00048 
00049     q->size++;
00050 
00051     /* node from the cache, or make a new one */
00052     qn = q->cache;
00053     if(qn != NULL)
00054         q->cache = qn->next;
00055     else
00056         qn = (_jqueue_node_t) pmalloc(q->p, sizeof(struct _jqueue_node_st));
00057 
00058     qn->data = data;
00059     qn->priority = priority;
00060 
00061     qn->next = NULL;
00062     qn->prev = NULL;
00063 
00064     /* first one */
00065     if(q->back == NULL && q->front == NULL) {
00066         q->back = qn;
00067         q->front = qn;
00068 
00069         return;
00070     }
00071 
00072     /* find the first node with priority <= to us */
00073     for(scan = q->back; scan != NULL && scan->priority > priority; scan = scan->next);
00074 
00075     /* didn't find one, so we have top priority - push us on the front */
00076     if(scan == NULL) {
00077         qn->prev = q->front;
00078         qn->prev->next = qn;
00079         q->front = qn;
00080 
00081         return;
00082     }
00083 
00084     /* push us in front of scan */
00085     qn->next = scan;
00086     qn->prev = scan->prev;
00087 
00088     if(scan->prev != NULL)
00089         scan->prev->next = qn;
00090     else
00091         q->back = qn;
00092 
00093     scan->prev = qn;
00094 }
00095 
00096 void *jqueue_pull(jqueue_t q) {
00097     void *data;
00098     _jqueue_node_t qn;
00099 
00100     assert((int) (q != NULL));
00101 
00102     if(q->front == NULL)
00103         return NULL;
00104 
00105     data = q->front->data;
00106 
00107     qn = q->front;
00108 
00109     if(qn->prev != NULL)
00110         qn->prev->next = NULL;
00111     
00112     q->front = qn->prev;
00113 
00114     /* node to cache for later reuse */
00115     qn->next = q->cache;
00116     q->cache = qn;
00117 
00118     if(q->front == NULL)
00119         q->back = NULL;
00120 
00121     q->size--;
00122 
00123     return data;
00124 }
00125 
00126 int jqueue_size(jqueue_t q) {
00127     return q->size;
00128 }
00129 
00130 time_t jqueue_age(jqueue_t q) {
00131     return time(NULL) - q->init_time;
00132 }