1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include <assert.h>
#include <config.h>
#include <string.h>
#include "smallarrayu64.h"
#include "xmalloc.h"
EXPORTED smallarrayu64_t *smallarrayu64_new(void)
{
return xzmalloc(sizeof(smallarrayu64_t));
}
EXPORTED void smallarrayu64_fini(smallarrayu64_t *sa)
{
if (!sa) return;
arrayu64_fini(&sa->spillover);
sa->count = 0;
sa->use_spillover = 0;
}
EXPORTED void smallarrayu64_free(smallarrayu64_t *sa)
{
if (!sa) return;
smallarrayu64_fini(sa);
free(sa);
}
EXPORTED int smallarrayu64_append(smallarrayu64_t *sa, uint64_t num)
{
if (sa->count < SMALLARRAYU64_ALLOC && !sa->use_spillover) {
if (num <= UINT8_MAX) {
sa->data[sa->count++] = num;
if (sa->count == SMALLARRAYU64_ALLOC) {
sa->use_spillover = 1;
}
return sa->count;
}
/* can't store num in preallocated data */
sa->use_spillover = 1;
}
return arrayu64_append(&sa->spillover, num);
}
EXPORTED size_t smallarrayu64_size(smallarrayu64_t *sa)
{
return sa->count + arrayu64_size(&sa->spillover);
}
static inline int adjust_index_ro(const smallarrayu64_t *sa, int idx)
{
size_t count = sa->count + arrayu64_size(&sa->spillover);
if (idx >= 0 && (unsigned) idx >= count)
return -1;
else if (idx < 0)
idx += count;
return idx;
}
EXPORTED uint64_t smallarrayu64_nth(smallarrayu64_t *sa, int idx)
{
if ((idx = adjust_index_ro(sa, idx)) < 0)
return 0;
if ((size_t)idx < sa->count) {
return sa->data[idx];
}
else {
return arrayu64_nth(&sa->spillover, idx - sa->count);
}
}
|