util: bitmap: Introduce bitmap subtraction

Performs binary subtraction of two bitmaps. Stores result in the first
operand.
This commit is contained in:
Peter Krempa 2016-01-07 15:45:39 +01:00
parent c3bd0019c0
commit 9479642fd3
4 changed files with 80 additions and 0 deletions

View File

@ -1161,6 +1161,7 @@ virBitmapSetAll;
virBitmapSetBit;
virBitmapSize;
virBitmapString;
virBitmapSubtract;
virBitmapToData;
virBitmapToDataBuf;

View File

@ -859,3 +859,24 @@ virBitmapOverlaps(virBitmapPtr b1,
return false;
}
/**
* virBitmapSubtract:
* @a: minuend/result
* @b: subtrahend
*
* Performs bitwise subtraction: a = a - b
*/
void
virBitmapSubtract(virBitmapPtr a,
virBitmapPtr b)
{
size_t i;
size_t max = a->map_len;
if (max > b->map_len)
max = b->map_len;
for (i = 0; i < max; i++)
a->map[i] &= ~b->map[i];
}

View File

@ -129,4 +129,7 @@ bool virBitmapOverlaps(virBitmapPtr b1,
virBitmapPtr b2)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
#endif

View File

@ -552,9 +552,55 @@ test10(const void *opaque ATTRIBUTE_UNUSED)
return ret;
}
struct testBinaryOpData {
const char *a;
const char *b;
const char *res;
};
static int
test11(const void *opaque)
{
const struct testBinaryOpData *data = opaque;
virBitmapPtr amap = NULL;
virBitmapPtr bmap = NULL;
virBitmapPtr resmap = NULL;
int ret = -1;
if (virBitmapParse(data->a, 0, &amap, 256) < 0 ||
virBitmapParse(data->b, 0, &bmap, 256) < 0 ||
virBitmapParse(data->res, 0, &resmap, 256) < 0)
goto cleanup;
virBitmapSubtract(amap, bmap);
if (!virBitmapEqual(amap, resmap)) {
fprintf(stderr, "\n bitmap subtraction failed: '%s'-'%s'!='%s'\n",
data->a, data->b, data->res);
goto cleanup;
}
ret = 0;
cleanup:
virBitmapFree(amap);
virBitmapFree(bmap);
virBitmapFree(resmap);
return ret;
}
#define TESTBINARYOP(A, B, RES, FUNC) \
testBinaryOpData.a = A; \
testBinaryOpData.b = B; \
testBinaryOpData.res = RES; \
if (virtTestRun(virtTestCounterNext(), FUNC, &testBinaryOpData) < 0) \
ret = -1;
static int
mymain(void)
{
struct testBinaryOpData testBinaryOpData;
int ret = 0;
if (virtTestRun("test1", test1, NULL) < 0)
@ -578,6 +624,15 @@ mymain(void)
if (virtTestRun("test10", test10, NULL) < 0)
ret = -1;
virtTestCounterReset("test11-");
TESTBINARYOP("0", "0", "0,^0", test11);
TESTBINARYOP("0-3", "0", "1-3", test11);
TESTBINARYOP("0-3", "0,3", "1-2", test11);
TESTBINARYOP("0,^0", "0", "0,^0", test11);
TESTBINARYOP("0-3", "0-3", "0,^0", test11);
TESTBINARYOP("0-3", "0,^0", "0-3", test11);
TESTBINARYOP("0,2", "1,3", "0,2", test11);
return ret;
}