apache / apache/rocketmq

[Enhancement] Reduce allocation in ExtraInfoUtil POP info parsing and return primitives from numeric getters

Open
#10,973 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
22.6k
Forks
12k
Avg merge
3d 1h
Merged PRs (30d)
27

Description

### Before Creating the Enhancement Request

- [x] I have confirmed that this should be classified as an enhancement rather than a bug/feature.

### Summary

Reduce per-request allocation in `ExtraInfoUtil`: parse POP `startOffsetInfo` / `msgOffsetInfo` / `orderCountInfo` without the intermediate `split` arrays, and return primitives from the numeric extraInfo getters.

### Motivation

Every POP response and every ACK goes through `ExtraInfoUtil`:

1. `parseStartOffsetInfo` / `parseMsgOffsetInfo` / `parseOrderCountInfo` split each entry with `one.split(KEY_SEPARATOR)` (a `String[]` plus three substrings per entry) and re-concatenate the first two fields into a map key; `parseMsgOffsetInfo` additionally splits the offset list with `split(",")`.
2. `getCkQueueOffset` / `getPopTime` / `getInvisibleTime` return boxed `Long` although every caller in the repository immediately assigns the result to a `long` (broker ACK/changeInvisibleTime paths, client batch-ack path, proxy `LocalMessageService`).

### Solution

- Walk each entry with `indexOf` instead of `split`: no intermediate array, and the map key is built with `StringBuilder.append(CharSequence, int, int)` without substrings. The value field keeps one substring for `parseLong` (Java 8 target has no range-parse API).
- Change the three getters to return `long` (`Long.parseLong` instead of `Long.valueOf`). This is source-compatible for all in-repo callers (none rely on nullability or identity); it is binary-incompatible for externally compiled bytecode, which needs a recompile.
- Behavior note: the previous split-based validation half-accepted corrupt entries with empty fields or trailing separators (producing keys like `"@a"`); the new validation rejects them with the same `IllegalArgumentException` used for other malformed shapes. Well-formed wire strings produced by the builders are unaffected, covered by new round-trip tests.

### Verification

- `ExtraInfoUtilTest` extended with round-trip (normal + retry topic, multi-entry), getter, and malformed-input cases; 5/5 pass. `AckMessageProcessorTest` / `ChangeInvisibleTimeProcessorTest` / `PopMessageProcessorTest` 25/25, `MQClientAPIImplTest` 133/133.
- 4-node cluster A/B in POP mode (`mqadmin setConsumeMode -m POP`, producer 64 threads + consumer 20 threads, consume TPS steady at 150–154k, 3 interleaved trials per side):
- broker side (remoting jar swapped on broker): young GC per million consumed msgs 2.60/2.62/2.70 (base) vs 2.63/2.64/2.62 (patch) — parity;
- client side (remoting jar swapped on consumer): 1.10/1.08/1.10 vs 1.11/1.10/1.10 — parity.
No regression on either side; the allocation saving itself (tens of bytes per response) is below GC-count resolution, so this is submitted as a cleanup-level optimization on a hot path.

Contributor guide

Open the contributing guide

Research direction

Start in ExtraInfoUtil and trace parseStartOffsetInfo, parseMsgOffsetInfo, parseOrderCountInfo, and the three numeric getters. Read the extended ExtraInfoUtilTest round-trip and malformed-input cases first, then run it with AckMessageProcessorTest, ChangeInvisibleTimeProcessorTest, PopMessageProcessorTest, and MQClientAPIImplTest. Done means the listed tests pass while preserving well-formed POP behavior and reducing the described temporary allocations.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, performance
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.