Skip to content

HDDS-14673. Implement ScmEnumCodec without reflection.#9843

Merged
szetszwo merged 9 commits intoapache:masterfrom
Russole:HDDS-14673
Feb 28, 2026
Merged

HDDS-14673. Implement ScmEnumCodec without reflection.#9843
szetszwo merged 9 commits intoapache:masterfrom
Russole:HDDS-14673

Conversation

@Russole
Copy link
Contributor

@Russole Russole commented Feb 27, 2026

What changes were proposed in this pull request?

  • Remove the generic ProtocolMessageEnum handling from ScmCodecFactory.
  • Add ScmCodec implementations for the following protobuf enums:
    • HddsProtos.PipelineState
    • HddsProtos.LifeCycleEvent
    • HddsProtos.NodeType
  • Register the above enum codecs explicitly in ScmCodecFactory.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-14673

How was this patch tested?

@Russole
Copy link
Contributor Author

Russole commented Feb 27, 2026

Hi @szetszwo, could you please help review this PR when you have time? Thanks!

Copy link
Contributor

@szetszwo szetszwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Russole , thanks a lot for spending time on finding out all the required enums!

We may change ScmEnumCodec to support generic enums; see https://issues.apache.org/jira/secure/attachment/13080998/9843_review.patch

@szetszwo szetszwo changed the title HDDS-14673. Check if ScmEnumCodec is needed. HDDS-14673. Implement ScmEnumCodec without reflection. Feb 27, 2026
@Russole
Copy link
Contributor Author

Russole commented Feb 28, 2026

Thanks @szetszwo for the review. I’ve updated the changes based on the comments.

@Russole Russole requested a review from szetszwo February 28, 2026 01:12
Copy link
Contributor

@szetszwo szetszwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 the change looks good.

@Russole
Copy link
Contributor Author

Russole commented Feb 28, 2026

Hi @szetszwo.I’ve updated the patch to fix the enum deserialization logic in ScmEnumCodec.

Previously we decoded using the enum ordinal (values[n]), but we serialize protobuf enums with getNumber(), so this could map to the wrong value. The new implementation restores the correct semantics by looking up enum constants by protobuf number (via a prebuilt number -> enum map), and keeps the same wire format.

Could you please take another look when you have time? Thanks!

@Russole Russole requested a review from szetszwo February 28, 2026 12:06
Copy link
Contributor

@szetszwo szetszwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Russole , thanks for catching the bug of using values array! You are right that we should use protobuf enum number.

Please see the comments inlined and also https://issues.apache.org/jira/secure/attachment/13081015/9843_review2.patch

public final class ScmCodecFactory {

private static Map<Class<?>, ScmCodec> codecs = new HashMap<>();
private static final Map<Class<?>, ScmCodec<?>> CODECS = new HashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that I added final in my last review. Let's do it later in order to avoid renaming.

public class ScmEnumCodec implements ScmCodec<Object> {
class ScmEnumCodec<T extends Enum<T> & ProtocolMessageEnum> implements ScmCodec<T> {
private final Class<T> enumClass;
private final Map<Integer, T> byNumber = new HashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pass the forNumber method:

  private final Class<T> enumClass;
  private final IntFunction<T> forNumber;

  ScmEnumCodec(Class<T> enumClass, IntFunction<T> forNumber) {
    Preconditions.assertTrue(enumClass.isEnum(), () -> "Not an enum: " + enumClass);
    for (T constant : enumClass.getEnumConstants()) {
      Preconditions.assertSame(constant, forNumber.apply(constant.getNumber()), "constant");
    }

    this.enumClass = enumClass;
    this.forNumber = forNumber;
  }

+ StringUtils.bytes2String(value.asReadOnlyByteBuffer()), e);
}

final T decoded = byNumber.get(n);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use forNumber:

    final T decoded = forNumber.apply(n);

@Russole
Copy link
Contributor Author

Russole commented Feb 28, 2026

Thanks @szetszwo for the comments. I’ve updated the changes accordingly.

@Russole Russole requested a review from szetszwo February 28, 2026 15:31
Copy link
Contributor

@szetszwo szetszwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 the change looks good.

@szetszwo szetszwo merged commit 4d9a757 into apache:master Feb 28, 2026
86 of 87 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants