HyukjinKwon commented on code in PR #59198:
URL: https://github.com/apache/spark/pull/59198#discussion_r4166090199


##########
common/unsafe/src/main/java/org/apache/spark/unsafe/types/UTF8String.java:
##########
@@ -821,8 +808,36 @@ public UTF8String toUpperCase() {
     return isFullAscii() ? toUpperCaseAscii() : toUpperCaseSlow();
   }
 
+  /**
+   * Returns the upper case of this ASCII string. The caller must ensure the 
string is full
+   * ASCII; the normal entry points reach this only after {@link 
#isFullAscii()} returns true.
+   *
+   * The result array is allocated lazily, only once a byte actually changes 
case: a string
+   * that is already upper case returns {@code this} with no allocation. 
Because upper-casing
+   * ASCII stays ASCII, the result is tagged full ASCII so later operations 
can skip re-scanning.
+   */
   public UTF8String toUpperCaseAscii() {
-    return convertAscii(Character::toUpperCase);
+    assert isFullAscii();
+    byte[] bytes = null;
+    for (int i = 0; i < numBytes; i++) {
+      byte b = getByte(i);
+      byte upper = (b >= 'a' && b <= 'z') ? (byte) (b - 32) : b;
+      if (upper != b && bytes == null) {
+        // First byte to change case: allocate the result and copy the clean 
prefix [0, i).
+        bytes = new byte[numBytes];
+        copyMemory(base, offset, bytes, BYTE_ARRAY_OFFSET, i);

Review Comment:
   **Nit (P3):** This new lazy-allocation branch bulk-copies the 
already-correct prefix `[0, i)` with `copyMemory` before the first 
case-changing byte, but no deterministic test exercises it with a non-empty 
prefix. `UTF8StringSuite.upperAndLower` only uses full-flip ASCII inputs 
(`ABCXYZ`/`abcxyz`, first change at index 0, so the prefix length is always 0) 
and non-ASCII inputs that take the slow path, and 
`UTF8StringPropertyCheckSuite` generates full-Unicode strings that essentially 
never land on the ASCII fast path. A future off-by-one or wrong-offset 
regression in this prefix copy would silently corrupt `lower()`/`upper()` 
output for the common mixed-case input (e.g. `toUpperCase("ABCdef")`) with no 
failing assertion. Consider adding a one-line assertion for a full-ASCII string 
whose first case-changing byte is past index 0, for both methods -- e.g. 
`assertEquals(fromString("ABCDEF"), fromString("ABCdef").toUpperCase())` and 
its lowercase mirror.
   
   **Verification:**
   - **Regression:** A unit assertion that corrupting the preserved clean 
prefix (wrong copy length/offset) would fail: for an ASCII input such as an 
already-uppercase prefix + lowercase suffix, toUpperCase returns the full 
uppercase string, and the lowercase mirror holds.



-- 
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]

Reply via email to