summaryrefslogtreecommitdiffstats
path: root/src/libnetdata/bitmap.h
blob: 184f94cb6cf5742489fcef77cce75dc80b8b1352 (plain)
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
70
71
72
73
74
75
76
77
78
79
80
81
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef NETDATA_BITMAP_H
#define NETDATA_BITMAP_H

#ifdef ENV32BIT

typedef struct bitmapX {
    uint32_t bits;
    uint32_t data[];
} BITMAPX;

typedef struct bitmap256 {
    uint32_t bits;
    uint32_t data[256 / 32];
} BITMAP256;

typedef struct bitmap1024 {
    uint32_t bits;
    uint32_t data[1024 / 32];
} BITMAP1024;

static inline BITMAPX *bitmapX_create(uint32_t bits) {
    BITMAPX *bmp = (BITMAPX *)callocz(1, sizeof(BITMAPX) + sizeof(uint32_t) * ((bits + 31) / 32));
    uint32_t *p = (uint32_t *)&bmp->bits;
    *p = bits;
    return bmp;
}

#define bitmapX_get_bit(ptr, idx) ((ptr)->data[(idx) >> 5] & (1U << ((idx) & 31)))
#define bitmapX_set_bit(ptr, idx, value) do {           \
    register uint32_t _bitmask = 1U << ((idx) & 31);    \
    if (value)                                          \
        (ptr)->data[(idx) >> 5] |= _bitmask;            \
    else                                                \
        (ptr)->data[(idx) >> 5] &= ~_bitmask;           \
} while(0)

#else // 64bit version of bitmaps

typedef struct bitmapX {
    uint32_t bits;
    uint64_t data[];
} BITMAPX;

typedef struct bitmap256 {
    uint32_t bits;
    uint64_t data[256 / 64];
} BITMAP256;

typedef struct bitmap1024 {
    uint32_t bits;
    uint64_t data[1024 / 64];
} BITMAP1024;

static inline BITMAPX *bitmapX_create(uint32_t bits) {
    BITMAPX *bmp = (BITMAPX *)callocz(1, sizeof(BITMAPX) + sizeof(uint64_t) * ((bits + 63) / 64));
    bmp->bits = bits;
    return bmp;
}

#define bitmapX_get_bit(ptr, idx) ((ptr)->data[(idx) >> 6] & (1ULL << ((idx) & 63)))
#define bitmapX_set_bit(ptr, idx, value) do {           \
    register uint64_t _bitmask = 1ULL << ((idx) & 63);  \
    if (value)                                          \
        (ptr)->data[(idx) >> 6] |= _bitmask;            \
    else                                                \
        (ptr)->data[(idx) >> 6] &= ~_bitmask;           \
} while(0)

#endif // 64bit version of bitmaps

#define BITMAPX_INITIALIZER(wanted_bits) { .bits = (wanted_bits), .data = {0} }
#define BITMAP256_INITIALIZER (BITMAP256)BITMAPX_INITIALIZER(256)
#define BITMAP1024_INITIALIZER (BITMAP1024)BITMAPX_INITIALIZER(1024)
#define bitmap256_get_bit(ptr, idx) bitmapX_get_bit((BITMAPX *)ptr, idx)
#define bitmap256_set_bit(ptr, idx, value) bitmapX_set_bit((BITMAPX *)ptr, idx, value)
#define bitmap1024_get_bit(ptr, idx) bitmapX_get_bit((BITMAPX *)ptr, idx)
#define bitmap1024_set_bit(ptr, idx, value) bitmapX_set_bit((BITMAPX *)ptr, idx, value)

#endif //NETDATA_BITMAP_H