Initialize
Continous integration / Tests (push) Canceled after 0s
Testing clients / Build beanstalkd (push) Canceled after 0s
Continous integration / Docker build (push) Canceled after 0s
Testing clients / Test Pheanstalk PHP (push) Canceled after 0s
Testing clients / Test Greenstalk Python (3.9) (push) Canceled after 0s
Testing clients / Test Pystalk Python (3.10) (push) Canceled after 0s
Continous integration / Tests (push) Canceled after 0s
Testing clients / Build beanstalkd (push) Canceled after 0s
Continous integration / Docker build (push) Canceled after 0s
Testing clients / Test Pheanstalk PHP (push) Canceled after 0s
Testing clients / Test Greenstalk Python (3.9) (push) Canceled after 0s
Testing clients / Test Pystalk Python (3.10) (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
#include "dat.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
ms_init(Ms *a, ms_event_fn oninsert, ms_event_fn onremove)
|
||||
{
|
||||
a->len = a->cap = a->last = 0;
|
||||
a->items = NULL;
|
||||
a->oninsert = oninsert;
|
||||
a->onremove = onremove;
|
||||
}
|
||||
|
||||
static int
|
||||
grow(Ms *a)
|
||||
{
|
||||
void **nitems;
|
||||
size_t ncap = a->cap << 1;
|
||||
if (!ncap)
|
||||
ncap = 1;
|
||||
|
||||
nitems = malloc(ncap * sizeof(void *));
|
||||
if (!nitems)
|
||||
return 0;
|
||||
|
||||
memcpy(nitems, a->items, a->len * sizeof(void *));
|
||||
free(a->items);
|
||||
a->items = nitems;
|
||||
a->cap = ncap;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ms_append(Ms *a, void *item)
|
||||
{
|
||||
if (a->len >= a->cap && !grow(a))
|
||||
return 0;
|
||||
|
||||
a->items[a->len++] = item;
|
||||
if (a->oninsert)
|
||||
a->oninsert(a, item, a->len - 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ms_delete(Ms *a, size_t i)
|
||||
{
|
||||
void *item;
|
||||
|
||||
if (i >= a->len)
|
||||
return 0;
|
||||
item = a->items[i];
|
||||
a->items[i] = a->items[--a->len];
|
||||
|
||||
/* it has already been removed now */
|
||||
if (a->onremove)
|
||||
a->onremove(a, item, i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ms_clear(Ms *a)
|
||||
{
|
||||
while (ms_delete(a, 0));
|
||||
free(a->items);
|
||||
ms_init(a, a->oninsert, a->onremove);
|
||||
}
|
||||
|
||||
int
|
||||
ms_remove(Ms *a, void *item)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < a->len; i++) {
|
||||
if (a->items[i] == item)
|
||||
return ms_delete(a, i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ms_contains(Ms *a, void *item)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < a->len; i++) {
|
||||
if (a->items[i] == item)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
ms_take(Ms *a)
|
||||
{
|
||||
void *item;
|
||||
|
||||
if (!a->len)
|
||||
return NULL;
|
||||
|
||||
// The result of last behaviour is that ms_take returns the oldest elements
|
||||
// first, exception is a row of multiple take calls without inserts on ms
|
||||
// of even number of elements. See the test.
|
||||
a->last = a->last % a->len;
|
||||
item = a->items[a->last];
|
||||
ms_delete(a, a->last);
|
||||
++a->last;
|
||||
return item;
|
||||
}
|
||||
Reference in New Issue
Block a user