HyukjinKwon commented on code in PR #59327:
URL: https://github.com/apache/spark/pull/59327#discussion_r4240452706
##########
core/src/main/scala/org/apache/spark/deploy/history/FsHistoryProvider.scala:
##########
@@ -1772,6 +1761,60 @@ private[history] class FsHistoryProvider(conf:
SparkConf, clock: Clock)
private[spark] object FsHistoryProvider {
+ /**
+ * Positions `in` at the start of the first line that begins at or after
byte `target`,
Review Comment:
**Nit (P3):** `in` itself isn't left at the line start. When a `\n` is
found, `in` has already been read up to 8 KiB past the boundary
(`in.read(buffer)`), and only the returned `SequenceInputStream(rest, in)`
starts at the line. "Bytes read past the boundary are put back in front of the
stream" is also ambiguous, because they are prepended only in the returned
stream, not pushed back into `in`.
The only caller uses the returned stream, but a future caller who trusts
this sentence and keeps reading `in` (for example the `tryWithResource` handle)
would silently lose up to 8 KiB of events. Something like this would be
clearer: "Returns a stream that starts at the first line beginning at or after
byte `target` of `in`, together with that line's byte offset. `in` itself is
consumed and must not be read afterwards; bytes read past the boundary are
prepended to the returned stream."
**Verification:**
- **Inspection:** The scaladoc no longer claims that `in` itself is
positioned at the line start, and its description of the returned stream, the
consumption of `in` and the non-positive-target case matches the implementation.
##########
core/src/test/scala/org/apache/spark/deploy/history/FsHistoryProviderSuite.scala:
##########
@@ -1248,6 +1248,142 @@ abstract class FsHistoryProviderSuite extends
SparkFunSuite with Matchers with P
}
}
+ test("end event reparse when the skip offset lands inside a multi-byte
character") {
+ val log = newLogFile("end-event-utf8", None, inProgress = false)
+ val bytes = writeRawLog(log, endEventTestLines("end-event-utf8",
+ jobStartLine(1, 0x4e2d.toChar.toString * 200)))
+ // The job description is written as raw UTF-8: skip to the second byte of
a character.
+ val leadByte = bytes.indexWhere(b => (b & 0xF0) == 0xE0)
+ assert(leadByte > 0)
+ val conf = createTestConf().set(END_EVENT_REPARSE_CHUNK_SIZE,
(bytes.length - leadByte - 1L))
Review Comment:
**Nit (P3):** With `bytes.length - leadByte - 1`, `target` is the second
byte of U+4E2D (E4 B8 AD), but `skipToLineStart` now skips only `target - 1`
bytes, so the raw scan starts on the lead byte E4, a character boundary. The
test still catches the original bug (skipping exactly `target` bytes and then
decoding). However, it would also pass with an alignment that decodes UTF-8
from `target - 1` before looking for `\n`, and that alignment fails whenever
`target - 1` is a continuation byte, which is exactly the case the raw-byte
scan is for.
Using `bytes.length - leadByte - 2` puts the target on the third byte, so
the scan starts on B8. With that change and an updated comment, this test would
cover a mid-character start. A couple of multi-byte cases in the
`skipToLineStart` unit test, with the target on each byte of a character, would
also pin this down at the helper level.
**Verification:**
- **Regression:** A completed log whose reparse offset falls inside a
multi-byte character, with the raw scan starting on a continuation byte, is
listed as completed, and a decode-before-scan alignment would make the test
fail.
- **Behavior:** skipToLineStart returns the first line starting at or after
the target, and its UTF-8 byte offset, for targets on the lead, second and
third byte of a 3-byte character.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]