Re: [libvirt] [PATCH v3 2/9] New functions for virBitmap
On Thu, Sep 13, 2012 at 02:35:03PM +0100, Daniel P. Berrange wrote: > On Thu, Sep 13, 2012 at 02:03:20PM +0800, Hu Tao wrote: > > In many places we store bitmap info in a chunk of data > > (pointed to by a char *), and have redundant codes to > > set/unset bits. This patch extends virBitmap, and convert > > those codes to use virBitmap in subsequent patches. > > --- > > .gitignore |1 + > > src/libvirt_private.syms | 11 ++ > > src/util/bitmap.c| 405 > > +- > > src/util/bitmap.h| 34 > > tests/Makefile.am|7 +- > > tests/virbitmaptest.c| 362 + > > 6 files changed, 818 insertions(+), 2 deletions(-) > > create mode 100644 tests/virbitmaptest.c > > > > diff --git a/.gitignore b/.gitignore > > index d998f0e..1ca537e 100644 > > --- a/.gitignore > > +++ b/.gitignore > > @@ -157,6 +157,7 @@ > > /tests/utiltest > > /tests/viratomictest > > /tests/virauthconfigtest > > +/tests/virbitmaptest > > /tests/virbuftest > > /tests/virdrivermoduletest > > /tests/virhashtest > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > > index 8dfb4ce..0ad6376 100644 > > --- a/src/libvirt_private.syms > > +++ b/src/libvirt_private.syms > > @@ -7,12 +7,23 @@ > > > > # bitmap.h > > virBitmapAlloc; > > +virBitmapAllocFromData; > > Hmm, can you rename the existing method 'virBitmapNew' and > then call you addition 'virBitmapNewData' OK. I will send v4 to address this. -- Thanks, Hu Tao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3 2/9] New functions for virBitmap
On Thu, Sep 13, 2012 at 02:03:20PM +0800, Hu Tao wrote: > In many places we store bitmap info in a chunk of data > (pointed to by a char *), and have redundant codes to > set/unset bits. This patch extends virBitmap, and convert > those codes to use virBitmap in subsequent patches. > --- > .gitignore |1 + > src/libvirt_private.syms | 11 ++ > src/util/bitmap.c| 405 > +- > src/util/bitmap.h| 34 > tests/Makefile.am|7 +- > tests/virbitmaptest.c| 362 + > 6 files changed, 818 insertions(+), 2 deletions(-) > create mode 100644 tests/virbitmaptest.c > > diff --git a/.gitignore b/.gitignore > index d998f0e..1ca537e 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -157,6 +157,7 @@ > /tests/utiltest > /tests/viratomictest > /tests/virauthconfigtest > +/tests/virbitmaptest > /tests/virbuftest > /tests/virdrivermoduletest > /tests/virhashtest > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 8dfb4ce..0ad6376 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -7,12 +7,23 @@ > > # bitmap.h > virBitmapAlloc; > +virBitmapAllocFromData; Hmm, can you rename the existing method 'virBitmapNew' and then call you addition 'virBitmapNewData' > +/** > + * virBitmapCopy: s/Copy/NewCopy/ > + * @src: the source bitmap. > + * > + * Makes a copy of bitmap @src. > + * > + * returns the copied bitmap on success, or NULL otherwise. Caller > + * should call virBitmapFree to free the returned bitmap. > + */ > +virBitmapPtr virBitmapNewCopy(virBitmapPtr src) > +{ > +virBitmapPtr dst; > + > +if ((dst = virBitmapAlloc(src->max_bit)) == NULL) > +return NULL; > + > +if (virBitmapCopy(dst, src) != 0) { > +virBitmapFree(dst); > +return NULL; > +} > + > +return dst; > +} > + > +/** > + * virBitmapAllocFromData: > + * @data: the data > + * @len: length of @data in bytes > + * > + * Allocate a bitmap from a chunk of data containing bits > + * information > + * > + * Returns a pointer to the allocated bitmap or NULL if > + * memory cannot be allocated. > + */ > +virBitmapPtr virBitmapAllocFromData(void *data, int len) s/AllocFromData/NewData/ > +{ > +virBitmapPtr bitmap; > +int i; > + > +bitmap = virBitmapAlloc(len * CHAR_BIT); > +if (!bitmap) > +return NULL; > + > +memcpy(bitmap->map, data, len); > +for (i = 0; i < bitmap->map_len; i++) > +bitmap->map[i] = le64toh(bitmap->map[i]); > + > +return bitmap; > +} ACK if those few renames are made Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 2/9] New functions for virBitmap
In many places we store bitmap info in a chunk of data (pointed to by a char *), and have redundant codes to set/unset bits. This patch extends virBitmap, and convert those codes to use virBitmap in subsequent patches. --- .gitignore |1 + src/libvirt_private.syms | 11 ++ src/util/bitmap.c| 405 +- src/util/bitmap.h| 34 tests/Makefile.am|7 +- tests/virbitmaptest.c| 362 + 6 files changed, 818 insertions(+), 2 deletions(-) create mode 100644 tests/virbitmaptest.c diff --git a/.gitignore b/.gitignore index d998f0e..1ca537e 100644 --- a/.gitignore +++ b/.gitignore @@ -157,6 +157,7 @@ /tests/utiltest /tests/viratomictest /tests/virauthconfigtest +/tests/virbitmaptest /tests/virbuftest /tests/virdrivermoduletest /tests/virhashtest diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8dfb4ce..0ad6376 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -7,12 +7,23 @@ # bitmap.h virBitmapAlloc; +virBitmapAllocFromData; +virBitmapClearAll; virBitmapClearBit; virBitmapCopy; +virBitmapEqual; +virBitmapFormat; virBitmapFree; virBitmapGetBit; +virBitmapIsAllSet; +virBitmapNewCopy; +virBitmapNextSetBit; +virBitmapParse; +virBitmapSetAll; virBitmapSetBit; +virBitmapSize; virBitmapString; +virBitmapToData; # buf.h diff --git a/src/util/bitmap.c b/src/util/bitmap.c index 434c443..a6234ba 100644 --- a/src/util/bitmap.c +++ b/src/util/bitmap.c @@ -33,6 +33,8 @@ #include "bitmap.h" #include "memory.h" #include "buf.h" +#include "util.h" +#include "c-ctype.h" struct _virBitmap { @@ -145,6 +147,12 @@ int virBitmapClearBit(virBitmapPtr bitmap, size_t b) return 0; } +/* Helper function. caller must ensure b < bitmap->size */ +static bool virBitmapIsSet(virBitmapPtr bitmap, size_t b) +{ +return !!(bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & VIR_BITMAP_BIT(b)); +} + /** * virBitmapGetBit: * @bitmap: Pointer to bitmap @@ -161,7 +169,7 @@ int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) if (bitmap->max_bit <= b) return -1; -*result = !!(bitmap->map[VIR_BITMAP_UNIT_OFFSET(b)] & VIR_BITMAP_BIT(b)); +*result = virBitmapIsSet(bitmap, b); return 0; } @@ -195,3 +203,398 @@ char *virBitmapString(virBitmapPtr bitmap) return virBufferContentAndReset(&buf); } + +/** + * virBitmapFormat: + * @bitmap: the bitmap + * + * This function is the counterpart of virBitmapParse. This function creates + * a human-readable string representing the bits in bitmap. + * + * See virBitmapParse for the format of @str. + * + * Returns the string on success or NULL otherwise. Caller should call + * VIR_FREE to free the string. + */ +char *virBitmapFormat(virBitmapPtr bitmap) +{ +virBuffer buf = VIR_BUFFER_INITIALIZER; +bool first = true; +int start, cur, prev; + +if (!bitmap) +return NULL; + +cur = virBitmapNextSetBit(bitmap, -1); +if (cur < 0) +return strdup(""); + +start = prev = cur; +while (prev >= 0) { +cur = virBitmapNextSetBit(bitmap, prev); + +if (cur == prev + 1) { +prev = cur; +continue; +} + +/* cur < 0 or cur > prev + 1 */ + +if (!first) +virBufferAddLit(&buf, ","); +else +first = false; + +if (prev == start) +virBufferAsprintf(&buf, "%d", start); +else +virBufferAsprintf(&buf, "%d-%d", start, prev); + +start = prev = cur; +} + +if (virBufferError(&buf)) { +virBufferFreeAndReset(&buf); +return NULL; +} + +return virBufferContentAndReset(&buf); +} + +/** + * virBitmapParse: + * @str: points to a string representing a human-readable bitmap + * @bitmap: a bitmap created from @str + * @bitmapSize: the upper limit of num of bits in created bitmap + * + * This function is the counterpart of virBitmapFormat. This function creates + * a bitmap, in which bits are set according to the content of @str. + * + * @str is a comma separated string of fields N, which means a number of bit + * to set, and ^N, which means to unset the bit, and N-M for ranges of bits + * to set. + * + * Returns the number of bits set in @bitmap, or -1 in case of error. + */ + +int virBitmapParse(const char *str, + char sep, + virBitmapPtr *bitmap, + size_t bitmapSize) +{ +int ret = 0; +bool neg = false; +const char *cur; +char *tmp; +int i, start, last; + +if (!str) +return -1; + +cur = str; +virSkipSpaces(&cur); + +if (*cur == 0) +return -1; + +*bitmap = virBitmapAlloc(bitmapSize); +if (!*bitmap) +return -1; + +while (*cur != 0 && *cur != sep) { +/* + * 3 constructs are allowed: + * - N : a single CPU number + * - N-M