提交 0711c4b7 编写于 作者: E Eric Blake

bitmap: add virBitmapCountBits

Sometimes it's handy to know how many bits are set.

* src/util/bitmap.h (virBitmapCountBits): New prototype.
(virBitmapNextSetBit): Use correct type.
* src/util/bitmap.c (virBitmapNextSetBit): Likewise.
(virBitmapSetAll): Maintain invariant of clear tail bits.
(virBitmapCountBits): New function.
* src/libvirt_private.syms (bitmap.h): Export it.
* tests/virbitmaptest.c (test2): Test it.
上级 0111b409
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
virBitmapClearAll; virBitmapClearAll;
virBitmapClearBit; virBitmapClearBit;
virBitmapCopy; virBitmapCopy;
virBitmapCountBits;
virBitmapEqual; virBitmapEqual;
virBitmapFormat; virBitmapFormat;
virBitmapFree; virBitmapFree;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "buf.h" #include "buf.h"
#include "util.h" #include "util.h"
#include "c-ctype.h" #include "c-ctype.h"
#include "count-one-bits.h"
struct _virBitmap { struct _virBitmap {
...@@ -527,8 +528,15 @@ size_t virBitmapSize(virBitmapPtr bitmap) ...@@ -527,8 +528,15 @@ size_t virBitmapSize(virBitmapPtr bitmap)
*/ */
void virBitmapSetAll(virBitmapPtr bitmap) void virBitmapSetAll(virBitmapPtr bitmap)
{ {
int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT;
memset(bitmap->map, 0xff, memset(bitmap->map, 0xff,
bitmap->map_len * (VIR_BITMAP_BITS_PER_UNIT / CHAR_BIT)); bitmap->map_len * (VIR_BITMAP_BITS_PER_UNIT / CHAR_BIT));
/* Ensure tail bits are clear. */
if (tail)
bitmap->map[bitmap->map_len - 1] &=
-1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail);
} }
/** /**
...@@ -585,10 +593,10 @@ bool virBitmapIsAllSet(virBitmapPtr bitmap) ...@@ -585,10 +593,10 @@ bool virBitmapIsAllSet(virBitmapPtr bitmap)
* *
* returns the position of the found bit, or -1 if no bit found. * returns the position of the found bit, or -1 if no bit found.
*/ */
int virBitmapNextSetBit(virBitmapPtr bitmap, int pos) ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
{ {
int nl; size_t nl;
int nb; size_t nb;
unsigned long bits; unsigned long bits;
if (pos < 0) if (pos < 0)
...@@ -613,3 +621,16 @@ int virBitmapNextSetBit(virBitmapPtr bitmap, int pos) ...@@ -613,3 +621,16 @@ int virBitmapNextSetBit(virBitmapPtr bitmap, int pos)
return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT; return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT;
} }
/* Return the number of bits currently set in the map. */
size_t
virBitmapCountBits(virBitmapPtr bitmap)
{
size_t i;
size_t ret = 0;
for (i = 0; i < bitmap->map_len; i++)
ret += count_one_bits_l(bitmap->map[i]);
return ret;
}
/* /*
* bitmap.h: Simple bitmap operations * bitmap.h: Simple bitmap operations
* *
* Copyright (C) 2012 Red Hat, Inc.
* Copyright (C) 2010 Novell, Inc. * Copyright (C) 2010 Novell, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
...@@ -99,7 +100,10 @@ void virBitmapClearAll(virBitmapPtr bitmap) ...@@ -99,7 +100,10 @@ void virBitmapClearAll(virBitmapPtr bitmap)
bool virBitmapIsAllSet(virBitmapPtr bitmap) bool virBitmapIsAllSet(virBitmapPtr bitmap)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
int virBitmapNextSetBit(virBitmapPtr bitmap, int pos) ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
ATTRIBUTE_NONNULL(1);
size_t virBitmapCountBits(virBitmapPtr bitmap)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
#endif #endif
...@@ -99,6 +99,9 @@ static int test2(const void *data ATTRIBUTE_UNUSED) ...@@ -99,6 +99,9 @@ static int test2(const void *data ATTRIBUTE_UNUSED)
if (testBit(bitmap, 100, 1020, false) < 0) if (testBit(bitmap, 100, 1020, false) < 0)
goto error; goto error;
if (virBitmapCountBits(bitmap) != 48)
goto error;
bitsString2 = virBitmapFormat(bitmap); bitsString2 = virBitmapFormat(bitmap);
if (strcmp(bitsString1, bitsString2)) if (strcmp(bitsString1, bitsString2))
goto error; goto error;
...@@ -106,6 +109,8 @@ static int test2(const void *data ATTRIBUTE_UNUSED) ...@@ -106,6 +109,8 @@ static int test2(const void *data ATTRIBUTE_UNUSED)
virBitmapSetAll(bitmap); virBitmapSetAll(bitmap);
if (testBit(bitmap, 0, size - 1, true) < 0) if (testBit(bitmap, 0, size - 1, true) < 0)
goto error; goto error;
if (virBitmapCountBits(bitmap) != size)
goto error;
if (!virBitmapIsAllSet(bitmap)) if (!virBitmapIsAllSet(bitmap))
goto error; goto error;
...@@ -113,6 +118,8 @@ static int test2(const void *data ATTRIBUTE_UNUSED) ...@@ -113,6 +118,8 @@ static int test2(const void *data ATTRIBUTE_UNUSED)
virBitmapClearAll(bitmap); virBitmapClearAll(bitmap);
if (testBit(bitmap, 0, size - 1, false) < 0) if (testBit(bitmap, 0, size - 1, false) < 0)
goto error; goto error;
if (virBitmapCountBits(bitmap) != 0)
goto error;
ret = 0; ret = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册