This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 4d9a7573edb HDDS-14673. Implement ScmEnumCodec without reflection.
(#9843)
4d9a7573edb is described below
commit 4d9a7573edb06021403e74ef610331d63ddf6778
Author: Russole <[email protected]>
AuthorDate: Sun Mar 1 02:48:48 2026 +0800
HDDS-14673. Implement ScmEnumCodec without reflection. (#9843)
---
.../hadoop/hdds/scm/ha/io/ScmCodecFactory.java | 16 ++++++-
.../apache/hadoop/hdds/scm/ha/io/ScmEnumCodec.java | 49 +++++++++++++++-------
2 files changed, 47 insertions(+), 18 deletions(-)
diff --git
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmCodecFactory.java
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmCodecFactory.java
index 4eecffcbea0..68e33ebd7b6 100644
---
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmCodecFactory.java
+++
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmCodecFactory.java
@@ -24,7 +24,11 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.IntFunction;
import org.apache.commons.lang3.ClassUtils;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleEvent;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeType;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.PipelineState;
import org.apache.hadoop.hdds.security.symmetric.ManagedSecretKey;
import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
import
org.apache.ratis.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
@@ -35,12 +39,11 @@
*/
public final class ScmCodecFactory {
- private static Map<Class<?>, ScmCodec> codecs = new HashMap<>();
+ private static Map<Class<?>, ScmCodec<?>> codecs = new HashMap<>();
static {
codecs.put(com.google.protobuf.Message.class, new
ScmNonShadedGeneratedMessageCodec());
codecs.put(Message.class, new ScmGeneratedMessageCodec());
- codecs.put(ProtocolMessageEnum.class, new ScmEnumCodec());
codecs.put(List.class, new ScmListCodec());
codecs.put(Integer.class, new ScmIntegerCodec());
codecs.put(Long.class, new ScmLongCodec());
@@ -51,6 +54,15 @@ public final class ScmCodecFactory {
codecs.put(com.google.protobuf.ByteString.class, new
ScmNonShadedByteStringCodec());
codecs.put(ByteString.class, new ScmByteStringCodec());
codecs.put(ManagedSecretKey.class, new ScmManagedSecretKeyCodec());
+
+ putEnum(LifeCycleEvent.class, LifeCycleEvent::forNumber);
+ putEnum(PipelineState.class, PipelineState::forNumber);
+ putEnum(NodeType.class, NodeType::forNumber);
+ }
+
+ static <T extends Enum<T> & ProtocolMessageEnum> void putEnum(
+ Class<T> enumClass, IntFunction<T> forNumber) {
+ codecs.put(enumClass, new ScmEnumCodec<>(enumClass, forNumber));
}
private ScmCodecFactory() { }
diff --git
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmEnumCodec.java
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmEnumCodec.java
index 9f33060f762..33849f3783b 100644
---
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmEnumCodec.java
+++
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/io/ScmEnumCodec.java
@@ -19,35 +19,52 @@
import com.google.common.primitives.Ints;
import com.google.protobuf.ProtocolMessageEnum;
-import java.lang.reflect.InvocationTargetException;
-import org.apache.hadoop.hdds.scm.ha.ReflectionUtil;
+import java.util.function.IntFunction;
+import org.apache.hadoop.hdds.StringUtils;
import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
import
org.apache.ratis.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
import org.apache.ratis.thirdparty.com.google.protobuf.UnsafeByteOperations;
+import org.apache.ratis.util.Preconditions;
/**
- * {@link ScmCodec} for {@link ProtocolMessageEnum} objects.
+ * {@link ScmCodec} for protobuf {@link ProtocolMessageEnum} objects.
+ * Stores protobuf enum number (wire value) and restores via number lookup.
*/
-public class ScmEnumCodec implements ScmCodec<Object> {
+class ScmEnumCodec<T extends Enum<T> & ProtocolMessageEnum> implements
ScmCodec<T> {
+ private final Class<T> enumClass;
+ private final IntFunction<T> forNumber;
+
+ ScmEnumCodec(Class<T> enumClass, IntFunction<T> forNumber) {
+ Preconditions.assertTrue(enumClass.isEnum());
+ for (T constant : enumClass.getEnumConstants()) {
+ Preconditions.assertSame(constant,
forNumber.apply(constant.getNumber()), "constant");
+ }
+
+ this.enumClass = enumClass;
+ this.forNumber = forNumber;
+ }
@Override
- public ByteString serialize(Object object)
- throws InvalidProtocolBufferException {
- // toByteArray returns a new array
- return
UnsafeByteOperations.unsafeWrap(Ints.toByteArray(((ProtocolMessageEnum)
object).getNumber()));
+ public ByteString serialize(T object) {
+ return
UnsafeByteOperations.unsafeWrap(Ints.toByteArray(object.getNumber()));
}
@Override
- public Object deserialize(Class<?> type, ByteString value)
- throws InvalidProtocolBufferException {
+ public T deserialize(Class<?> type, ByteString value) throws
InvalidProtocolBufferException {
+ final int n;
try {
- return ReflectionUtil.getMethod(type, "valueOf", int.class)
- .invoke(null, Ints.fromByteArray(
- value.toByteArray()));
- } catch (NoSuchMethodException | IllegalAccessException
- | InvocationTargetException ex) {
+ n = Ints.fromByteArray(value.toByteArray());
+ } catch (Exception e) {
+ throw new InvalidProtocolBufferException(
+ "Failed to deserialize enum " + enumClass + ": "
+ + StringUtils.bytes2String(value.asReadOnlyByteBuffer()), e);
+ }
+
+ final T decoded = forNumber.apply(n);
+ if (decoded == null) {
throw new InvalidProtocolBufferException(
- "Message cannot be decoded!" + ex.getMessage());
+ "Unknown enum number for " + enumClass.getName() + ": " + n);
}
+ return decoded;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]