File: smallarrayu64.c

package info (click to toggle)
cyrus-imapd 3.12.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 60,544 kB
  • sloc: ansic: 280,382; perl: 146,834; javascript: 9,624; sh: 5,730; yacc: 2,660; cpp: 2,263; makefile: 2,103; lex: 675; xml: 621; awk: 303; python: 273; asm: 262
file content (69 lines) | stat: -rw-r--r-- 1,648 bytes parent folder | download | duplicates (8)
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);
    }
}