]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add simple bitmap class
authorEric Bollengier <eric@baculasystems.com>
Fri, 12 Jun 2020 14:24:01 +0000 (16:24 +0200)
committerEric Bollengier <eric@baculasystems.com>
Tue, 1 Mar 2022 14:36:15 +0000 (15:36 +0100)
bacula/src/lib/Makefile.in
bacula/src/lib/bitmap.c [new file with mode: 0644]
bacula/src/lib/bitmap.h [new file with mode: 0644]

index 670517b6380e4bfb6459e26525f0ea966c2b8e3f..c2dcfa9d05e6d61ca63dfcdb9a25848b43cbfc2a 100644 (file)
@@ -136,6 +136,12 @@ wait_test: Makefile bsys.c
        $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -L../findlib -o $@ bsys.o $(DLIB) -lbac -lbacfind -lm $(LIBS) $(OPENSSL_LIBS)
        $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $@ $(DESTDIR)$(sbindir)/
 
+bitmap_test: Makefile bitmap.c unittests.o bitmap.h
+       $(RMF) bsys.o
+       $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) bitmap.c
+       $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ bitmap.o unittests.o $(DLIB) -lbac -lm $(LIBS) $(OPENSSL_LIBS)
+       $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $@ $(DESTDIR)$(sbindir)/
+
 output_test: Makefile libbac.la output.c unittests.o
        $(RMF) output.o
        $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) output.c
diff --git a/bacula/src/lib/bitmap.c b/bacula/src/lib/bitmap.c
new file mode 100644 (file)
index 0000000..740941a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2022 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+/* Written by Eric Bollengier June 2020 */
+
+#include "bacula.h"
+#include "bitmap.h"
+
+#ifdef TEST_PROGRAM
+#include "unittests.h"
+
+int main(int argc, char **argv)
+{
+   Unittests("bitmap_test", true, true);
+   bitmap a(10);
+   a.dump();
+   for (int i = 0; i < 10 ; i++) {
+      is(a.is_set(i), -1, "Test all bits");
+   }
+   is(a.get_max_bit(), 9, "Test max_bit");
+   is(a.is_set(11), -1, "Test incorrect value");
+   is(a.is_set(200), -1, "Test incorrect value");
+   ok(a.bit_set(5), "Test set value");
+   ok(a.bit_set(8), "Test set value");
+   nok(a.bit_set(12), "Test set value");
+   is(a.is_set(12), -1, "Test is_set value");
+   is(a.bit_set(8), 1, "Test is_set value");
+   a.dump();
+   
+   a.resize(30);
+   is(a.get_max_bit(), 29, "Test max_bit");
+   is(a.is_set(8), 1, "Test is_set value");
+   is(a.is_set(5), 1, "Test is_set value");
+   is(a.bit_set(8), 1, "Test is_set value");
+   for (int i = 0; i < 30 ; i++) {
+      a.bit_clear(i);
+      is(a.is_set(i), 0, "Test all bits");
+   }
+   for (int i = 0; i < 30 ; i++) {
+      a.bit_reset(i);
+      is(a.is_set(i), -1, "Test all bits");
+   }
+   a.dump();
+
+   return report();
+}
+
+#endif
diff --git a/bacula/src/lib/bitmap.h b/bacula/src/lib/bitmap.h
new file mode 100644 (file)
index 0000000..f5be720
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2022 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+/* Written by Eric Bollengier June 2020 */
+
+#ifndef BITMAP_H
+#define BITMAP_H
+
+/* Small class to check bitmap and determine when they are set or not */
+void       set_assert_msg        (const char *file, int line, const char *msg);
+
+class bitmap: public SMARTALLOC
+{
+   int      len;
+   uint32_t max;
+   char *array;
+   char *isset;
+
+   void init(uint32_t nb_bits)
+   {
+      max = MAX(1, nb_bits);
+      len = nbytes_for_bits(max);
+      Dmsg2(0, "max=%d len=%d\n", max, len);
+      if (array) {
+         free(array);
+      }
+      if (isset) {
+         free(isset);
+      }
+      array = (char *)malloc(len);
+      isset = (char *)malloc(len);
+      bmemset(array, 0, len);
+      bmemset(isset, 0, len);
+   };
+
+public:
+   bitmap(uint32_t nb_bits): len(0), max(0), array(NULL), isset(NULL) {
+      init(nb_bits);
+   };
+   ~bitmap() {
+      free(array);
+      free(isset);
+   };
+   void copy(bitmap *from) {
+      init(from->max);
+      memcpy(isset, from->isset, len);
+      memcpy(array, from->array, len);
+   };
+   void resize(uint32_t nb_bits) {
+      if (nb_bits <= max) {
+         max = nb_bits;
+
+      } else {
+         max = nb_bits;
+         int tlen = nbytes_for_bits(max);
+         char *tarray = (char *) malloc(len);
+         char *tisset = (char *) malloc(len);
+         bmemset(tarray, 0, tlen);
+         bmemset(tisset, 0, tlen);
+         memcpy(tarray, array, len);
+         memcpy(tisset, isset, len);
+         free(array);
+         free(tisset);
+         array = tarray;
+         isset = isset;
+         len = tlen;
+      }
+   };
+
+   void dump() {
+      POOL_MEM tmp;
+      for (uint32_t i = 0 ; i < max ; i++) {
+         switch(is_set(i)) {
+         case -1:
+            pm_strcat(tmp, ".");
+            break;
+         case 0:
+            pm_strcat(tmp, "0");
+            break;
+         case 1:
+            pm_strcat(tmp, "1");
+            break;
+         }
+      }
+      Dmsg2(0, "bitmap %p: [%s]\n", this, tmp.c_str());
+   };
+
+   int32_t get_max_bit() {
+      return max - 1;
+   };
+
+   /* -1: not set
+    *  0: cleared
+    *  1: set
+    */
+   int is_set(uint32_t b) {
+      if (b >= max) {
+         ASSERTD(b >= max, "Should not query so much bit in bitmap");
+         return -1;
+      }
+      if (bit_is_set(b, isset)) {
+         return bit_is_set(b, array);
+
+      } else {
+         return -1;
+      }
+   };
+
+   bool bit_set(uint32_t b) {
+      if (b >= max) {
+         ASSERTD(b >= max, "Should not set so much bit in bitmap");
+         return false;
+      }
+      set_bit(b, isset);
+      set_bit(b, array);
+      return true;
+   };
+
+   bool bit_clear(uint32_t b) {
+      if (b >= max) {
+         ASSERTD(b >= max, "Should not clear so much bit in bitmap");
+         return false;
+      }
+      clear_bit(b, array);
+      set_bit(b, isset);
+      return true;
+   };
+
+   bool bit_reset(uint32_t b) {
+      if (b >= max) {
+         ASSERTD(b >= max, "Should not reset so much bit in bitmap");
+         return false;
+      }
+      clear_bit(b, isset);
+      clear_bit(b, array);
+      return true;
+   };
+};
+
+#endif  /* BITMAP_H */