This changeset fixes a huge pile of problems, as indicated in the error log of the Doxygen run after merging all the recent Doxygen improvements unfortunately, auto-linking does still not work at various places. There is no clear indication what might be the problem. Possibly the rather unstable Sqlite support in this Doxygen version is the cause. Anyway, needs to be investigated further.
160 lines
4.7 KiB
C
160 lines
4.7 KiB
C
/*
|
|
PRIQUEUE.h - simple heap based priority queue
|
|
|
|
Copyright (C) Lumiera.org
|
|
2011, Christian Thaeter <ct@pipapo.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
/** @file priqueue.h
|
|
** Simple priority queue implementation based on a binary heap.
|
|
** Only 'insert' 'remove' and 'peek' operations are supported.
|
|
** Memory is dynamically managed through an optionally user supplied 'resize' function.
|
|
** Elements in the queue have a user-define size but should kept as small as possible.
|
|
** This is only intended to associate lightweight data such as a key and a pointer,
|
|
** storing the key in the element can save dereferencing cost and thus improve
|
|
** cache locality.
|
|
**
|
|
** @warning elements in the queue get moved in memory, so referencing them is not allowed.
|
|
**
|
|
** @todo we might add operations to change the priority of an arbitrary element or remove
|
|
** any but the topmost element. The idea is to let expired elements sink to the top
|
|
** and just detect and remove them on next access.
|
|
**
|
|
** @see backend::engine::SchedulerFrontend
|
|
**
|
|
*/
|
|
|
|
|
|
#ifndef LIB_PRIQUEUE_H
|
|
#define LIB_PRIQUEUE_H
|
|
|
|
|
|
#include "lib/error.h"
|
|
|
|
|
|
typedef struct lumiera_priqueue_struct lumiera_priqueue;
|
|
typedef lumiera_priqueue* LumieraPriQueue;
|
|
|
|
/** function to compare 2 keys, mandatory */
|
|
typedef int (*lumiera_priqueue_cmp_fn)(void*, void*);
|
|
|
|
/** function to copy elements, optional.
|
|
* Has the same prototype as memcpy which is used by default */
|
|
typedef void *(*lumiera_priqueue_copy_fn)(void *dest, const void *src, size_t n);
|
|
|
|
/** called when used hits the high or low water marks and initially by priqueue_init() (with queue==NULL)
|
|
* or at priqueue_destroy (with queue != NULL, used elements == 0), optional.
|
|
*
|
|
* @note must be aware of resizes by more than just incrementing the queue by one
|
|
*/
|
|
typedef LumieraPriQueue (*lumiera_priqueue_resize_fn) (LumieraPriQueue);
|
|
|
|
|
|
/**
|
|
* @remarks this structure is not opaque to make it possible
|
|
* to implement a low level resize operation
|
|
* which has to reallocate the queue and update
|
|
* the high and low water marks.
|
|
*/
|
|
struct lumiera_priqueue_struct
|
|
{
|
|
void* queue;
|
|
size_t element_size;
|
|
unsigned used;
|
|
unsigned high_water; ///< elements in the queue
|
|
unsigned low_water; ///< size for shrinking the queue
|
|
|
|
lumiera_priqueue_cmp_fn cmpfn;
|
|
lumiera_priqueue_copy_fn copyfn;
|
|
|
|
lumiera_priqueue_resize_fn resizefn;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LumieraPriQueue
|
|
lumiera_priqueue_init (LumieraPriQueue self,
|
|
size_t element_size,
|
|
lumiera_priqueue_cmp_fn cmpfn,
|
|
lumiera_priqueue_copy_fn copyfn,
|
|
lumiera_priqueue_resize_fn resizefn);
|
|
|
|
|
|
|
|
LumieraPriQueue
|
|
lumiera_priqueue_destroy (LumieraPriQueue self);
|
|
|
|
|
|
/**
|
|
* calls resize to match for at least 'elements' in the queue
|
|
* and then sets low_water to 0, disabling shrinking
|
|
* @note on overflow resize will re-enable low_water if it is not aware of this
|
|
*/
|
|
LumieraPriQueue
|
|
lumiera_priqueue_reserve (LumieraPriQueue self, unsigned elements);
|
|
|
|
|
|
/**
|
|
* supplied/default resize function based on realloc
|
|
* initially allocates an array for 64 elements,
|
|
* doubles this when the high water mark is hit,
|
|
* shrinks at high_water/8-8 (that is, 64 is the minimum size)
|
|
*/
|
|
LumieraPriQueue
|
|
lumiera_priqueue_clib_resize (LumieraPriQueue self);
|
|
|
|
|
|
|
|
|
|
/**
|
|
* insert a new element into the priority queue
|
|
* the element will be copied
|
|
* @return \c NULL on error
|
|
*/
|
|
LumieraPriQueue
|
|
lumiera_priqueue_insert (LumieraPriQueue self, void* element);
|
|
|
|
|
|
/**
|
|
* @return pointer to the topmost element, `NULL` on empty queue
|
|
* @note returned pointer is only valid as long
|
|
* as no insert or remove is called
|
|
*/
|
|
static inline void*
|
|
lumiera_priqueue_peek (LumieraPriQueue self)
|
|
{
|
|
if (self && self->queue)
|
|
return self->queue;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/**
|
|
* removes the topmost element
|
|
* @return \c NULL on error (empty queue, resize failure)
|
|
*/
|
|
LumieraPriQueue
|
|
lumiera_priqueue_remove (LumieraPriQueue self);
|
|
|
|
|
|
|
|
#endif/*LIB_PRIQUEUE_H*/
|