On 9/24/13 11:28 AM, Rainer Schuetze wrote:
On 24.09.2013 10:46, Dmitry Olshansky wrote:
* expand(b, minDelta, maxDelta) grows b's length by at least minDelta
(and on a best-effort basis by at least maxDelta) and returns true, or
does nothing and returns false. In most allocators this should be @safe.
(One key insight is that expand() can be made @safe whereas shrink() or
realloc() are most often not; such mini-epiphanies are very exciting
because they put the design on a beam guide with few principles and many
consequences.) The precondition is that b is null or has been previously
returned by allocate(). This method is optional.
Great to see this primitive. Classic malloc-ators are so lame...
(+ WinAPI Heaps fits here)
expand is nice, but I don't like minDelta and maxDelta as arguments. On
a shared allocator this can lead to undesired side-effects, i.e. when
this function is called concurrently on the same block by two threads,
the net result will be the sum of the deltas of the two threads, while
later synchronization on the memory block might only allow one thread to
actually use the extended memory area. This can happen with gc_extend in
the current GC when appending to a shared array.
I'd prefer the function to actually pass the desired sizes:
void[] expand(void[] b, size_t minSize, size_t maxSize);
I don't understand this argument. These parameters can be trivially
computed from the others, after which locking etc. proceeds just the same.
FWIW I chose the "delta"-based signature because with it the
precondition is:
assert(minDelta <= maxDelta);
In fact behavior can be easily defined at no cost even if this
precondition is not satisfied. With the "absolute"-based signature the
precondition is:
assert(minSize <= maxSize && b.length <= minSize);
which causes confusion - people will pass small sizes to expand()
expecting it to contract, something that expand() can't support as a
matter of principle (safety!!!).
Andrei