1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /* Written by Eric Bollengier June 2020 */
20 
21 #ifndef BITMAP_H
22 #define BITMAP_H
23 
24 /* Small class to check bitmap and determine when they are set or not */
25 void       set_assert_msg        (const char *file, int line, const char *msg);
26 
27 class bitmap: public SMARTALLOC
28 {
29    int      len;
30    uint32_t max;
31    char *array;
32    char *isset;
33 
init(uint32_t nb_bits)34    void init(uint32_t nb_bits)
35    {
36       max = MAX(1, nb_bits);
37       len = nbytes_for_bits(max);
38       Dmsg2(0, "max=%d len=%d\n", max, len);
39       if (array) {
40          free(array);
41       }
42       if (isset) {
43          free(isset);
44       }
45       array = (char *)malloc(len);
46       isset = (char *)malloc(len);
47       bmemset(array, 0, len);
48       bmemset(isset, 0, len);
49    };
50 
51 public:
bitmap(uint32_t nb_bits)52    bitmap(uint32_t nb_bits): len(0), max(0), array(NULL), isset(NULL) {
53       init(nb_bits);
54    };
~bitmap()55    ~bitmap() {
56       free(array);
57       free(isset);
58    };
copy(bitmap * from)59    void copy(bitmap *from) {
60       init(from->max);
61       memcpy(isset, from->isset, len);
62       memcpy(array, from->array, len);
63    };
resize(uint32_t nb_bits)64    void resize(uint32_t nb_bits) {
65       if (nb_bits <= max) {
66          max = nb_bits;
67 
68       } else {
69          max = nb_bits;
70          int tlen = nbytes_for_bits(max);
71          char *tarray = (char *) malloc(len);
72          char *tisset = (char *) malloc(len);
73          bmemset(tarray, 0, tlen);
74          bmemset(tisset, 0, tlen);
75          memcpy(tarray, array, len);
76          memcpy(tisset, isset, len);
77          free(array);
78          free(tisset);
79          array = tarray;
80          isset = isset;
81          len = tlen;
82       }
83    };
84 
dump()85    void dump() {
86       POOL_MEM tmp;
87       for (uint32_t i = 0 ; i < max ; i++) {
88          switch(is_set(i)) {
89          case -1:
90             pm_strcat(tmp, ".");
91             break;
92          case 0:
93             pm_strcat(tmp, "0");
94             break;
95          case 1:
96             pm_strcat(tmp, "1");
97             break;
98          }
99       }
100       Dmsg2(0, "bitmap %p: [%s]\n", this, tmp.c_str());
101    };
102 
get_max_bit()103    int32_t get_max_bit() {
104       return max - 1;
105    };
106 
107    /* -1: not set
108     *  0: cleared
109     *  1: set
110     */
is_set(uint32_t b)111    int is_set(uint32_t b) {
112       if (b >= max) {
113          ASSERTD(b >= max, "Should not query so much bit in bitmap");
114          return -1;
115       }
116       if (bit_is_set(b, isset)) {
117          return bit_is_set(b, array);
118 
119       } else {
120          return -1;
121       }
122    };
123 
bit_set(uint32_t b)124    bool bit_set(uint32_t b) {
125       if (b >= max) {
126          ASSERTD(b >= max, "Should not set so much bit in bitmap");
127          return false;
128       }
129       set_bit(b, isset);
130       set_bit(b, array);
131       return true;
132    };
133 
bit_clear(uint32_t b)134    bool bit_clear(uint32_t b) {
135       if (b >= max) {
136          ASSERTD(b >= max, "Should not clear so much bit in bitmap");
137          return false;
138       }
139       clear_bit(b, array);
140       set_bit(b, isset);
141       return true;
142    };
143 
bit_reset(uint32_t b)144    bool bit_reset(uint32_t b) {
145       if (b >= max) {
146          ASSERTD(b >= max, "Should not reset so much bit in bitmap");
147          return false;
148       }
149       clear_bit(b, isset);
150       clear_bit(b, array);
151       return true;
152    };
153 };
154 
155 #endif  /* BITMAP_H */
156