skalibs: the genqdyn library interface
Keywords: skalibs c unix genqdyn library queue libdatastruct

libdatastruct
libskarnet
skalibs
Software
skarnet.org

# The `genqdyn` library interface

The following functions are declared in the `skalibs/genqdyn.h` header, and implemented in the `libskarnet.a` or `libskarnet.so` library.

## General information

`genqdyn` is a set of functions implementing simple queues on generic objects. The dyn prefix means the queues are dynamically allocated (and live in heap memory): it is possible to enqueue an arbitrary number of objects, up to the available memory.

## Data structures

A `genqdyn` structure holds the information necessary to implement a queue. It can be declared anywhere (including in the stack). All genqdyn functions take a pointer to this structure as an argument.

## Macros

`genqdyn GENQDYN_INIT(type, num, den)`
Returns an anonymous genqdyn structure suitable for holding objects of type type. The num and den arguments are integers, used to tune the amount of memory needed / management overhead balance. num/den must be a fractional value between 0 and 1. The closer to 0, the longer genqdyn will wait before performing a cleanup (and the more memory it can consume). At 0, genqdyn can only recycle memory when the queue becomes totally empty. The closer to 1, the more genqdyn optimizes its memory usage (and the more often it performs maintenance on its queue). At 1, it performs maintenance every time an object is popped. Anything between 1/4 and 3/4 is a reasonable value for num/den.

`size_t genqdyn_n (genqdyn *g)`
Returns the number of elements in the genqdyn *g, which must have been initialized.

`void *genqdyn_peek (genqdyn *g)`
Peeks at the next object in the queue, i.e. the object that has been pushed the earliest and that hasn't been popped yet. You can use the `GENQDYN_PEEK(type, g)` macro to get a `type *` pointer instead of a `void *` one.

## Functions

`void genqdyn_init (genqdyn *g, size_t esize, unsigned int num, unsigned int den)`
Initializes the genqdyn *g to hold objects of size esize. g must be unused, or have been freed. The num and den arguments tune g's behaviour as described above in the GENQDYN_INIT description. This function is similar to the GENQDYN_INIT macro, except that it can be used dynamically and works on a pre-declared genqdyn, whereas the macro can only be used as a static initializer.

`void genqdyn_free (genqdyn *g)`
Frees the resources used by *g, which is then considered uninitialized.

`int genqdyn_push (genqdyn *g, void const *p)`
Pushes the object pointed to by p onto the queue. This object must have the same size that has been given to the `genqdyn_init()` invocation, or be of the same type that has been given to the `GENQDYN_INIT()` invocation. The function returns 1 if it succeeds and 0 (and sets errno) if it fails.

`int genqdyn_unpush (genqdyn *g)`
Undoes the last push. Returns 1, except if the queue is empty, in which case it returns 0 and sets errno to EINVAL.

`int genqdyn_pop (genqdyn *g)`
Pops an object from the queue, and possibly performs maintenance to reuse some memory. Returns 1, unless the queue is empty, in which case it returns 0 and sets errno to EINVAL.