]> xenbits.xensource.com Git - libvirt.git/commitdiff
bitmap: add virBitmapLastSetBit for finding the last bit position of bitmap
authorChen Fan <chen.fan.fnst@cn.fujitsu.com>
Tue, 4 Nov 2014 02:44:39 +0000 (10:44 +0800)
committerMartin Kletzander <mkletzan@redhat.com>
Tue, 4 Nov 2014 06:03:36 +0000 (07:03 +0100)
Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
src/libvirt_private.syms
src/util/virbitmap.c
src/util/virbitmap.h
tests/virbitmaptest.c

index e7e8df526c0f3c6f69de3bb6350f8082ca0cca59..840d93bcae43d03a048b4028479a82984c6ed4a6 100644 (file)
@@ -1011,6 +1011,7 @@ virBitmapFree;
 virBitmapGetBit;
 virBitmapIsAllClear;
 virBitmapIsAllSet;
+virBitmapLastSetBit;
 virBitmapNew;
 virBitmapNewCopy;
 virBitmapNewData;
index b6bd074cf4232a4a5f6a89d38e076a24ff64f024..04a2388049d2f4d71b921a7b0987d38c31597a5d 100644 (file)
@@ -650,6 +650,51 @@ virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
     return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT;
 }
 
+/**
+ * virBitmapLastSetBit:
+ * @bitmap: the bitmap
+ *
+ * Search for the last set bit in bitmap @bitmap.
+ *
+ * Returns the position of the found bit, or -1 if no bit is set.
+ */
+ssize_t
+virBitmapLastSetBit(virBitmapPtr bitmap)
+{
+    ssize_t i;
+    int unusedBits;
+    ssize_t sz;
+    unsigned long bits;
+
+    unusedBits = bitmap->map_len * VIR_BITMAP_BITS_PER_UNIT - bitmap->max_bit;
+
+    sz = bitmap->map_len - 1;
+    if (unusedBits > 0) {
+        bits = bitmap->map[sz] & (VIR_BITMAP_BIT(VIR_BITMAP_BITS_PER_UNIT - unusedBits) - 1);
+        if (bits != 0)
+            goto found;
+
+        sz--;
+    }
+
+    for (; sz >= 0; sz--) {
+        bits = bitmap->map[sz];
+        if (bits != 0)
+            goto found;
+    }
+
+    if (bits == 0)
+        return -1;
+
+ found:
+    for (i = VIR_BITMAP_BITS_PER_UNIT - 1; i >= 0; i--) {
+        if (bits & 1UL << i)
+            return i + sz * VIR_BITMAP_BITS_PER_UNIT;
+    }
+
+    return -1;
+}
+
 /**
  * virBitmapNextClearBit:
  * @bitmap: the bitmap
index 4493cc94ba500f716458504cbcccdf9d73fbc004..565264cc4c4283cde7e2904066e33b42d6961976 100644 (file)
@@ -105,6 +105,9 @@ bool virBitmapIsAllClear(virBitmapPtr bitmap)
 ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
     ATTRIBUTE_NONNULL(1);
 
+ssize_t virBitmapLastSetBit(virBitmapPtr bitmap)
+    ATTRIBUTE_NONNULL(1);
+
 ssize_t virBitmapNextClearBit(virBitmapPtr bitmap, ssize_t pos)
     ATTRIBUTE_NONNULL(1);
 
index ea832ad7f3fa3ad4b99be04b6b955137122457c7..ac5f2987d760ecf813c82270a24dc9806f4bbd59 100644 (file)
@@ -171,7 +171,7 @@ test3(const void *data ATTRIBUTE_UNUSED)
     return ret;
 }
 
-/* test for virBitmapNextSetBit, virBitmapNextClearBit */
+/* test for virBitmapNextSetBit, virBitmapLastSetBit, virBitmapNextClearBit */
 static int
 test4(const void *data ATTRIBUTE_UNUSED)
 {
@@ -200,6 +200,9 @@ test4(const void *data ATTRIBUTE_UNUSED)
     if (virBitmapNextSetBit(bitmap, -1) != -1)
         goto error;
 
+    if (virBitmapLastSetBit(bitmap) != -1)
+        goto error;
+
     for (i = 0; i < size; i++) {
         if (virBitmapNextClearBit(bitmap, i - 1) != i)
             goto error;
@@ -232,6 +235,11 @@ test4(const void *data ATTRIBUTE_UNUSED)
     if (virBitmapNextSetBit(bitmap, i) != -1)
         goto error;
 
+    j = sizeof(bitsPos)/sizeof(int) - 1;
+
+    if (virBitmapLastSetBit(bitmap) != bitsPos[j])
+        goto error;
+
     j = 0;
     i = -1;
 
@@ -255,6 +263,9 @@ test4(const void *data ATTRIBUTE_UNUSED)
     if (virBitmapNextSetBit(bitmap, i) != -1)
         goto error;
 
+    if (virBitmapLastSetBit(bitmap) != size - 1)
+        goto error;
+
     if (virBitmapNextClearBit(bitmap, -1) != -1)
         goto error;