mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Allow arbitary InOut filters to be chained in IoFilterGroup.
If InOut filters were placed next to each other then the second filter would never get a NULL input signaling it to flush. This arrangement only worked if the second filter had some other indication that it should flush, such as a decompression filter where the flush is indicated in the input stream. This is not a live issue because currently no InOut filters are chained together.
This commit is contained in:
parent
838cfa44b7
commit
410a04a58e
@ -39,6 +39,10 @@
|
||||
<p>Add <code>IoFilter</code> interface to <code>CipherBlock</code> object.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Allow arbitary <code>InOut</code> filters to be chained in <code>IoFilterGroup</code>.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-contributor id="cynthia.shang"/>
|
||||
|
@ -254,6 +254,20 @@ ioFilterGroupProcess(IoFilterGroup *this, const Buffer *input, Buffer *output)
|
||||
// Keep processing while the filter is not done or there is input
|
||||
if (!ioFilterDone(filterData->filter) || filterData->input != NULL)
|
||||
{
|
||||
// If we are flushing and the prior filter is done and is not producing any more output then this filter should
|
||||
// be flushing as well. Set filterData->input = NULL so it knows there is no more input coming.
|
||||
//
|
||||
// If the filter is already done then there is no need to set input to NULL because it has already flushed and
|
||||
// the filter shouldn't need to hand NULL input if it doesn't need it to know when to flush.
|
||||
//
|
||||
// Checking filterIdx - 1 is safe because the first filter's filterData->input is always set to NULL when input
|
||||
// is NULL.
|
||||
if (input == NULL && filterData->input != NULL && !ioFilterDone(filterData->filter) &&
|
||||
ioFilterDone(ioFilterGroupGet(this, filterIdx - 1)->filter) && bufUsed(filterData->input) == 0)
|
||||
{
|
||||
filterData->input = NULL;
|
||||
}
|
||||
|
||||
ioFilterProcessInOut(filterData->filter, filterData->input, filterData->output);
|
||||
|
||||
// If inputSame is set then the output buffer for this filter is full and it will need to be pre-processed with
|
||||
@ -262,7 +276,7 @@ ioFilterGroupProcess(IoFilterGroup *this, const Buffer *input, Buffer *output)
|
||||
this->inputSame = true;
|
||||
|
||||
// Else clear the buffer if it was locally allocated. If this is an input buffer that was passed in then the
|
||||
// caller is reponsible for clearing it.
|
||||
// caller is responsible for clearing it.
|
||||
else if (filterData->inputLocal != NULL)
|
||||
bufUsedZero(filterData->inputLocal);
|
||||
}
|
||||
|
@ -416,6 +416,9 @@ testRun(void)
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioSizeFilter(sizeFilter)), " add filter to filter group");
|
||||
TEST_RESULT_VOID(
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("double", 2, 3, 'X')->filter), " add filter to filter group");
|
||||
TEST_RESULT_VOID(
|
||||
ioFilterGroupAdd(filterGroup, ioTestFilterMultiplyNew("single", 1, 1, 'Y')->filter),
|
||||
" add filter to filter group");
|
||||
TEST_RESULT_VOID(ioFilterGroupAdd(filterGroup, ioTestFilterSizeNew("size2")->filter), " add filter to filter group");
|
||||
TEST_RESULT_VOID(ioWriteFilterGroupSet(ioBufferWriteIo(bufferWrite), filterGroup), " add filter group to write io");
|
||||
|
||||
@ -436,12 +439,12 @@ testRun(void)
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ112233445", " check write");
|
||||
|
||||
TEST_RESULT_VOID(ioWriteClose(ioBufferWriteIo(bufferWrite)), " close buffer write object");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ1122334455XXX", " check write after close");
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "AABB\n\nZZ1122334455XXXY", " check write after close");
|
||||
|
||||
TEST_RESULT_PTR(ioWriteFilterGroup(ioBufferWriteIo(bufferWrite)), filterGroup, " check filter group");
|
||||
TEST_RESULT_UINT(
|
||||
varUInt64(ioFilterGroupResult(filterGroup, ioFilterType(ioSizeFilter(sizeFilter)))), 9, " check filter result");
|
||||
TEST_RESULT_UINT(varUInt64(ioFilterGroupResult(filterGroup, strNew("size2"))), 21, " check filter result");
|
||||
TEST_RESULT_UINT(varUInt64(ioFilterGroupResult(filterGroup, strNew("size2"))), 22, " check filter result");
|
||||
|
||||
TEST_RESULT_VOID(ioBufferWriteFree(bufferWrite), " free buffer write object");
|
||||
TEST_RESULT_VOID(ioBufferWriteFree(NULL), " free NULL buffer write object");
|
||||
|
Loading…
Reference in New Issue
Block a user