On 08/14/2010 10:23 AM, Eric Blake wrote:
So, after some IRC discussions, two ideas emerged in addition to the
obvious documentation update. One is the simpler VIR_EXPAND_N, where
the array size always matches the array allocation, along with a
VIR_SHRINK_N counterpart which can trim an array back down (and
failure to trim need not be fatal). But this can scale quadratically
if you end up with a large array, as the existing contents must be
copied on every realloc. See patches 1 and 2 for an implementation
and use.
The other idea is VIR_RESIZE_N, which tracks allocation separately
from usage, and has better scaling by doing geometric growth only when
needed rather than on every array usage increase. But it takes more
parameters (making it slightly harder to remember how to use
correctly), along with possible modifications of the struct tracking
an array (so it might not be possible to modify all uses of
VIR_REALLOC_N to use this, if it would end up altering a public struct
layout). See patches 3 and 4 for an implementation and use.
Again on IRC, Matthias had yet another idea, by borrowing after c++'s
new[] and delete[] operators. Basically, VIR_ALLOC_N overallocates,
reserves the first 8 bytes for itself (or, more likely,
__alignof__(union{size_t;long double;}) bytes, to be precise to platform
alignment needs), and stores the length of the array in that chunk while
returning an offset pointer to the user. That way, the user does not
have to track allocations; all other VIR_*_N macros would be able to
look before the user's pointer to find that hidden length field. On the
other hand, it means we would need a VIR_FREE_N for arrays, since the
user's pointer is not the same as the pointer returned by malloc; and
mixing VIR_ALLOC/VIR_FREE_N or VIR_ALLOC_N/VIR_FREE is a disaster
waiting to happen.
It sounds like it might have some appeal for reducing some of the user's
book-keeping, but would require a careful audit of code to safely match
VIR_ALLOC_N exactly with VIR_FREE_N. Thoughts on this approach?
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org