On 28/07/2013 12:00 a.m., Kinkie wrote:
Here is the use case I am thinking about:
sbuf.reserveSpace(ioSize);
bytesRead = read(sbuf.rawSpace(), ioSize);
sbuf.forceSize(sbuf.size() + bytesRead);
This explains it all, we're thinking about two different use cases.
The other use case is:
sbuf.reserveCapacity(newCapacity);
sbuf.append(something).append(somethingelse).append(verylongstring).append(whoknows).
This could be used e.g. to instantiate error pages from their
templates (pseudo-code):
Sbuf template(.....);
Sbuf errorpage;
errorpage.reserveCapacity(template * reasonable_scaling_factor);
SBufTokenizer t(template);
while (SBuf parsed=t.nextToken("%")) {
errorpage.append(parsed).append(handleCode(t.peek());
}
errorpage.append(t.whatever_remains());
In cases such as this it may not be needed to cow(), so why do it?
The above case is already handled by rawSpace(), but now I am confused
why rawSpace() is implemented using unconditional cow() while
reserveSpace() appears to be optimizing something. That optimization
seems to be the key here. Perhaps rawSpace() should be deleted and
reserveCapacity() adjusted to use the same optimization?
reserveSpace(n) ought to be reserveCapacity(content size + n)
Apart from this, I see the benefit of Amos' suggestion of having
rawSpace also absorb the function of reserveCapacity.
This also covers you observation that both reserveSpace and rawSpace
are maybe not needed, one can do the job of both.
No. I think what Alex is getting at is that they *do* have potential
uses but those uses have very different semantic requirements, from each
other and from what some (one?) of them do right now.
There is a case for each of them:
reserveCapacity(size) - in code needing and being able to hint a
specific total capacity (minimum) to exist in the buffer.
reserveSpace(size) - in code which only knows how much is going to
be _added_, to simplify the caller code. This can therefore be an inline
wrapper for reserveCapacity(currentSize+newSize).
* both of the above are about optimizing cow() and ensuring extra
space is available. Nothing more.
rawSpace() - in code needing to play with the raw buffer for some reason.
Adding size to rawSpace() adds the multiple benefits of not needing to
explicitly run reserve*(), thus preventing mistakes with selecting
_which_ reserve*(), enforcing that the space available is guaranteed to
be a fixed known size in advance of that use, thus nobody can play with
the buffer directly unless they know how much of it they will be playing
with or at least can (over-)estimate an amount.
Amos