refactor(mt): move input-range commit policy to Rust
Move the ready/wrap branch and synchronization ordering from ZSTDMT_tryGetInputRange into Rust. The Rust policy now waits for the prefix range, invokes the C-owned prefix move, waits for the selected source range, and publishes the buffer; C retains memmove, private buffer fields, round-buffer state, and LDM callbacks behind the projection. Add ABI assertions and focused wrapped/ordinary ordering tests. Test Plan: git diff --cached --check; focused Rust tests added; full capped Rust/native/original-suite verification follows.
This commit is contained in:
@@ -957,6 +957,19 @@ typedef struct {
|
||||
size_t bufferCapacity;
|
||||
size_t roundBufferPos;
|
||||
} ZSTDMT_RustTryGetInputRangeResult;
|
||||
typedef char ZSTDMT_rust_try_get_input_range_result_layout[
|
||||
(offsetof(ZSTDMT_RustTryGetInputRangeResult, ready) == 0
|
||||
&& offsetof(ZSTDMT_RustTryGetInputRangeResult, movePrefix)
|
||||
== sizeof(unsigned)
|
||||
&& offsetof(ZSTDMT_RustTryGetInputRangeResult, bufferStart)
|
||||
== 2 * sizeof(unsigned)
|
||||
&& offsetof(ZSTDMT_RustTryGetInputRangeResult, bufferCapacity)
|
||||
== 2 * sizeof(unsigned) + sizeof(void*)
|
||||
&& offsetof(ZSTDMT_RustTryGetInputRangeResult, roundBufferPos)
|
||||
== 2 * sizeof(unsigned) + sizeof(void*) + sizeof(size_t)
|
||||
&& sizeof(ZSTDMT_RustTryGetInputRangeResult)
|
||||
== 2 * sizeof(unsigned) + sizeof(void*) + 2 * sizeof(size_t))
|
||||
? 1 : -1];
|
||||
typedef void (*ZSTDMT_jobProjectionFn)(void* opaque, unsigned jobID,
|
||||
ZSTDMT_RustJobProjection* projection);
|
||||
ZSTDMT_RustInputRange ZSTDMT_rust_getInputDataInUse(
|
||||
@@ -965,6 +978,19 @@ ZSTDMT_RustInputRange ZSTDMT_rust_getInputDataInUse(
|
||||
void* opaque, ZSTDMT_jobProjectionFn projectJob);
|
||||
ZSTDMT_RustTryGetInputRangeResult ZSTDMT_rust_tryGetInputRange(
|
||||
const ZSTDMT_RustTryGetInputRangeProjection* projection);
|
||||
typedef void (*ZSTDMT_inputRangeWaitFn)(
|
||||
void* opaque, void* bufferStart, size_t bufferCapacity);
|
||||
typedef void (*ZSTDMT_inputRangeMovePrefixFn)(
|
||||
void* opaque, void* destination, const void* source, size_t size,
|
||||
size_t roundBufferPos);
|
||||
typedef void (*ZSTDMT_inputRangePublishBufferFn)(
|
||||
void* opaque, void* bufferStart, size_t bufferCapacity);
|
||||
int ZSTDMT_rust_commitInputRange(
|
||||
const ZSTDMT_RustTryGetInputRangeResult* result,
|
||||
void* roundBufferStart, const void* prefixStart, size_t prefixSize,
|
||||
void* opaque, ZSTDMT_inputRangeWaitFn waitForLdm,
|
||||
ZSTDMT_inputRangeMovePrefixFn movePrefix,
|
||||
ZSTDMT_inputRangePublishBufferFn publishBuffer);
|
||||
size_t ZSTDMT_rust_toFlushNow(unsigned doneJobID, unsigned nextJobID,
|
||||
unsigned jobIDMask, void* opaque,
|
||||
ZSTDMT_jobProjectionFn projectJob);
|
||||
@@ -3296,6 +3322,43 @@ static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, Buffer buffer)
|
||||
ZSTDMT_rust_waitForLdmComplete(&state);
|
||||
}
|
||||
|
||||
static void ZSTDMT_inputRangeWaitForLdm(
|
||||
void* opaque, void* bufferStart, size_t bufferCapacity)
|
||||
{
|
||||
ZSTDMT_waitForLdmComplete((ZSTDMT_CCtx*)opaque,
|
||||
(Buffer){ bufferStart, bufferCapacity });
|
||||
}
|
||||
|
||||
static void ZSTDMT_inputRangeMovePrefix(
|
||||
void* opaque, void* destination, const void* source, size_t size,
|
||||
size_t roundBufferPos)
|
||||
{
|
||||
ZSTDMT_CCtx* const mtctx = (ZSTDMT_CCtx*)opaque;
|
||||
/* ZSTD_invalidateRepCodes() doesn't work for extDict variants.
|
||||
* Simply copy the prefix to the beginning in that case. */
|
||||
ZSTD_memmove(destination, source, size);
|
||||
mtctx->inBuff.prefix.start = (const BYTE*)destination;
|
||||
mtctx->roundBuff.pos = roundBufferPos;
|
||||
}
|
||||
|
||||
static void ZSTDMT_inputRangePublishBuffer(
|
||||
void* opaque, void* bufferStart, size_t bufferCapacity)
|
||||
{
|
||||
ZSTDMT_CCtx* const mtctx = (ZSTDMT_CCtx*)opaque;
|
||||
Buffer const buffer = { bufferStart, bufferCapacity };
|
||||
|
||||
DEBUGLOG(5, "Using prefix range [%zx, %zx)",
|
||||
(size_t)mtctx->inBuff.prefix.start,
|
||||
(size_t)mtctx->inBuff.prefix.start + mtctx->inBuff.prefix.size);
|
||||
DEBUGLOG(5, "Using source range [%zx, %zx)",
|
||||
(size_t)buffer.start,
|
||||
(size_t)buffer.start + buffer.capacity);
|
||||
|
||||
mtctx->inBuff.buffer = buffer;
|
||||
mtctx->inBuff.filled = 0;
|
||||
assert(mtctx->roundBuff.pos + buffer.capacity <= mtctx->roundBuff.capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to set the inBuff to the next section to fill.
|
||||
* If any part of the new section is still in use we give up.
|
||||
@@ -3316,47 +3379,22 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
||||
};
|
||||
ZSTDMT_RustTryGetInputRangeResult const result =
|
||||
ZSTDMT_rust_tryGetInputRange(&projection);
|
||||
Buffer buffer;
|
||||
|
||||
DEBUGLOG(5, "ZSTDMT_tryGetInputRange");
|
||||
assert(mtctx->inBuff.buffer.start == NULL);
|
||||
|
||||
if (!result.ready) {
|
||||
if (!ZSTDMT_rust_commitInputRange(
|
||||
&result,
|
||||
mtctx->roundBuff.buffer,
|
||||
mtctx->inBuff.prefix.start,
|
||||
mtctx->inBuff.prefix.size,
|
||||
mtctx,
|
||||
ZSTDMT_inputRangeWaitForLdm,
|
||||
ZSTDMT_inputRangeMovePrefix,
|
||||
ZSTDMT_inputRangePublishBuffer)) {
|
||||
DEBUGLOG(5, "Waiting for buffer...");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (result.movePrefix) {
|
||||
/* ZSTD_invalidateRepCodes() doesn't work for extDict variants.
|
||||
* Simply copy the prefix to the beginning in that case.
|
||||
*/
|
||||
BYTE* const start = (BYTE*)mtctx->roundBuff.buffer;
|
||||
size_t const prefixSize = mtctx->inBuff.prefix.size;
|
||||
|
||||
buffer.start = start;
|
||||
buffer.capacity = prefixSize;
|
||||
ZSTDMT_waitForLdmComplete(mtctx, buffer);
|
||||
ZSTD_memmove(start, mtctx->inBuff.prefix.start, prefixSize);
|
||||
mtctx->inBuff.prefix.start = start;
|
||||
mtctx->roundBuff.pos = result.roundBufferPos;
|
||||
}
|
||||
|
||||
buffer.start = (BYTE*)result.bufferStart;
|
||||
buffer.capacity = result.bufferCapacity;
|
||||
|
||||
ZSTDMT_waitForLdmComplete(mtctx, buffer);
|
||||
|
||||
DEBUGLOG(5, "Using prefix range [%zx, %zx)",
|
||||
(size_t)mtctx->inBuff.prefix.start,
|
||||
(size_t)mtctx->inBuff.prefix.start + mtctx->inBuff.prefix.size);
|
||||
DEBUGLOG(5, "Using source range [%zx, %zx)",
|
||||
(size_t)buffer.start,
|
||||
(size_t)buffer.start + buffer.capacity);
|
||||
|
||||
|
||||
mtctx->inBuff.buffer = buffer;
|
||||
mtctx->inBuff.filled = 0;
|
||||
assert(mtctx->roundBuff.pos + buffer.capacity <= mtctx->roundBuff.capacity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user