rich7420 opened a new pull request, #11112:
URL: https://github.com/apache/ozone/pull/11112

   ## What changes were proposed in this pull request?
   
   `StringCodecBase` (the base of `StringCodec` and `FixedLengthStringCodec`) 
allocates a fresh `CharsetEncoder` on every encode and a fresh `CharsetDecoder` 
on every decode:
   
   - `encode(...)` -> `newEncoder().encode(...)`
   - `decodeNoFallback(...)` / `decodeWithFallback(...)` -> 
`newDecoder().decode(...)`
   
   These codecs are singletons on a hot path: every `String` RocksDB key/value 
(OM/SCM tables, iterators, compaction) is serialized/deserialized through them, 
so a short-lived coder is created on each call.
   
   `CharsetEncoder`/`CharsetDecoder` are stateful and not thread-safe, so this 
caches one per thread (`ThreadLocal`) and reuses it:
   
   - the encoder is `reset()` before each use, because the 3-arg `encode(in, 
out, endOfInput)` does not reset on its own;
   - the decoder uses the single-arg `CharsetDecoder.decode(ByteBuffer)`, which 
resets internally (per its javadoc), so no explicit reset is added there.
   
   The cache is per codec instance rather than `static`, because subclasses use 
different charsets. `reset()` only clears coding state and keeps 
`onMalformedInput`/`onUnmappableCharacter(REPORT)`, so behavior is unchanged.
   
   ## What is the link to the Apache JIRA
   
   https://issues.apache.org/jira/browse/HDDS-16277
   
   ## How was this patch tested?
   
   The change is behavior-preserving, so the existing codec tests are the 
regression gate. They exercise repeated encode/decode over the singleton codecs 
(which now go through the reused coder), malformed-input reporting, and 
multi-byte rejection:
   
   ```
   mvn -pl hadoop-hdds/framework test 
-Dtest=TestCodec,TestFixedLengthStringCodec
   Tests run: 8, Failures: 0, Errors: 0, Skipped: 0 -- in 
org.apache.hadoop.hdds.utils.db.TestCodec
   Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 -- in 
org.apache.hadoop.hdds.utils.db.TestFixedLengthStringCodec
   ```
   
   checkstyle, pmd and findbugs are green on the fork CI run.
   
   ### Microbenchmark
   
   JMH (out of tree), JDK 21, single thread, `fork=2`. Both variants run the 
identical encode/decode and differ only in coder acquisition (fresh vs. reused 
per thread), so the delta is attributable to this change. `gc.alloc.rate.norm` 
error is +/- 0.001 B/op, i.e. the per-call allocation is exact.
   
   Encode:
   
   | input | ns/op (old -> new) | B/op (old -> new) |
   | --- | --- | --- |
   | `/vol1/bucket1/dir1/dir2/object-file-000000123.dat` | 81.7 -> 66.3 (-19%) 
| 208 -> 112 (-96 B, -46%) |
   | `8f14e45f-ceea-467a-9d1b-2f3c4d5e6f70` | 58.7 -> 53.6 (-9%) | 208 -> 112 
(-96 B, -46%) |
   
   Decode:
   
   | input | ns/op (old -> new) | B/op (old -> new) |
   | --- | --- | --- |
   | `/vol1/bucket1/dir1/dir2/object-file-000000123.dat` | 29.5 -> 25.5 (-14%) 
| 368 -> 328 (-40 B, -11%) |
   | `8f14e45f-ceea-467a-9d1b-2f3c4d5e6f70` | 28.7 -> 26.5 (-8%) | 320 -> 280 
(-40 B, -13%) |
   
   Each encode drops one `CharsetEncoder` (96 B/op) and each decode one 
`CharsetDecoder` (40 B/op); encode allocation rate falls ~34-41%. The benchmark 
isolates the coder acquisition, so the absolute per-call savings carry over to 
the full `toPersistedFormat`/`fromPersistedFormat` path, while the percentage 
there is diluted by the surrounding buffer work.
   


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