[libvirt] [PATCH 2/4] fixup? util: Optimize virBitmapUnion()
Ján Tomko
jtomko at redhat.com
Mon Jun 3 12:10:37 UTC 2019
On Fri, May 31, 2019 at 05:22:00PM +0200, Andrea Bolognani wrote:
>The original implementation is extremely straightforward but
>not too efficient, because it uses the public API instead of
>poking the innards directly. This second implementation does
>the latter, and as a consequence can afford to make @b const,
>which is nice even though most existing virBitmap APIs use
>non-const pointers even for read-only bitmaps.
>
>That said, I'm not entirely sure I got it quite right, so a
>review from someone who's well versed in the virBitmap
>internals (*cough* Peter *cough*) would be appreciated, and
>if my implementation passes muster or can be amended through
>review comments I'll gladly squash this commit into the
>previous one.
Yes please. Also drop this paragraph. History is written by the winners
;)
>
>Signed-off-by: Andrea Bolognani <abologna at redhat.com>
>---
> src/util/virbitmap.c | 18 ++++++++++++------
> src/util/virbitmap.h | 2 +-
> 2 files changed, 13 insertions(+), 7 deletions(-)
>
>diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
>index 1f0db563ab..f2127c053d 100644
>--- a/src/util/virbitmap.c
>+++ b/src/util/virbitmap.c
>@@ -1271,17 +1271,23 @@ virBitmapIntersect(virBitmapPtr a,
> */
> int
> virBitmapUnion(virBitmapPtr a,
>- virBitmapPtr b)
>+ const virBitmap *b)
> {
> size_t i;
>+ size_t max;
>
>- for (i = 0; i < b->nbits; i++) {
>- if (virBitmapIsBitSet(b, i)) {
>- if (virBitmapSetBitExpand(a, i) < 0)
>- return -1;
>- }
>+ if (a->nbits < b->nbits &&
>+ virBitmapExpand(a, b->nbits) < 0) {
After this, 'b' can hold b->nbits and 'a' can hold b->nbits+1.
if (b->nbits &&
a->nbits < b->nbits &&
virBitmapExpand(a, b->nbits -1) < 0) {
>+ return -1;
> }
>
>+ max = a->map_len;
>+ if (max > b->map_len)
>+ max = b->map_len;
You expanded the 'a' bitmap just a few lines above.
So if you can safely go up to b->map_len without accessing
invalid memory in a or missing any set bits in b.
>+
>+ for (i = 0; i < max; i++)
>+ a->map[i] |= b->map[i];
>+
> return 0;
> }
>
Reviewed-by: Ján Tomko <jtomko at redhat.com>
Jano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20190603/951c475d/attachment-0001.sig>
More information about the libvir-list
mailing list