Interface RecordSplitter
Implementations are used in two different contexts: stream-based planning code that skips forward to the next complete record, and byte-array chunking code that slices an already-read buffer at the last complete record.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final longReturned only byfindProvenRecordBoundary(InputStream)when a bounded probe cannot prove a record start within its convergence window (e.g.static final longReturned byfindNextRecordBoundary(InputStream)when a scanner exceedsmaxRecordBytes()before finding a record boundary. -
Method Summary
Modifier and TypeMethodDescriptiondefault intfindLastRecordBoundary(byte[] buf, int length) Returns the index of the byte that terminates the last complete record withinbuf[0..length), or-1if no complete record terminates inside that range.intfindLastRecordBoundary(byte[] buf, int offset, int length) Returns the index of the byte that terminates the last complete record withinbuf[offset..offset + length), or-1if no complete record terminates inside that range.longfindNextRecordBoundary(InputStream stream) Scans forward from the current stream position until the next complete record boundary.default longfindProvenRecordBoundary(InputStream stream) Probes for a proven record start starting from the current stream position (an arbitrary mid-file stride offset).default longfindRecordStartAtOrAfter(InputStream stream, long minSkip, BooleanSupplier isCancelled) Exact forward walk from a stream opened at a known record start, keeping cross-record parse state (e.g.intMaximum bytes a single record may occupy before the splitter reportsRECORD_TOO_LARGE.default booleanWhether this splitter can prove a record start at an arbitrary mid-file offset even though it is not strided (i.e.default booleanWhether it is safe to begin a boundary probe at an arbitrary mid-file offset (as the stride-based segmentation inFileSplitProviderandParallelParsingCoordinatordoes).
-
Field Details
-
RECORD_TOO_LARGE
static final long RECORD_TOO_LARGEReturned byfindNextRecordBoundary(InputStream)when a scanner exceedsmaxRecordBytes()before finding a record boundary. Distinct from EOF (-1).- See Also:
-
AMBIGUOUS
static final long AMBIGUOUSReturned only byfindProvenRecordBoundary(InputStream)when a bounded probe cannot prove a record start within its convergence window (e.g. a quote-free stretch where the in-quote hypothesis never closes, or a lookahead that would need a byte past the window). Distinct from EOF (-1) andRECORD_TOO_LARGE(-2): it means "undecided here, retry with the exact walk", not "no boundary" or "record too large". The exact walk (findRecordStartAtOrAfter(InputStream, long, BooleanSupplier)), not the probe, owns theRECORD_TOO_LARGEverdict because it always starts from a known record start.- See Also:
-
-
Method Details
-
findNextRecordBoundary
Scans forward from the current stream position until the next complete record boundary.- Returns:
- the number of bytes consumed,
-1if EOF is reached before a boundary, orRECORD_TOO_LARGEif the next record exceedsmaxRecordBytes() - Throws:
IOException
-
findLastRecordBoundary
Returns the index of the byte that terminates the last complete record withinbuf[offset..offset + length), or-1if no complete record terminates inside that range.When the range ends inside an open record, implementations must return the previous complete record boundary, not a byte inside the open tail. Implementations that enforce
maxRecordBytes()may return(int)RECORD_TOO_LARGEwhen no boundary was found and the open record already exceeds the cap, so callers fail fast instead of growing the buffer further.- Throws:
IOException
-
findLastRecordBoundary
Returns the index of the byte that terminates the last complete record withinbuf[0..length), or-1if no complete record terminates inside that range.- Throws:
IOException
-
maxRecordBytes
int maxRecordBytes()Maximum bytes a single record may occupy before the splitter reportsRECORD_TOO_LARGE. -
supportsStridedProbing
default boolean supportsStridedProbing()Whether it is safe to begin a boundary probe at an arbitrary mid-file offset (as the stride-based segmentation inFileSplitProviderandParallelParsingCoordinatordoes).This holds only when every record terminator is unambiguous from the byte immediately at it, i.e. a raw newline is always a true record boundary regardless of the state the scan started in. It is false for splitters whose grammar can carry a record across a raw newline (quoted fields with embedded newlines, bracketed multi-value cells): starting a probe inside such a construct misreads an in-construct newline as a terminator and desyncs the parse. Callers that get
falsemust not split at arbitrary offsets; they read the file as one sequential stream instead. -
supportsProvenProbing
default boolean supportsProvenProbing()Whether this splitter can prove a record start at an arbitrary mid-file offset even though it is not strided (i.e.supportsStridedProbing()isfalsebecause its grammar can carry a record across a raw newline). This is the second capability boolean on the SPI, orthogonal tosupportsStridedProbing(): a splitter that returnstruehere restores cross-node macro splitting for quoted/escaped text by running a boundedfindProvenRecordBoundary(InputStream)probe and falling back to a monotonicfindRecordStartAtOrAfter(InputStream, long, BooleanSupplier)exact walk, both of which yield only true record starts, so a split boundary is never cut inside a quoted field or an escaped newline.Callers must check this before calling
findProvenRecordBoundary(InputStream)orfindRecordStartAtOrAfter(InputStream, long, BooleanSupplier), exactly as they checksupportsStridedProbing()beforefindNextRecordBoundary(InputStream)on the strided path. -
findProvenRecordBoundary
Probes for a proven record start starting from the current stream position (an arbitrary mid-file stride offset). Returns the byte count consumed through the record terminator at which the probe proved a record start (mirroringfindNextRecordBoundary(InputStream)'sconsumedreturn, so the caller adds it to the stream's base offset), orAMBIGUOUSif it could not prove one within its bounded convergence window. Never returnsRECORD_TOO_LARGE: window exhaustion is alwaysAMBIGUOUS, deferring the cap verdict tofindRecordStartAtOrAfter(InputStream, long, BooleanSupplier).The default implementation throws so a splitter that advertises
supportsProvenProbing()but forgets to override this fails loud rather than silently delegating to a quote-unaware scan.- Throws:
IOException
-
findRecordStartAtOrAfter
default long findRecordStartAtOrAfter(InputStream stream, long minSkip, BooleanSupplier isCancelled) throws IOException Exact forward walk from a stream opened at a known record start, keeping cross-record parse state (e.g. in-quote) across records in a single pass, returning the stream-relative offset of the first record start at or afterminSkip.minSkipis stream-relative and always> 0, so the returned offset is strictly greater than the stream's base record start (never0). ReturnsRECORD_TOO_LARGEif a single record exceedsmaxRecordBytes()before a boundary, or-1at EOF before reachingminSkip.isCancelledis polled inside the byte loop so a long walk (a record up tomaxRecordBytes()) aborts promptly; a cancelled walk throwsTaskCancelledException. Read-time callers that do not carry a cancellable task pass() -> false.The default implementation throws so a splitter that advertises
supportsProvenProbing()but forgets to override this fails loud.- Throws:
IOException
-