You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by yu...@apache.org on 2017/08/29 12:30:44 UTC

[16/28] incubator-rocketmq git commit: [ROCKETMQ-259]Fix too many reflection calls when decode remoting command header

[ROCKETMQ-259]Fix too many reflection calls when decode remoting command header


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/f613c3b7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/f613c3b7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/f613c3b7

Branch: refs/heads/master
Commit: f613c3b7dfefc1cea15d8aa22fec763995a624e7
Parents: f091203
Author: yukon <yu...@apache.org>
Authored: Fri Aug 11 19:15:38 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Aug 11 22:14:56 2017 +0800

----------------------------------------------------------------------
 .../remoting/protocol/RemotingCommand.java      | 20 ++++++--------
 .../remoting/protocol/RemotingCommandTest.java  | 29 ++++++++++++++++++++
 2 files changed, 37 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/f613c3b7/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
index bee9b12..2f8cb38 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
@@ -43,7 +43,7 @@ public class RemotingCommand {
     private static final Map<Class, String> CANONICAL_NAME_CACHE = new HashMap<Class, String>();
     // 1, Oneway
     // 1, RESPONSE_COMMAND
-    private static final Map<Field, Annotation> NOT_NULL_ANNOTATION_CACHE = new HashMap<Field, Annotation>();
+    private static final Map<Field, Boolean> NULLABLE_FIELD_CACHE = new HashMap<Field, Boolean>();
     private static final String STRING_CANONICAL_NAME = String.class.getCanonicalName();
     private static final String DOUBLE_CANONICAL_NAME_1 = Double.class.getCanonicalName();
     private static final String DOUBLE_CANONICAL_NAME_2 = double.class.getCanonicalName();
@@ -252,11 +252,9 @@ public class RemotingCommand {
                         try {
                             String value = this.extFields.get(fieldName);
                             if (null == value) {
-                                Annotation annotation = getNotNullAnnotation(field);
-                                if (annotation != null) {
+                                if (!isFieldNullable(field)) {
                                     throw new RemotingCommandException("the custom field <" + fieldName + "> is null");
                                 }
-
                                 continue;
                             }
 
@@ -305,16 +303,14 @@ public class RemotingCommand {
         return field;
     }
 
-    private Annotation getNotNullAnnotation(Field field) {
-        Annotation annotation = NOT_NULL_ANNOTATION_CACHE.get(field);
-
-        if (annotation == null) {
-            annotation = field.getAnnotation(CFNotNull.class);
-            synchronized (NOT_NULL_ANNOTATION_CACHE) {
-                NOT_NULL_ANNOTATION_CACHE.put(field, annotation);
+    private boolean isFieldNullable(Field field) {
+        if (!NULLABLE_FIELD_CACHE.containsKey(field)) {
+            Annotation annotation = field.getAnnotation(CFNotNull.class);
+            synchronized (NULLABLE_FIELD_CACHE) {
+                NULLABLE_FIELD_CACHE.put(field, annotation == null);
             }
         }
-        return annotation;
+        return NULLABLE_FIELD_CACHE.get(field);
     }
 
     private String getCanonicalName(Class clazz) {

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/f613c3b7/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RemotingCommandTest.java
----------------------------------------------------------------------
diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RemotingCommandTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RemotingCommandTest.java
index e11915b..2bd41ce 100644
--- a/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RemotingCommandTest.java
+++ b/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RemotingCommandTest.java
@@ -16,8 +16,11 @@
  */
 package org.apache.rocketmq.remoting.protocol;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 import org.apache.rocketmq.remoting.CommandCustomHeader;
+import org.apache.rocketmq.remoting.annotation.CFNotNull;
 import org.apache.rocketmq.remoting.exception.RemotingCommandException;
 import org.junit.Test;
 
@@ -179,6 +182,32 @@ public class RemotingCommandTest {
         assertThat(((ExtFieldsHeader) decodedHeader).isBooleanValue()).isEqualTo(true);
         assertThat(((ExtFieldsHeader) decodedHeader).getDoubleValue()).isBetween(0.617, 0.619);
     }
+
+    @Test
+    public void testNotNullField() throws Exception {
+        RemotingCommand remotingCommand = new RemotingCommand();
+        Method method = RemotingCommand.class.getDeclaredMethod("isFieldNullable", Field.class);
+        method.setAccessible(true);
+
+        Field nullString = FieldTestClass.class.getDeclaredField("nullString");
+        assertThat(method.invoke(remotingCommand, nullString)).isEqualTo(false);
+
+        Field nullableString = FieldTestClass.class.getDeclaredField("nullable");
+        assertThat(method.invoke(remotingCommand, nullableString)).isEqualTo(true);
+
+        Field value = FieldTestClass.class.getDeclaredField("value");
+        assertThat(method.invoke(remotingCommand, value)).isEqualTo(false);
+    }
+}
+
+class FieldTestClass {
+    @CFNotNull
+    String nullString = null;
+
+    String nullable = null;
+
+    @CFNotNull
+    String value = "NotNull";
 }
 
 class SampleCommandCustomHeader implements CommandCustomHeader {