mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
bitmap: add way to find next clear bit
We had an easy way to iterate set bits, but not for iterating cleared bits. * src/util/virbitmap.h (virBitmapNextClearBit): New prototype. * src/util/virbitmap.c (virBitmapNextClearBit): Implement it. * src/libvirt_private.syms (bitmap.h): Export it. * tests/virbitmaptest.c (test4): Test it.
This commit is contained in:
parent
75fabbdf3f
commit
98fc0137f1
@ -18,6 +18,7 @@ virBitmapIsAllSet;
|
|||||||
virBitmapNew;
|
virBitmapNew;
|
||||||
virBitmapNewCopy;
|
virBitmapNewCopy;
|
||||||
virBitmapNewData;
|
virBitmapNewData;
|
||||||
|
virBitmapNextClearBit;
|
||||||
virBitmapNextSetBit;
|
virBitmapNextSetBit;
|
||||||
virBitmapParse;
|
virBitmapParse;
|
||||||
virBitmapSetAll;
|
virBitmapSetAll;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* virbitmap.h: Simple bitmap operations
|
* virbitmap.h: Simple bitmap operations
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2012 Red Hat, Inc.
|
* Copyright (C) 2010-2013 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
|
||||||
@ -595,13 +595,14 @@ bool virBitmapIsAllSet(virBitmapPtr bitmap)
|
|||||||
* @bitmap: the bitmap
|
* @bitmap: the bitmap
|
||||||
* @pos: the position after which to search for a set bit
|
* @pos: the position after which to search for a set bit
|
||||||
*
|
*
|
||||||
* search the first set bit after position @pos in bitmap @bitmap.
|
* Search for the first set bit after position @pos in bitmap @bitmap.
|
||||||
* @pos can be -1 to search for the first set bit. Position starts
|
* @pos can be -1 to search for the first set bit. Position starts
|
||||||
* at 0.
|
* at 0.
|
||||||
*
|
*
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
|
ssize_t
|
||||||
|
virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
|
||||||
{
|
{
|
||||||
size_t nl;
|
size_t nl;
|
||||||
size_t nb;
|
size_t nb;
|
||||||
@ -630,6 +631,54 @@ ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
|
|||||||
return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT;
|
return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virBitmapNextClearBit:
|
||||||
|
* @bitmap: the bitmap
|
||||||
|
* @pos: the position after which to search for a clear bit
|
||||||
|
*
|
||||||
|
* Search for the first clear bit after position @pos in bitmap @bitmap.
|
||||||
|
* @pos can be -1 to search for the first set bit. Position starts
|
||||||
|
* at 0.
|
||||||
|
*
|
||||||
|
* Returns the position of the found bit, or -1 if no bit found.
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
virBitmapNextClearBit(virBitmapPtr bitmap, ssize_t pos)
|
||||||
|
{
|
||||||
|
size_t nl;
|
||||||
|
size_t nb;
|
||||||
|
unsigned long bits;
|
||||||
|
|
||||||
|
if (pos < 0)
|
||||||
|
pos = -1;
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if (pos >= bitmap->max_bit)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
nl = pos / VIR_BITMAP_BITS_PER_UNIT;
|
||||||
|
nb = pos % VIR_BITMAP_BITS_PER_UNIT;
|
||||||
|
|
||||||
|
bits = ~bitmap->map[nl] & ~((1UL << nb) - 1);
|
||||||
|
|
||||||
|
while (bits == 0 && ++nl < bitmap->map_len) {
|
||||||
|
bits = ~bitmap->map[nl];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nl == bitmap->map_len - 1) {
|
||||||
|
/* Ensure tail bits are ignored. */
|
||||||
|
int tail = bitmap->max_bit % VIR_BITMAP_BITS_PER_UNIT;
|
||||||
|
|
||||||
|
if (tail)
|
||||||
|
bits &= -1UL >> (VIR_BITMAP_BITS_PER_UNIT - tail);
|
||||||
|
}
|
||||||
|
if (bits == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the number of bits currently set in the map. */
|
/* Return the number of bits currently set in the map. */
|
||||||
size_t
|
size_t
|
||||||
virBitmapCountBits(virBitmapPtr bitmap)
|
virBitmapCountBits(virBitmapPtr bitmap)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* virbitmap.h: Simple bitmap operations
|
* virbitmap.h: Simple bitmap operations
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Red Hat, Inc.
|
* Copyright (C) 2012-2013 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
|
||||||
@ -103,6 +103,9 @@ bool virBitmapIsAllSet(virBitmapPtr bitmap)
|
|||||||
ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
|
ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
ssize_t virBitmapNextClearBit(virBitmapPtr bitmap, ssize_t pos)
|
||||||
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
size_t virBitmapCountBits(virBitmapPtr bitmap)
|
size_t virBitmapCountBits(virBitmapPtr bitmap)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2013 Red Hat, Inc.
|
||||||
* Copyright (C) 2012 Fujitsu.
|
* Copyright (C) 2012 Fujitsu.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -160,7 +161,7 @@ error:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test for virBitmapNextSetBit */
|
/* test for virBitmapNextSetBit, virBitmapNextClearBit */
|
||||||
static int test4(const void *data ATTRIBUTE_UNUSED)
|
static int test4(const void *data ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
const char *bitsString = "0, 2-4, 6-10, 12, 14-18, 20, 22, 25";
|
const char *bitsString = "0, 2-4, 6-10, 12, 14-18, 20, 22, 25";
|
||||||
@ -169,17 +170,30 @@ static int test4(const void *data ATTRIBUTE_UNUSED)
|
|||||||
0, 2, 3, 4, 6, 7, 8, 9, 10, 12,
|
0, 2, 3, 4, 6, 7, 8, 9, 10, 12,
|
||||||
14, 15, 16, 17, 18, 20, 22, 25
|
14, 15, 16, 17, 18, 20, 22, 25
|
||||||
};
|
};
|
||||||
int npos = 18;
|
int bitsPosInv[] = {
|
||||||
|
1, 5, 11, 13, 19, 21, 23, 24, 26, 27,
|
||||||
|
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
|
||||||
|
};
|
||||||
virBitmapPtr bitmap = NULL;
|
virBitmapPtr bitmap = NULL;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
if (ARRAY_CARDINALITY(bitsPos) + ARRAY_CARDINALITY(bitsPosInv) != size)
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* 1. zero set */
|
/* 1. zero set */
|
||||||
|
|
||||||
bitmap = virBitmapNew(size);
|
bitmap = virBitmapNew(size);
|
||||||
if (!bitmap)
|
if (!bitmap)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (virBitmapNextSetBit(bitmap, -1) >= 0)
|
if (virBitmapNextSetBit(bitmap, -1) != -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
if (virBitmapNextClearBit(bitmap, i - 1) != i)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (virBitmapNextClearBit(bitmap, i) != -1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virBitmapFree(bitmap);
|
virBitmapFree(bitmap);
|
||||||
@ -195,27 +209,39 @@ static int test4(const void *data ATTRIBUTE_UNUSED)
|
|||||||
j = 0;
|
j = 0;
|
||||||
i = -1;
|
i = -1;
|
||||||
|
|
||||||
while (j < npos) {
|
while (j < ARRAY_CARDINALITY(bitsPos)) {
|
||||||
i = virBitmapNextSetBit(bitmap, i);
|
i = virBitmapNextSetBit(bitmap, i);
|
||||||
if (i != bitsPos[j++])
|
if (i != bitsPos[j++])
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virBitmapNextSetBit(bitmap, i) > 0)
|
if (virBitmapNextSetBit(bitmap, i) != -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
i = -1;
|
||||||
|
|
||||||
|
while (j < ARRAY_CARDINALITY(bitsPosInv)) {
|
||||||
|
i = virBitmapNextClearBit(bitmap, i);
|
||||||
|
if (i != bitsPosInv[j++])
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBitmapNextClearBit(bitmap, i) != -1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* 3. full set */
|
/* 3. full set */
|
||||||
|
|
||||||
i = -1;
|
|
||||||
virBitmapSetAll(bitmap);
|
virBitmapSetAll(bitmap);
|
||||||
|
|
||||||
for (j = 0; j < size; j++) {
|
for (i = 0; i < size; i++) {
|
||||||
i = virBitmapNextSetBit(bitmap, i);
|
if (virBitmapNextSetBit(bitmap, i - 1) != i)
|
||||||
if (i != j)
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (virBitmapNextSetBit(bitmap, i) != -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (virBitmapNextSetBit(bitmap, i) > 0)
|
if (virBitmapNextClearBit(bitmap, -1) != -1)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virBitmapFree(bitmap);
|
virBitmapFree(bitmap);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user