Pablo Greco 40546a
From 6ee2c599db989189e639c3de88d20045c62a1d2c Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <6ee2c599db989189e639c3de88d20045c62a1d2c@dist-git>
Pablo Greco 40546a
From: Andrea Bolognani <abologna@redhat.com>
Pablo Greco 40546a
Date: Tue, 11 Jun 2019 10:55:01 +0200
Pablo Greco 40546a
Subject: [PATCH] util: Introduce virBitmapUnion()
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
(cherry picked from commit 1b2ac8010cc1fe871f538b3f48c5e48213c5c074)
Pablo Greco 40546a
Pablo Greco 40546a
https://bugzilla.redhat.com/show_bug.cgi?id=1716908
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Pablo Greco 40546a
Message-Id: <20190611085506.12564-2-abologna@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/libvirt_private.syms |  1 +
Pablo Greco 40546a
 src/util/virbitmap.c     | 27 +++++++++++++++++++++++++++
Pablo Greco 40546a
 src/util/virbitmap.h     |  4 ++++
Pablo Greco 40546a
 tests/virbitmaptest.c    | 38 ++++++++++++++++++++++++++++++++++++++
Pablo Greco 40546a
 4 files changed, 70 insertions(+)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
Pablo Greco 40546a
index ee7625b0f3..05c96c29e2 100644
Pablo Greco 40546a
--- a/src/libvirt_private.syms
Pablo Greco 40546a
+++ b/src/libvirt_private.syms
Pablo Greco 40546a
@@ -1476,6 +1476,7 @@ virBitmapSubtract;
Pablo Greco 40546a
 virBitmapToData;
Pablo Greco 40546a
 virBitmapToDataBuf;
Pablo Greco 40546a
 virBitmapToString;
Pablo Greco 40546a
+virBitmapUnion;
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 # util/virbuffer.h
Pablo Greco 40546a
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
Pablo Greco 40546a
index ef18dad255..49e542a4e6 100644
Pablo Greco 40546a
--- a/src/util/virbitmap.c
Pablo Greco 40546a
+++ b/src/util/virbitmap.c
Pablo Greco 40546a
@@ -1265,6 +1265,33 @@ virBitmapIntersect(virBitmapPtr a,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
+/**
Pablo Greco 40546a
+ * virBitmapUnion:
Pablo Greco 40546a
+ * @a: bitmap, modified to contain result
Pablo Greco 40546a
+ * @b: other bitmap
Pablo Greco 40546a
+ *
Pablo Greco 40546a
+ * Performs union of two bitmaps: a = union(a, b)
Pablo Greco 40546a
+ *
Pablo Greco 40546a
+ * Returns 0 on success, <0 on failure.
Pablo Greco 40546a
+ */
Pablo Greco 40546a
+int
Pablo Greco 40546a
+virBitmapUnion(virBitmapPtr a,
Pablo Greco 40546a
+               const virBitmap *b)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (a->nbits < b->nbits &&
Pablo Greco 40546a
+        virBitmapExpand(a, b->nbits - 1) < 0) {
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < b->map_len; i++)
Pablo Greco 40546a
+        a->map[i] |= b->map[i];
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 /**
Pablo Greco 40546a
  * virBitmapSubtract:
Pablo Greco 40546a
  * @a: minuend/result
Pablo Greco 40546a
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
Pablo Greco 40546a
index 312e7e2933..5934508d11 100644
Pablo Greco 40546a
--- a/src/util/virbitmap.h
Pablo Greco 40546a
+++ b/src/util/virbitmap.h
Pablo Greco 40546a
@@ -151,6 +151,10 @@ bool virBitmapOverlaps(virBitmapPtr b1,
Pablo Greco 40546a
 void virBitmapIntersect(virBitmapPtr a, virBitmapPtr b)
Pablo Greco 40546a
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
Pablo Greco 40546a
 
Pablo Greco 40546a
+int virBitmapUnion(virBitmapPtr a,
Pablo Greco 40546a
+                   const virBitmap *b)
Pablo Greco 40546a
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
Pablo Greco 40546a
+
Pablo Greco 40546a
 void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b)
Pablo Greco 40546a
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
Pablo Greco 40546a
 
Pablo Greco 40546a
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
Pablo Greco 40546a
index 2fbafc0a76..cafe865dde 100644
Pablo Greco 40546a
--- a/tests/virbitmaptest.c
Pablo Greco 40546a
+++ b/tests/virbitmaptest.c
Pablo Greco 40546a
@@ -740,6 +740,34 @@ test14(const void *opaque)
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
+/* virBitmapUnion() */
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+test15(const void *opaque)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    const struct testBinaryOpData *data = opaque;
Pablo Greco 40546a
+    VIR_AUTOPTR(virBitmap) amap = NULL;
Pablo Greco 40546a
+    VIR_AUTOPTR(virBitmap) bmap = NULL;
Pablo Greco 40546a
+    VIR_AUTOPTR(virBitmap) resmap = NULL;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (!(amap = virBitmapParseUnlimited(data->a)) ||
Pablo Greco 40546a
+        !(bmap = virBitmapParseUnlimited(data->b)) ||
Pablo Greco 40546a
+        !(resmap = virBitmapParseUnlimited(data->res))) {
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (virBitmapUnion(amap, bmap) < 0)
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (!virBitmapEqual(amap, resmap)) {
Pablo Greco 40546a
+        fprintf(stderr,
Pablo Greco 40546a
+                "\n bitmap union failed: union('%s', '%s') != '%s'\n",
Pablo Greco 40546a
+                data->a, data->b, data->res);
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
 
Pablo Greco 40546a
 #define TESTBINARYOP(A, B, RES, FUNC) \
Pablo Greco 40546a
     testBinaryOpData.a = A; \
Pablo Greco 40546a
@@ -798,6 +826,16 @@ mymain(void)
Pablo Greco 40546a
     TESTBINARYOP("0-3", "0,^0", "0-3", test14);
Pablo Greco 40546a
     TESTBINARYOP("0,2", "1,3", "0,2", test14);
Pablo Greco 40546a
 
Pablo Greco 40546a
+    /* virBitmapUnion() */
Pablo Greco 40546a
+    virTestCounterReset("test15-");
Pablo Greco 40546a
+    TESTBINARYOP("0-1", "0-1", "0-1", test15);
Pablo Greco 40546a
+    TESTBINARYOP("0", "1", "0-1", test15);
Pablo Greco 40546a
+    TESTBINARYOP("0-1", "2-3", "0-3", test15);
Pablo Greco 40546a
+    TESTBINARYOP("0-3", "1-2", "0-3", test15);
Pablo Greco 40546a
+    TESTBINARYOP("0,^0", "12345", "12345", test15);
Pablo Greco 40546a
+    TESTBINARYOP("12345", "0,^0", "12345", test15);
Pablo Greco 40546a
+    TESTBINARYOP("0,^0", "0,^0", "0,^0", test15);
Pablo Greco 40546a
+
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a