Ring buffers.

Overview

// typedefs

typedef struct te_ring te_ring;

// structs

struct te_ring;

// global functions

te_errno te_ring_put(te_ring* ring, const void* element);
te_errno te_ring_get(te_ring* ring, void* element);
const void* te_ring_peek(const te_ring* ring);
size_t te_ring_copy(const te_ring* ring, size_t count, te_vec* dest);
size_t te_ring_put_many(te_ring* ring, size_t count, const void* elements);
size_t te_ring_get_many(te_ring* ring, size_t count, te_vec* dest);
void te_ring_resize(te_ring* ring, size_t new_ring_size);
void te_ring_free(te_ring* ring);

// macros

#define TE_RING_INIT(type_, destroy_, ring_size_)
#define TE_RING_INIT_AUTOPTR(type_, ring_size_)

Detailed Documentation

Typedefs

typedef struct te_ring te_ring

Ring buffer structure.

All the fields may be inspected but must never be directly modified by the user.

Global Functions

te_errno te_ring_put(te_ring* ring, const void* element)

Put the content of element into the ring.

If the ring is already full, the oldest element is discarded. If the ring has non-null destructor, it is called for the discarded element.

Parameters:

ring

ring buffer

element

new data

TE_ENOBUFS

The ring buffer has overflowed. It is not an error, but the caller may take some appropriate action if needed.

Returns:

status code

te_errno te_ring_get(te_ring* ring, void* element)

Get the oldest element from the ring.

The element is removed from the ring and the read pointer is moved to the next element.

The data are put into element if it is not NULL; otherwise the data are discared (the element destructor is called if it’s non-null).

If there is no data in ring, element is not changed.

Parameters:

ring

ring buffer

element

destination buffer (may be NULL)

TE_ENODATA

The ring is empty.

Returns:

status code

const void* te_ring_peek(const te_ring* ring)

Get the oldest element from the ring keeping it.

The pointer inside the ring itself is returned, the caller must treat it as a pointer to local storage.

The read pointer is not moved.

Parameters:

ring

ring buffer

Returns:

the pointer to the data or NULL if the ring is empty

size_t te_ring_copy(const te_ring* ring, size_t count, te_vec* dest)

Copy at most count oldest elements from ring to dest.

The read pointer is not moved. The data are appended to dest.

dest must have a null destructor.

Parameters:

ring

ring buffer

count

maximum number of elements to copy

dest

destination vector

Returns:

the number of elements actually copied (may be 0)

size_t te_ring_put_many(te_ring* ring, size_t count, const void* elements)

Put count items from elements to ring.

The ring is never overran, if there is not enough space in ring, fewer elements are put.

Parameters:

ring

ring buffer

count

maximum number of elements to put

elements

new data

Returns:

the number of elements actually put (may be 0)

size_t te_ring_get_many(te_ring* ring, size_t count, te_vec* dest)

Get at most count oldest elements from ring and put them to dest.

The elements are removed from the ring and the read pointer is moved as needed.

The data are appended to dest, if dest is not NULL, otherwise the data are discarded (the element destructor is called if it’s not null).

Parameters:

ring

ring buffer

count

maximum number of elements to put

dest

destination vector (may be NULL)

Returns:

the number of elements actually got.

void te_ring_resize(te_ring* ring, size_t new_ring_size)

Change the size of ring to new_ring_size.

If new_ring_size is less than the current fill of the ring, oldest redundant items are discarded. In all other cases all the data are preserved, but the layout may change.

Parameters:

ring

ring buffer

new_ring_size

new size of the ring

void te_ring_free(te_ring* ring)

Free any resources associated with ring.

Parameters:

ring

ring buffer

Macros

#define TE_RING_INIT(type_, destroy_, ring_size_)

Initialize a ring to store objects of a given type_.

Parameters:

type_

type of elements

destroy_

element destructor

ring_size_

initial ring size