mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
dynarray: Reimplement with nicer semantics
A dynamic array is a nice simple container, but the old interface wasn't quite what I wanted it to be. I like GLib's way of providing the free callback at the container creation time, because that way the free callback doesn't have to be given every time something is removed from the array. The allocation pattern was changed too: instead of increasing the array size always by 25 when the array gets full, the size gets doubled now (the lowest non-zero size is still 25). The array can't store NULL pointers anymore, and pa_dynarray_get() was changed so that it's forbidden to try to access elements outside the valid range. The set of supported operations may seem a bit arbitrary. The operation set is by no means complete at this point. I have included only those operations that are required by the current code and some unpublished code of mine.
This commit is contained in:
parent
d00d5b6611
commit
0f2840f4c6
4 changed files with 65 additions and 71 deletions
|
|
@ -31,82 +31,65 @@
|
|||
|
||||
#include "dynarray.h"
|
||||
|
||||
/* If the array becomes to small, increase its size by 25 entries */
|
||||
#define INCREASE_BY 25
|
||||
|
||||
struct pa_dynarray {
|
||||
void **data;
|
||||
unsigned n_allocated, n_entries;
|
||||
pa_free_cb_t free_cb;
|
||||
};
|
||||
|
||||
pa_dynarray* pa_dynarray_new(void) {
|
||||
pa_dynarray *a;
|
||||
pa_dynarray* pa_dynarray_new(pa_free_cb_t free_cb) {
|
||||
pa_dynarray *array;
|
||||
|
||||
a = pa_xnew(pa_dynarray, 1);
|
||||
a->data = NULL;
|
||||
a->n_entries = 0;
|
||||
a->n_allocated = 0;
|
||||
array = pa_xnew0(pa_dynarray, 1);
|
||||
array->free_cb = free_cb;
|
||||
|
||||
return a;
|
||||
return array;
|
||||
}
|
||||
|
||||
void pa_dynarray_free(pa_dynarray *a, pa_free_cb_t free_func) {
|
||||
void pa_dynarray_free(pa_dynarray *array) {
|
||||
unsigned i;
|
||||
pa_assert(a);
|
||||
pa_assert(array);
|
||||
|
||||
if (free_func)
|
||||
for (i = 0; i < a->n_entries; i++)
|
||||
if (a->data[i])
|
||||
free_func(a->data[i]);
|
||||
if (array->free_cb)
|
||||
for (i = 0; i < array->n_entries; i++)
|
||||
array->free_cb(array->data[i]);
|
||||
|
||||
pa_xfree(a->data);
|
||||
pa_xfree(a);
|
||||
pa_xfree(array->data);
|
||||
pa_xfree(array);
|
||||
}
|
||||
|
||||
void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p) {
|
||||
pa_assert(a);
|
||||
void pa_dynarray_append(pa_dynarray *array, void *p) {
|
||||
pa_assert(array);
|
||||
pa_assert(p);
|
||||
|
||||
if (i >= a->n_allocated) {
|
||||
unsigned n;
|
||||
if (array->n_entries == array->n_allocated) {
|
||||
unsigned n = PA_MAX(array->n_allocated * 2, 25U);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
n = i+INCREASE_BY;
|
||||
a->data = pa_xrealloc(a->data, sizeof(void*)*n);
|
||||
memset(a->data+a->n_allocated, 0, sizeof(void*)*(n-a->n_allocated));
|
||||
a->n_allocated = n;
|
||||
array->data = pa_xrealloc(array->data, sizeof(void *) * n);
|
||||
array->n_allocated = n;
|
||||
}
|
||||
|
||||
a->data[i] = p;
|
||||
|
||||
if (i >= a->n_entries)
|
||||
a->n_entries = i+1;
|
||||
array->data[array->n_entries++] = p;
|
||||
}
|
||||
|
||||
unsigned pa_dynarray_append(pa_dynarray*a, void *p) {
|
||||
unsigned i;
|
||||
void *pa_dynarray_get(pa_dynarray *array, unsigned i) {
|
||||
pa_assert(array);
|
||||
pa_assert(i < array->n_entries);
|
||||
|
||||
pa_assert(a);
|
||||
|
||||
i = a->n_entries;
|
||||
pa_dynarray_put(a, i, p);
|
||||
|
||||
return i;
|
||||
return array->data[i];
|
||||
}
|
||||
|
||||
void *pa_dynarray_get(pa_dynarray*a, unsigned i) {
|
||||
pa_assert(a);
|
||||
void *pa_dynarray_steal_last(pa_dynarray *array) {
|
||||
pa_assert(array);
|
||||
|
||||
if (i >= a->n_entries)
|
||||
if (array->n_entries > 0)
|
||||
return array->data[--array->n_entries];
|
||||
else
|
||||
return NULL;
|
||||
|
||||
pa_assert(a->data);
|
||||
return a->data[i];
|
||||
}
|
||||
|
||||
unsigned pa_dynarray_size(pa_dynarray*a) {
|
||||
pa_assert(a);
|
||||
unsigned pa_dynarray_size(pa_dynarray *array) {
|
||||
pa_assert(array);
|
||||
|
||||
return a->n_entries;
|
||||
return array->n_entries;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue