geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From u..@apache.org
Subject [geode] 01/01: GEODE-5705: Improve basicReadObject to use switch statement rather than if statements.
Date Mon, 10 Sep 2018 17:20:42 GMT
This is an automated email from the ASF dual-hosted git repository.

udo pushed a commit to branch feature/GEODE-5705
in repository https://gitbox.apache.org/repos/asf/geode.git

commit bdd5617b51b9d62217a714511e119d906b83c64a
Author: Udo Kohlmeyer <ukohlmeyer@pivotal.io>
AuthorDate: Thu Sep 6 17:14:03 2018 -0700

    GEODE-5705: Improve basicReadObject to use switch statement rather
    than if statements.
---
 .../main/java/org/apache/geode/DataSerializer.java |    3 +-
 .../geode/internal/InternalDataSerializer.java     | 1601 +++++++++-----------
 .../apache/geode/internal/util/DscodeHelper.java}  |   33 +-
 .../java/org/apache/geode/internal/DSCODETest.java |   18 +
 4 files changed, 792 insertions(+), 863 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/DataSerializer.java b/geode-core/src/main/java/org/apache/geode/DataSerializer.java
index 45a757a..430e2f9 100644
--- a/geode-core/src/main/java/org/apache/geode/DataSerializer.java
+++ b/geode-core/src/main/java/org/apache/geode/DataSerializer.java
@@ -1481,8 +1481,7 @@ public abstract class DataSerializer {
    * @since GemFire 5.7
    */
   public static void writeCharArray(char[] array, DataOutput out) throws IOException {
-
-    InternalDataSerializer.writeCharArray(array, array != null ? array.length : -1, out);
+    InternalDataSerializer.writeCharArray(array, out);
   }
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java b/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java
index 72a1bc0..e0b364c 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/InternalDataSerializer.java
@@ -106,6 +106,7 @@ import org.apache.geode.internal.lang.ClassUtils;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LocalizedMessage;
 import org.apache.geode.internal.logging.log4j.LogMarker;
+import org.apache.geode.internal.util.DscodeHelper;
 import org.apache.geode.internal.util.concurrent.CopyOnWriteHashMap;
 import org.apache.geode.pdx.NonPortableClassException;
 import org.apache.geode.pdx.PdxInstance;
@@ -131,15 +132,22 @@ import org.apache.geode.pdx.internal.TypeRegistry;
  * @since GemFire 3.5
  */
 public abstract class InternalDataSerializer extends DataSerializer {
+  // array is null
+  public static final byte NULL_ARRAY = -1;
+  /**
+   * array len encoded as int in next 4 bytes
+   *
+   * @since GemFire 5.7
+   */
+  public static final byte INT_ARRAY_LEN = -3;
+  public static final boolean LOAD_CLASS_EACH_TIME =
+      Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "loadClassOnEveryDeserialization");
   private static final Logger logger = LogService.getLogger();
-
   /**
    * Maps Class names to their DataSerializer. This is used to find a DataSerializer during
    * serialization.
    */
   private static final Map<String, DataSerializer> classesToSerializers = new ConcurrentHashMap<>();
-
-
   /**
    * This list contains classes that Geode's classes subclass, such as antlr AST classes which are
    * used by our Object Query Language. It also contains certain classes that are DataSerializable
@@ -191,22 +199,80 @@ public abstract class InternalDataSerializer extends DataSerializer {
 
           // geode-modules
           + ";org.apache.geode.modules.util.SessionCustomExpiry" + ";";
-
-
+  private static final String serializationVersionTxt =
+      System.getProperty(DistributionConfig.GEMFIRE_PREFIX + "serializationVersion");
+  /**
+   * Change this constant to be the last one in SERIALIZATION_VERSION
+   */
+  private static final SERIALIZATION_VERSION latestVersion = SERIALIZATION_VERSION.v662;
+  private static final SERIALIZATION_VERSION serializationVersion = calculateSerializationVersion();
+  /**
+   * Maps the id of a serializer to its {@code DataSerializer}.
+   */
+  private static final ConcurrentMap/* <Integer, DataSerializer|Marker> */ idsToSerializers =
+      new ConcurrentHashMap();
+  /**
+   * Contains the classnames of the data serializers (and not the supported classes) not yet loaded
+   * into the vm as keys and their corresponding holder instances as values.
+   */
+  private static final ConcurrentHashMap<String, SerializerAttributesHolder> dsClassesToHolders =
+      new ConcurrentHashMap<>();
+  /**
+   * Contains the id of the data serializers not yet loaded into the vm as keys and their
+   * corresponding holder instances as values.
+   */
+  private static final ConcurrentHashMap<Integer, SerializerAttributesHolder> idsToHolders =
+      new ConcurrentHashMap<>();
+  /**
+   * Contains the classnames of supported classes as keys and their corresponding
+   * SerializerAttributesHolder instances as values. This applies only to the data serializers which
+   * have not been loaded into the vm.
+   */
+  private static final ConcurrentHashMap<String, SerializerAttributesHolder> supportedClassesToHolders =
+      new ConcurrentHashMap<>();
+  private static final Object listenersSync = new Object();
+  private static final byte TIME_UNIT_NANOSECONDS = -1;
+  private static final byte TIME_UNIT_MICROSECONDS = -2;
+  private static final byte TIME_UNIT_MILLISECONDS = -3;
+  private static final byte TIME_UNIT_SECONDS = -4;
+  private static final ConcurrentMap dsfidToClassMap =
+      logger.isTraceEnabled(LogMarker.SERIALIZER_WRITE_DSFID_VERBOSE) ? new ConcurrentHashMap()
+          : null;
+  /**
+   * array len encoded as unsigned short in next 2 bytes
+   *
+   * @since GemFire 5.7
+   */
+  private static final byte SHORT_ARRAY_LEN = -2;
+  private static final int MAX_BYTE_ARRAY_LEN = (byte) -4 & 0xFF;
+  private static final ThreadLocal<Boolean> pdxSerializationInProgress = new ThreadLocal<>();
+  // Variable Length long encoded as int in next 4 bytes
+  private static final byte INT_VL = 126;
+  // Variable Length long encoded as long in next 8 bytes
+  private static final byte LONG_VL = 127;
+  private static final int MAX_BYTE_VL = 125;
+  private static final CopyOnWriteHashMap<String, WeakReference<Class<?>>> classCache =
+      LOAD_CLASS_EACH_TIME ? null : new CopyOnWriteHashMap<>();
+  private static final Object cacheAccessLock = new Object();
   private static InputStreamFilter defaultSerializationFilter = new EmptyInputStreamFilter();
-
   /**
    * A deserialization filter for ObjectInputStreams
    */
   private static InputStreamFilter serializationFilter = defaultSerializationFilter;
-
-  private static final String serializationVersionTxt =
-      System.getProperty(DistributionConfig.GEMFIRE_PREFIX + "serializationVersion");
-
   /**
    * support for old GemFire clients and WAN sites - needed to enable moving from GemFire to Geode
    */
   private static OldClientSupportService oldClientSupportService;
+  /**
+   * {@code RegistrationListener}s that receive callbacks when {@code DataSerializer}s and {@code
+   * Instantiator}s are registered. Note: copy-on-write access used for this set
+   */
+  private static volatile Set listeners = new HashSet();
+  private static DataSerializer dvddeserializer;
+
+  static {
+    initializeWellKnownSerializers();
+  }
 
   /**
    * For backward compatibility we must swizzle the package of some classes that had to be moved
@@ -281,7 +347,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     serializationFilter = defaultSerializationFilter;
   }
 
-
   /**
    * {@link DistributedSystemService}s that need to acceptlist Serializable objects can use this to
    * read them from a file and then return them via
@@ -311,25 +376,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
 
   }
 
-
-  /**
-   * Any time new serialization format is added then a new enum needs to be added here.
-   *
-   * @since GemFire 6.6.2
-   */
-  private enum SERIALIZATION_VERSION {
-    vINVALID,
-    // includes 6.6.0.x and 6.6.1.x. Note that no serialization changes were made in 6.6 until 6.6.2
-    v660,
-    // 6.6.2.x or later NOTE if you add a new constant make sure and update "latestVersion".
-    v662
-  }
-
-  /**
-   * Change this constant to be the last one in SERIALIZATION_VERSION
-   */
-  private static final SERIALIZATION_VERSION latestVersion = SERIALIZATION_VERSION.v662;
-
   private static SERIALIZATION_VERSION calculateSerializationVersion() {
     if (serializationVersionTxt == null || serializationVersionTxt.isEmpty()) {
       return latestVersion;
@@ -343,8 +389,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  private static final SERIALIZATION_VERSION serializationVersion = calculateSerializationVersion();
-
   public static boolean is662SerializationEnabled() {
     return serializationVersion.ordinal() >= SERIALIZATION_VERSION.v662.ordinal();
   }
@@ -358,10 +402,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  static {
-    initializeWellKnownSerializers();
-  }
-
   private static void initializeWellKnownSerializers() {
     // ArrayBlockingQueue does not have zero-arg constructor
     // LinkedBlockingQueue does have zero-arg constructor but no way to get capacity
@@ -769,42 +809,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
   }
 
   /**
-   * Maps the id of a serializer to its {@code DataSerializer}.
-   */
-  private static final ConcurrentMap/* <Integer, DataSerializer|Marker> */ idsToSerializers =
-      new ConcurrentHashMap();
-
-  /**
-   * Contains the classnames of the data serializers (and not the supported classes) not yet loaded
-   * into the vm as keys and their corresponding holder instances as values.
-   */
-  private static final ConcurrentHashMap<String, SerializerAttributesHolder> dsClassesToHolders =
-      new ConcurrentHashMap<>();
-
-  /**
-   * Contains the id of the data serializers not yet loaded into the vm as keys and their
-   * corresponding holder instances as values.
-   */
-  private static final ConcurrentHashMap<Integer, SerializerAttributesHolder> idsToHolders =
-      new ConcurrentHashMap<>();
-
-  /**
-   * Contains the classnames of supported classes as keys and their corresponding
-   * SerializerAttributesHolder instances as values. This applies only to the data serializers which
-   * have not been loaded into the vm.
-   */
-  private static final ConcurrentHashMap<String, SerializerAttributesHolder> supportedClassesToHolders =
-      new ConcurrentHashMap<>();
-
-  /**
-   * {@code RegistrationListener}s that receive callbacks when {@code DataSerializer}s and {@code
-   * Instantiator}s are registered. Note: copy-on-write access used for this set
-   */
-  private static volatile Set listeners = new HashSet();
-
-  private static final Object listenersSync = new Object();
-
-  /**
    * Convert the given unsigned byte to an int. The returned value will be in the range [0..255]
    * inclusive
    */
@@ -812,14 +816,14 @@ public abstract class InternalDataSerializer extends DataSerializer {
     return ub & 0xFF;
   }
 
-  public static void setOldClientSupportService(final OldClientSupportService svc) {
-    oldClientSupportService = svc;
-  }
-
   public static OldClientSupportService getOldClientSupportService() {
     return oldClientSupportService;
   }
 
+  public static void setOldClientSupportService(final OldClientSupportService svc) {
+    oldClientSupportService = svc;
+  }
+
   /**
    * Instantiates an instance of {@code DataSerializer}
    *
@@ -1097,53 +1101,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  /**
-   * A SerializerAttributesHolder holds information required to load a DataSerializer and exists to
-   * allow client/server connections to be created more quickly than they would if the
-   * DataSerializer information downloaded from the server were used to immediately load the
-   * corresponding classes.
-   */
-  public static class SerializerAttributesHolder {
-    private String className = "";
-    private EventID eventId = null;
-    private ClientProxyMembershipID proxyId = null;
-    private int id = 0;
-
-    SerializerAttributesHolder() {}
-
-    SerializerAttributesHolder(String name, EventID event, ClientProxyMembershipID proxy, int id) {
-      this.className = name;
-      this.eventId = event;
-      this.proxyId = proxy;
-      this.id = id;
-    }
-
-    /**
-     * @return String the classname of the data serializer this instance represents.
-     */
-    public String getClassName() {
-      return this.className;
-    }
-
-    public EventID getEventId() {
-      return this.eventId;
-    }
-
-    public ClientProxyMembershipID getProxyId() {
-      return this.proxyId;
-    }
-
-    public int getId() {
-      return this.id;
-    }
-
-    @Override
-    public String toString() {
-      return "SerializerAttributesHolder[name=" + this.className + ",id=" + this.id + ",eventId="
-          + this.eventId + ']';
-    }
-  }
-
   private static void sendRegistrationMessageToServers(DataSerializer dataSerializer) {
     PoolManagerImpl.allPoolsRegisterDataSerializers(dataSerializer);
   }
@@ -1684,7 +1641,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-
   public static boolean autoSerialized(Object o, DataOutput out) throws IOException {
     AutoSerializableManager asm = TypeRegistry.getAutoSerializableManager();
     if (asm != null) {
@@ -1789,8 +1745,7 @@ public abstract class InternalDataSerializer extends DataSerializer {
    */
   public static void checkOut(DataOutput out) {
     if (out == null) {
-      String s = "Null DataOutput";
-      throw new NullPointerException(s);
+      throw new NullPointerException("Null DataOutput");
     }
   }
 
@@ -1801,8 +1756,7 @@ public abstract class InternalDataSerializer extends DataSerializer {
    */
   public static void checkIn(DataInput in) {
     if (in == null) {
-      String s = "Null DataInput";
-      throw new NullPointerException(s);
+      throw new NullPointerException("Null DataInput");
     }
   }
 
@@ -1819,20 +1773,22 @@ public abstract class InternalDataSerializer extends DataSerializer {
   public static void writeSet(Collection<?> set, DataOutput out) throws IOException {
     checkOut(out);
 
-    int size;
-    if (set == null) {
-      size = -1;
-    } else {
-      size = set.size();
-    }
-    writeArrayLength(size, out);
-    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Writing HashSet with {} elements: {}", size, set);
-    }
-    if (size > 0) {
+    if (set != null) {
+      final int size = set.size();
+      writeArrayLength(size, out);
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+        logger
+            .trace(LogMarker.SERIALIZER_VERBOSE, "Writing HashSet with {} elements: {}", size, set);
+      }
       for (Object element : set) {
         writeObject(element, out);
       }
+    } else {
+      writeArrayLength(-1, out);
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+        logger
+            .trace(LogMarker.SERIALIZER_VERBOSE, "Writing HashSet with {} elements: {}", -1, set);
+      }
     }
   }
 
@@ -1963,7 +1919,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-
   /**
    * Writes the type code for a primitive type Class to {@code DataOutput}.
    */
@@ -1995,45 +1950,36 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  public static Class decodePrimitiveClass(byte typeCode) {
-    if (typeCode == DSCODE.BOOLEAN_TYPE.toByte()) {
-      return Boolean.TYPE;
-    }
-    if (typeCode == DSCODE.CHARACTER_TYPE.toByte()) {
-      return Character.TYPE;
-    }
-    if (typeCode == DSCODE.BYTE_TYPE.toByte()) {
-      return Byte.TYPE;
-    }
-    if (typeCode == DSCODE.SHORT_TYPE.toByte()) {
-      return Short.TYPE;
-    }
-    if (typeCode == DSCODE.INTEGER_TYPE.toByte()) {
-      return Integer.TYPE;
-    }
-    if (typeCode == DSCODE.LONG_TYPE.toByte()) {
-      return Long.TYPE;
-    }
-    if (typeCode == DSCODE.FLOAT_TYPE.toByte()) {
-      return Float.TYPE;
-    }
-    if (typeCode == DSCODE.DOUBLE_TYPE.toByte()) {
-      return Double.TYPE;
-    }
-    if (typeCode == DSCODE.VOID_TYPE.toByte()) {
-      return Void.TYPE;
-    }
-    if (typeCode == DSCODE.NULL.toByte()) {
-      return null;
+  public static Class decodePrimitiveClass(byte typeCode) throws IOException {
+    DSCODE dscode = DscodeHelper.toDSCODE(typeCode);
+    switch (dscode) {
+      case BOOLEAN_TYPE:
+        return Boolean.TYPE;
+      case CHARACTER_TYPE:
+        return Character.TYPE;
+      case BYTE_TYPE:
+        return Byte.TYPE;
+      case SHORT_TYPE:
+        return Short.TYPE;
+      case INTEGER_TYPE:
+        return Integer.TYPE;
+      case LONG_TYPE:
+        return Long.TYPE;
+      case FLOAT_TYPE:
+        return Float.TYPE;
+      case DOUBLE_TYPE:
+        return Double.TYPE;
+      case VOID_TYPE:
+        return Void.TYPE;
+      case NULL:
+        return null;
+      default:
+        throw new InternalGemFireError(
+            LocalizedStrings.InternalDataSerializer_UNEXPECTED_TYPECODE_0
+                .toLocalizedString(typeCode));
     }
-    throw new InternalGemFireError(
-        LocalizedStrings.InternalDataSerializer_UNEXPECTED_TYPECODE_0.toLocalizedString(typeCode));
-  }
 
-  private static final byte TIME_UNIT_NANOSECONDS = -1;
-  private static final byte TIME_UNIT_MICROSECONDS = -2;
-  private static final byte TIME_UNIT_MILLISECONDS = -3;
-  private static final byte TIME_UNIT_SECONDS = -4;
+  }
 
   /**
    * Reads a {@code TimeUnit} from a {@code DataInput}.
@@ -2146,10 +2092,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     return result;
   }
 
-  private static final ConcurrentMap dsfidToClassMap =
-      logger.isTraceEnabled(LogMarker.SERIALIZER_WRITE_DSFID_VERBOSE) ? new ConcurrentHashMap()
-          : null;
-
   public static void writeUserDataSerializableHeader(int classId, DataOutput out)
       throws IOException {
     if (classId <= Byte.MAX_VALUE && classId >= Byte.MIN_VALUE) {
@@ -2171,19 +2113,19 @@ public abstract class InternalDataSerializer extends DataSerializer {
    * @see DataSerializer#readCharArray
    * @since GemFire 6.6
    */
-  public static void writeCharArray(char[] array, int length, DataOutput out) throws IOException {
+  public static void writeCharArray(char[] array, DataOutput out) throws IOException {
     checkOut(out);
 
     if (array == null) {
-      length = -1;
-    }
-    writeArrayLength(length, out);
-    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Writing char array of length {}", length);
-    }
-    if (length > 0) {
-      for (int i = 0; i < length; i++) {
-        out.writeChar(array[i]);
+      writeArrayLength(-1, out);
+    } else {
+      final int length = array.length;
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Writing char array of length {}", length);
+      }
+      writeArrayLength(length, out);
+      for (char character : array) {
+        out.writeChar(character);
       }
     }
   }
@@ -2422,7 +2364,7 @@ public abstract class InternalDataSerializer extends DataSerializer {
       boolean invoked = false;
       Version v = InternalDataSerializer.getVersionForDataStreamOrNull(out);
 
-      if (v != null && v != Version.CURRENT) {
+      if (Version.CURRENT != v && v != null) {
         // get versions where DataOutput was upgraded
         Version[] versions = null;
         if (ds instanceof SerializationVersions) {
@@ -2431,7 +2373,7 @@ public abstract class InternalDataSerializer extends DataSerializer {
         }
         // check if the version of the peer or diskstore is different and
         // there has been a change in the message
-        if (versions != null && versions.length > 0) {
+        if (versions != null) {
           for (Version version : versions) {
             // if peer version is less than the greatest upgraded version
             if (v.compareTo(version) < 0) {
@@ -2495,7 +2437,7 @@ public abstract class InternalDataSerializer extends DataSerializer {
     try {
       boolean invoked = false;
       Version v = InternalDataSerializer.getVersionForDataStreamOrNull(in);
-      if (v != null && v != Version.CURRENT) {
+      if (Version.CURRENT != v && v != null) {
         // get versions where DataOutput was upgraded
         Version[] versions = null;
         if (ds instanceof SerializationVersions) {
@@ -2504,7 +2446,7 @@ public abstract class InternalDataSerializer extends DataSerializer {
         }
         // check if the version of the peer or diskstore is different and
         // there has been a change in the message
-        if (versions != null && versions.length > 0) {
+        if (versions != null) {
           for (Version version : versions) {
             // if peer version is less than the greatest upgraded version
             if (v.compareTo(version) < 0) {
@@ -2534,7 +2476,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-
   private static Object readDataSerializable(final DataInput in)
       throws IOException, ClassNotFoundException {
     Class c = readClass(in);
@@ -2642,25 +2583,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  // array is null
-  public static final byte NULL_ARRAY = -1;
-
-  /**
-   * array len encoded as unsigned short in next 2 bytes
-   *
-   * @since GemFire 5.7
-   */
-  private static final byte SHORT_ARRAY_LEN = -2;
-
-  /**
-   * array len encoded as int in next 4 bytes
-   *
-   * @since GemFire 5.7
-   */
-  public static final byte INT_ARRAY_LEN = -3;
-
-  private static final int MAX_BYTE_ARRAY_LEN = (byte) -4 & 0xFF;
-
   public static void writeArrayLength(int len, DataOutput out) throws IOException {
     if (len == -1) {
       out.writeByte(NULL_ARRAY);
@@ -2683,9 +2605,9 @@ public abstract class InternalDataSerializer extends DataSerializer {
       int result = ubyteToInt(code);
       if (result > MAX_BYTE_ARRAY_LEN) {
         if (code == SHORT_ARRAY_LEN) {
-          result = in.readUnsignedShort();
+          return in.readUnsignedShort();
         } else if (code == INT_ARRAY_LEN) {
-          result = in.readInt();
+          return in.readInt();
         } else {
           throw new IllegalStateException("unexpected array length code=" + code);
         }
@@ -2694,61 +2616,46 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  /**
-   * Serializes a list of Integers. The argument may be null. Deserialize with
-   * readListOfIntegers().
-   *
-   * TODO: writeListOfIntegers is unused
-   */
-  public void writeListOfIntegers(List<Integer> list, DataOutput out) throws IOException {
-    int size;
-    if (list == null) {
-      size = -1;
-    } else {
-      size = list.size();
-    }
-    InternalDataSerializer.writeArrayLength(size, out);
-    if (size > 0) {
-      for (int i = 0; i < size; i++) {
-        out.writeInt(list.get(i));
-      }
+  private static Object readDSFID(final DataInput in, DSCODE dscode)
+      throws IOException, ClassNotFoundException {
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+      logger.trace(LogMarker.SERIALIZER_VERBOSE, "readDSFID: header={}", dscode);
+    }
+    switch (dscode) {
+      case DS_FIXED_ID_BYTE:
+        return DSFIDFactory.create(in.readByte(), in);
+      case DS_FIXED_ID_SHORT:
+        return DSFIDFactory.create(in.readShort(), in);
+      case DS_NO_FIXED_ID:
+        return readDataSerializableFixedID(in);
+      case DS_FIXED_ID_INT:
+        return DSFIDFactory.create(in.readInt(), in);
+      default:
+        throw new IllegalStateException("unexpected byte: " + dscode + " while reading dsfid");
     }
   }
 
   public static Object readDSFID(final DataInput in) throws IOException, ClassNotFoundException {
     checkIn(in);
-    byte header = in.readByte();
-    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-      logger.trace(LogMarker.SERIALIZER_VERBOSE, "readDSFID: header={}", header);
-    }
-    if (header == DSCODE.DS_FIXED_ID_BYTE.toByte()) {
-      return DSFIDFactory.create(in.readByte(), in);
-    } else if (header == DSCODE.DS_FIXED_ID_SHORT.toByte()) {
-      return DSFIDFactory.create(in.readShort(), in);
-    } else if (header == DSCODE.DS_NO_FIXED_ID.toByte()) {
-      return readDataSerializableFixedID(in);
-    } else if (header == DSCODE.DS_FIXED_ID_INT.toByte()) {
-      return DSFIDFactory.create(in.readInt(), in);
-    } else {
-      throw new IllegalStateException("unexpected byte: " + header + " while reading dsfid");
+    return readDSFID(in, DscodeHelper.toDSCODE(in.readByte()));
+  }
+
+  private static int readDSFIDHeader(final DataInput in, DSCODE dscode) throws IOException {
+    switch (dscode) {
+      case DS_FIXED_ID_BYTE:
+        return in.readByte();
+      case DS_FIXED_ID_SHORT:
+        return in.readShort();
+      case DS_FIXED_ID_INT:
+        return in.readInt();
+      default:
+        throw new IllegalStateException("unexpected byte: " + dscode + " while reading dsfid");
     }
   }
 
   public static int readDSFIDHeader(final DataInput in) throws IOException {
     checkIn(in);
-    byte header = in.readByte();
-    if (header == DSCODE.DS_FIXED_ID_BYTE.toByte()) {
-      return in.readByte();
-    } else if (header == DSCODE.DS_FIXED_ID_SHORT.toByte()) {
-      return in.readShort();
-    } else if (header == DSCODE.DS_NO_FIXED_ID.toByte()) {
-      // is that correct??
-      return Integer.MAX_VALUE;
-    } else if (header == DSCODE.DS_FIXED_ID_INT.toByte()) {
-      return in.readInt();
-    } else {
-      throw new IllegalStateException("unexpected byte: " + header + " while reading dsfid");
-    }
+    return readDSFIDHeader(in, DscodeHelper.toDSCODE(in.readByte()));
   }
 
   /**
@@ -2758,50 +2665,59 @@ public abstract class InternalDataSerializer extends DataSerializer {
    * @throws IOException A problem occurs while reading from {@code in}
    * @since GemFire 5.7
    */
-  public static String readString(DataInput in, byte header) throws IOException {
-    if (header == DSCODE.STRING_BYTES.toByte()) {
-      int len = in.readUnsignedShort();
-      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading STRING_BYTES of len={}", len);
-      }
-      byte[] buf = new byte[len];
-      in.readFully(buf, 0, len);
-      return new String(buf, 0); // intentionally using deprecated constructor
-    } else if (header == DSCODE.STRING.toByte()) {
-      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading utf STRING");
-      }
-      return in.readUTF();
-    } else if (header == DSCODE.NULL_STRING.toByte()) {
-      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading NULL_STRING");
-      }
-      return null;
-    } else if (header == DSCODE.HUGE_STRING_BYTES.toByte()) {
-      int len = in.readInt();
-      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading HUGE_STRING_BYTES of len={}", len);
-      }
-      byte[] buf = new byte[len];
-      in.readFully(buf, 0, len);
-      return new String(buf, 0); // intentionally using deprecated constructor
-    } else if (header == DSCODE.HUGE_STRING.toByte()) {
-      int len = in.readInt();
-      if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading HUGE_STRING of len={}", len);
-      }
-      char[] buf = new char[len];
-      for (int i = 0; i < len; i++) {
-        buf[i] = in.readChar();
+  private static String readString(DataInput in, DSCODE dscode) throws IOException {
+    switch (dscode) {
+      case STRING_BYTES:
+        return readStringBytesFromDataInput(in, in.readUnsignedShort());
+      case STRING:
+        return readStringUTFFromDataInput(in);
+      case NULL_STRING: {
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+          logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading NULL_STRING");
+        }
+        return null;
       }
-      return new String(buf);
-    } else {
-      String s = "Unknown String header " + header;
-      throw new IOException(s);
+      case HUGE_STRING_BYTES:
+        return readStringBytesFromDataInput(in, in.readInt());
+      case HUGE_STRING:
+        return readHugeStringFromDataInput(in);
+      default:
+        throw new IOException("Unknown String header " + dscode);
     }
   }
 
-  private static DataSerializer dvddeserializer;
+  private static String readHugeStringFromDataInput(DataInput in) throws IOException {
+    int len = in.readInt();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading HUGE_STRING of len={}", len);
+    }
+    char[] buf = new char[len];
+    for (int i = 0; i < len; i++) {
+      buf[i] = in.readChar();
+    }
+    return new String(buf);
+  }
+
+  private static String readStringUTFFromDataInput(DataInput in) throws IOException {
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading utf STRING");
+    }
+    return in.readUTF();
+  }
+
+  private static String readStringBytesFromDataInput(DataInput dataInput, int len)
+      throws IOException {
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Reading STRING_BYTES of len={}", len);
+    }
+    byte[] buf = new byte[len];
+    dataInput.readFully(buf, 0, len);
+    return new String(buf, 0); // intentionally using deprecated constructor
+  }
+
+  public static String readString(DataInput in, byte header) throws IOException {
+    return readString(in, DscodeHelper.toDSCODE(header));
+  }
 
   // TODO: registerDVDDeserializer is unused
   public static void registerDVDDeserializer(DataSerializer dvddeslzr) {
@@ -2834,260 +2750,207 @@ public abstract class InternalDataSerializer extends DataSerializer {
 
     // Read the header byte
     byte header = in.readByte();
+    DSCODE headerDSCode = DscodeHelper.toDSCODE(header);
+
     if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
       logger.trace(LogMarker.SERIALIZER_VERBOSE, "basicReadObject: header={}", header);
     }
-    if (header == DSCODE.DS_FIXED_ID_BYTE.toByte()) {
-      return DSFIDFactory.create(in.readByte(), in);
-    }
-    if (header == DSCODE.DS_FIXED_ID_SHORT.toByte()) {
-      return DSFIDFactory.create(in.readShort(), in);
-    }
-    if (header == DSCODE.DS_FIXED_ID_INT.toByte()) {
-      return DSFIDFactory.create(in.readInt(), in);
-    }
-    if (header == DSCODE.DS_NO_FIXED_ID.toByte()) {
-      return readDataSerializableFixedID(in);
-    }
-    if (header == DSCODE.NULL.toByte()) {
-      return null;
-    }
-    if (header == DSCODE.NULL_STRING.toByte() || header == DSCODE.STRING.toByte()
-        || header == DSCODE.HUGE_STRING.toByte() || header == DSCODE.STRING_BYTES.toByte()
-        || header == DSCODE.HUGE_STRING_BYTES.toByte()) {
-      return readString(in, header);
-    }
-    if (header == DSCODE.CLASS.toByte()) {
-      return readClass(in);
-    }
-    if (header == DSCODE.DATE.toByte()) {
-      return readDate(in);
-    }
-    if (header == DSCODE.FILE.toByte()) {
-      return readFile(in);
-    }
-    if (header == DSCODE.INET_ADDRESS.toByte()) {
-      return readInetAddress(in);
-    }
-    if (header == DSCODE.BOOLEAN.toByte()) {
-      return readBoolean(in);
-    }
-    if (header == DSCODE.CHARACTER.toByte()) {
-      return readCharacter(in);
-    }
-    if (header == DSCODE.BYTE.toByte()) {
-      return readByte(in);
-    }
-    if (header == DSCODE.SHORT.toByte()) {
-      return readShort(in);
-    }
-    if (header == DSCODE.INTEGER.toByte()) {
-      return readInteger(in);
-    }
-    if (header == DSCODE.LONG.toByte()) {
-      return readLong(in);
-    }
-    if (header == DSCODE.FLOAT.toByte()) {
-      return readFloat(in);
-    }
-    if (header == DSCODE.DOUBLE.toByte()) {
-      return readDouble(in);
-    }
-    if (header == DSCODE.BYTE_ARRAY.toByte()) {
-      return readByteArray(in);
-    }
-    if (header == DSCODE.ARRAY_OF_BYTE_ARRAYS.toByte()) {
-      return readArrayOfByteArrays(in);
-    }
-    if (header == DSCODE.SHORT_ARRAY.toByte()) {
-      return readShortArray(in);
-    }
-    if (header == DSCODE.STRING_ARRAY.toByte()) {
-      return readStringArray(in);
-    }
-    if (header == DSCODE.INT_ARRAY.toByte()) {
-      return readIntArray(in);
-    }
-    if (header == DSCODE.LONG_ARRAY.toByte()) {
-      return readLongArray(in);
-    }
-    if (header == DSCODE.FLOAT_ARRAY.toByte()) {
-      return readFloatArray(in);
-    }
-    if (header == DSCODE.DOUBLE_ARRAY.toByte()) {
-      return readDoubleArray(in);
-    }
-    if (header == DSCODE.BOOLEAN_ARRAY.toByte()) {
-      return readBooleanArray(in);
-    }
-    if (header == DSCODE.CHAR_ARRAY.toByte()) {
-      return readCharArray(in);
-    }
-    if (header == DSCODE.OBJECT_ARRAY.toByte()) {
-      return readObjectArray(in);
-    }
-    if (header == DSCODE.ARRAY_LIST.toByte()) {
-      return readArrayList(in);
-    }
-    if (header == DSCODE.LINKED_LIST.toByte()) {
-      return readLinkedList(in);
-    }
-    if (header == DSCODE.HASH_SET.toByte()) {
-      return readHashSet(in);
-    }
-    if (header == DSCODE.LINKED_HASH_SET.toByte()) {
-      return readLinkedHashSet(in);
-    }
-    if (header == DSCODE.HASH_MAP.toByte()) {
-      return readHashMap(in);
-    }
-    if (header == DSCODE.IDENTITY_HASH_MAP.toByte()) {
-      return readIdentityHashMap(in);
-    }
-    if (header == DSCODE.HASH_TABLE.toByte()) {
-      return readHashtable(in);
-    }
-    if (header == DSCODE.CONCURRENT_HASH_MAP.toByte()) {
-      return readConcurrentHashMap(in);
-    }
-    if (header == DSCODE.PROPERTIES.toByte()) {
-      return readProperties(in);
-    }
-    if (header == DSCODE.TIME_UNIT.toByte()) {
-      return readTimeUnit(in);
-    }
-    if (header == DSCODE.USER_CLASS.toByte()) {
-      return readUserObject(in, in.readByte());
-    }
-    if (header == DSCODE.USER_CLASS_2.toByte()) {
-      return readUserObject(in, in.readShort());
-    }
-    if (header == DSCODE.USER_CLASS_4.toByte()) {
-      return readUserObject(in, in.readInt());
-    }
-    if (header == DSCODE.VECTOR.toByte()) {
-      return readVector(in);
-    }
-    if (header == DSCODE.STACK.toByte()) {
-      return readStack(in);
-    }
-    if (header == DSCODE.TREE_MAP.toByte()) {
-      return readTreeMap(in);
-    }
-    if (header == DSCODE.TREE_SET.toByte()) {
-      return readTreeSet(in);
-    }
-    if (header == DSCODE.BOOLEAN_TYPE.toByte()) {
-      return Boolean.TYPE;
-    }
-    if (header == DSCODE.CHARACTER_TYPE.toByte()) {
-      return Character.TYPE;
-    }
-    if (header == DSCODE.BYTE_TYPE.toByte()) {
-      return Byte.TYPE;
-    }
-    if (header == DSCODE.SHORT_TYPE.toByte()) {
-      return Short.TYPE;
-    }
-    if (header == DSCODE.INTEGER_TYPE.toByte()) {
-      return Integer.TYPE;
-    }
-    if (header == DSCODE.LONG_TYPE.toByte()) {
-      return Long.TYPE;
-    }
-    if (header == DSCODE.FLOAT_TYPE.toByte()) {
-      return Float.TYPE;
-    }
-    if (header == DSCODE.DOUBLE_TYPE.toByte()) {
-      return Double.TYPE;
-    }
-    if (header == DSCODE.VOID_TYPE.toByte()) {
-      return Void.TYPE;
-    }
-    if (header == DSCODE.USER_DATA_SERIALIZABLE.toByte()) {
-      return readUserDataSerializable(in, in.readByte());
-    }
-    if (header == DSCODE.USER_DATA_SERIALIZABLE_2.toByte()) {
-      return readUserDataSerializable(in, in.readShort());
-    }
-    if (header == DSCODE.USER_DATA_SERIALIZABLE_4.toByte()) {
-      return readUserDataSerializable(in, in.readInt());
-    }
-    if (header == DSCODE.DATA_SERIALIZABLE.toByte()) {
-      return readDataSerializable(in);
+
+    switch (headerDSCode) {
+      case DS_FIXED_ID_BYTE:
+        return DSFIDFactory.create(in.readByte(), in);
+      case DS_FIXED_ID_SHORT:
+        return DSFIDFactory.create(in.readShort(), in);
+      case DS_FIXED_ID_INT:
+        return DSFIDFactory.create(in.readInt(), in);
+      case DS_NO_FIXED_ID:
+        return readDataSerializableFixedID(in);
+      case NULL:
+        return null;
+      case NULL_STRING:
+        return null;
+      case STRING:
+        return readStringUTFFromDataInput(in);
+      case HUGE_STRING:
+        return readHugeStringFromDataInput(in);
+      case STRING_BYTES:
+        return readStringBytesFromDataInput(in, in.readUnsignedShort());
+      case HUGE_STRING_BYTES:
+        return readStringBytesFromDataInput(in, in.readInt());
+      case CLASS:
+        return readClass(in);
+      case DATE:
+        return readDate(in);
+      case FILE:
+        return readFile(in);
+      case INET_ADDRESS:
+        return readInetAddress(in);
+      case BOOLEAN:
+        return readBoolean(in);
+      case CHARACTER:
+        return readCharacter(in);
+      case BYTE:
+        return readByte(in);
+      case SHORT:
+        return readShort(in);
+      case INTEGER:
+        return readInteger(in);
+      case LONG:
+        return readLong(in);
+      case FLOAT:
+        return readFloat(in);
+      case DOUBLE:
+        return readDouble(in);
+      case BYTE_ARRAY:
+        return readByteArray(in);
+      case ARRAY_OF_BYTE_ARRAYS:
+        return readArrayOfByteArrays(in);
+      case SHORT_ARRAY:
+        return readShortArray(in);
+      case STRING_ARRAY:
+        return readStringArray(in);
+      case INT_ARRAY:
+        return readIntArray(in);
+      case LONG_ARRAY:
+        return readLongArray(in);
+      case FLOAT_ARRAY:
+        return readFloatArray(in);
+      case DOUBLE_ARRAY:
+        return readDoubleArray(in);
+      case BOOLEAN_ARRAY:
+        return readBooleanArray(in);
+      case CHAR_ARRAY:
+        return readCharArray(in);
+      case OBJECT_ARRAY:
+        return readObjectArray(in);
+      case ARRAY_LIST:
+        return readArrayList(in);
+      case LINKED_LIST:
+        return readLinkedList(in);
+      case HASH_SET:
+        return readHashSet(in);
+      case LINKED_HASH_SET:
+        return readLinkedHashSet(in);
+      case HASH_MAP:
+        return readHashMap(in);
+      case IDENTITY_HASH_MAP:
+        return readIdentityHashMap(in);
+      case HASH_TABLE:
+        return readHashtable(in);
+      case CONCURRENT_HASH_MAP:
+        return readConcurrentHashMap(in);
+      case PROPERTIES:
+        return readProperties(in);
+      case TIME_UNIT:
+        return readTimeUnit(in);
+      case USER_CLASS:
+        return readUserObject(in, in.readByte());
+      case USER_CLASS_2:
+        return readUserObject(in, in.readShort());
+      case USER_CLASS_4:
+        return readUserObject(in, in.readInt());
+      case VECTOR:
+        return readVector(in);
+      case STACK:
+        return readStack(in);
+      case TREE_MAP:
+        return readTreeMap(in);
+      case TREE_SET:
+        return readTreeSet(in);
+      case BOOLEAN_TYPE:
+        return Boolean.TYPE;
+      case CHARACTER_TYPE:
+        return Character.TYPE;
+      case BYTE_TYPE:
+        return Byte.TYPE;
+      case SHORT_TYPE:
+        return Short.TYPE;
+      case INTEGER_TYPE:
+        return Integer.TYPE;
+      case LONG_TYPE:
+        return Long.TYPE;
+      case FLOAT_TYPE:
+        return Float.TYPE;
+      case DOUBLE_TYPE:
+        return Double.TYPE;
+      case VOID_TYPE:
+        return Void.TYPE;
+      case USER_DATA_SERIALIZABLE:
+        return readUserDataSerializable(in, in.readByte());
+      case USER_DATA_SERIALIZABLE_2:
+        return readUserDataSerializable(in, in.readShort());
+      case USER_DATA_SERIALIZABLE_4:
+        return readUserDataSerializable(in, in.readInt());
+      case DATA_SERIALIZABLE:
+        return readDataSerializable(in);
+      case SERIALIZABLE:
+        return readSerializable(in);
+      case PDX:
+        return readPdxSerializable(in);
+      case PDX_ENUM:
+        return readPdxEnum(in);
+      case GEMFIRE_ENUM:
+        return readGemFireEnum(in);
+      case PDX_INLINE_ENUM:
+        return readPdxInlineEnum(in);
+      case BIG_INTEGER:
+        return readBigInteger(in);
+      case BIG_DECIMAL:
+        return readBigDecimal(in);
+      case UUID:
+        return readUUID(in);
+      case TIMESTAMP:
+        return readTimestamp(in);
+      default:
+        throw new IOException("Unknown header byte: " + header);
     }
-    if (header == DSCODE.SERIALIZABLE.toByte()) {
-      final boolean isDebugEnabled_SERIALIZER = logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE);
-      Object serializableResult;
-      if (in instanceof DSObjectInputStream) {
-        serializableResult = ((DSObjectInputStream) in).readObject();
+  }
+
+  private static Serializable readSerializable(DataInput in)
+      throws IOException, ClassNotFoundException {
+    final boolean isDebugEnabled_SERIALIZER = logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE);
+    Serializable serializableResult;
+    if (in instanceof DSObjectInputStream) {
+      serializableResult = (Serializable) ((DSObjectInputStream) in).readObject();
+    } else {
+      InputStream stream;
+      if (in instanceof InputStream) {
+        stream = (InputStream) in;
       } else {
-        InputStream stream;
-        if (in instanceof InputStream) {
-          stream = (InputStream) in;
-        } else {
-          stream = new InputStream() {
-            @Override
-            public int read() throws IOException {
-              try {
-                return in.readUnsignedByte(); // fix for bug 47249
-              } catch (EOFException ignored) {
-                return -1;
-              }
+        stream = new InputStream() {
+          @Override
+          public int read() throws IOException {
+            try {
+              return in.readUnsignedByte(); // fix for bug 47249
+            } catch (EOFException ignored) {
+              return -1;
             }
-
-          };
-        }
-
-        ObjectInput ois = new DSObjectInputStream(stream);
-        serializationFilter.setFilterOn((ObjectInputStream) ois);
-        if (stream instanceof VersionedDataStream) {
-          Version v = ((VersionedDataStream) stream).getVersion();
-          if (v != null && v != Version.CURRENT) {
-            ois = new VersionedObjectInput(ois, v);
           }
-        }
 
-        serializableResult = ois.readObject();
+        };
+      }
 
-        if (isDebugEnabled_SERIALIZER) {
-          logger.trace(LogMarker.SERIALIZER_VERBOSE, "Read Serializable object: {}",
-              serializableResult);
+      ObjectInput ois = new DSObjectInputStream(stream);
+      serializationFilter.setFilterOn((ObjectInputStream) ois);
+      if (stream instanceof VersionedDataStream) {
+        Version v = ((VersionedDataStream) stream).getVersion();
+        if (Version.CURRENT != v && v != null) {
+          ois = new VersionedObjectInput(ois, v);
         }
       }
+
+      serializableResult = (Serializable) ois.readObject();
+
       if (isDebugEnabled_SERIALIZER) {
-        logger.trace(LogMarker.SERIALIZER_VERBOSE, "deserialized instanceof {}",
-            serializableResult.getClass());
+        logger.trace(LogMarker.SERIALIZER_VERBOSE, "Read Serializable object: {}",
+            serializableResult);
       }
-      return serializableResult;
-    }
-    if (header == DSCODE.PDX.toByte()) {
-      return readPdxSerializable(in);
-    }
-    if (header == DSCODE.PDX_ENUM.toByte()) {
-      return readPdxEnum(in);
-    }
-    if (header == DSCODE.GEMFIRE_ENUM.toByte()) {
-      return readGemFireEnum(in);
-    }
-    if (header == DSCODE.PDX_INLINE_ENUM.toByte()) {
-      return readPdxInlineEnum(in);
-    }
-    if (header == DSCODE.BIG_INTEGER.toByte()) {
-      return readBigInteger(in);
-    }
-    if (header == DSCODE.BIG_DECIMAL.toByte()) {
-      return readBigDecimal(in);
     }
-    if (header == DSCODE.UUID.toByte()) {
-      return readUUID(in);
-    }
-    if (header == DSCODE.TIMESTAMP.toByte()) {
-      return readTimestamp(in);
+    if (isDebugEnabled_SERIALIZER) {
+      logger.trace(LogMarker.SERIALIZER_VERBOSE, "deserialized instanceof {}",
+          serializableResult.getClass());
     }
-
-    String s = "Unknown header byte: " + header;
-    throw new IOException(s);
+    return serializableResult;
   }
 
   private static Object readUserDataSerializable(final DataInput in, int classId)
@@ -3123,19 +2986,13 @@ public abstract class InternalDataSerializer extends DataSerializer {
     }
   }
 
-  private static final ThreadLocal<Boolean> pdxSerializationInProgress = new ThreadLocal<>();
-
   public static boolean isPdxSerializationInProgress() {
     Boolean v = pdxSerializationInProgress.get();
     return v != null && v;
   }
 
-  public static void setPdxSerializationInProgress(boolean v) {
-    if (v) {
-      pdxSerializationInProgress.set(true);
-    } else {
-      pdxSerializationInProgress.set(false);
-    }
+  public static void setPdxSerializationInProgress(boolean inProgress) {
+    pdxSerializationInProgress.set(inProgress);
   }
 
   public static boolean writePdx(DataOutput out, InternalCache internalCache, Object pdx,
@@ -3327,48 +3184,360 @@ public abstract class InternalDataSerializer extends DataSerializer {
     return supportedClassesToHolders;
   }
 
+  public static void writeObjectArray(Object[] array, DataOutput out, boolean ensureCompatibility)
+      throws IOException {
+    InternalDataSerializer.checkOut(out);
+    int length = -1;
+    if (array != null) {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
+      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Writing Object array of length {}", length);
+    }
+    if (length >= 0) {
+      writeClass(array.getClass().getComponentType(), out);
+      for (int i = 0; i < length; i++) {
+        basicWriteObject(array[i], out, ensureCompatibility);
+      }
+    }
+  }
+
   /**
-   * A marker object for {@code DataSerializer}s that have not been registered. Using this marker
-   * object allows us to asynchronously send {@code DataSerializer} registration updates. If the
-   * serialized bytes arrive at a VM before the registration message does, the deserializer will
-   * wait an amount of time for the registration message to arrive.
+   * Write a variable length long the old way (pre 7.0). Use this only in contexts where you might
+   * need to communicate with pre 7.0 members or files.
    */
-  abstract static class Marker {
-    /**
-     * The DataSerializer that is filled in upon registration
-     */
-    protected DataSerializer serializer = null;
-
-    /**
-     * set to true once setSerializer is called.
-     */
-    boolean hasBeenSet = false;
-
-    abstract DataSerializer getSerializer();
+  public static void writeVLOld(long data, DataOutput out) throws IOException {
+    if (data < 0) {
+      Assert.fail("Data expected to be >=0 is " + data);
+    }
+    if (data <= MAX_BYTE_VL) {
+      out.writeByte((byte) data);
+    } else if (data <= 0x7FFF) {
+      // set the sign bit to indicate a short
+      out.write(((int) data >>> 8 | 0x80) & 0xFF);
+      out.write((int) data >>> 0 & 0xFF);
+    } else if (data <= Integer.MAX_VALUE) {
+      out.writeByte(INT_VL);
+      out.writeInt((int) data);
+    } else {
+      out.writeByte(LONG_VL);
+      out.writeLong(data);
+    }
+  }
 
-    /**
-     * Sets the serializer associated with this marker. It will notify any threads that are waiting
-     * for the serializer to be registered.
-     */
-    void setSerializer(DataSerializer serializer) {
-      synchronized (this) {
-        this.hasBeenSet = true;
-        this.serializer = serializer;
-        this.notifyAll();
-      }
+  /**
+   * Write a variable length long the old way (pre 7.0). Use this only in contexts where you might
+   * need to communicate with pre 7.0 members or files.
+   */
+  public static long readVLOld(DataInput in) throws IOException {
+    byte code = in.readByte();
+    long result;
+    if (code < 0) {
+      // mask off sign bit
+      result = code & 0x7F;
+      result <<= 8;
+      result |= in.readByte() & 0xFF;
+    } else if (code <= MAX_BYTE_VL) {
+      result = code;
+    } else if (code == INT_VL) {
+      result = in.readInt();
+    } else if (code == LONG_VL) {
+      result = in.readLong();
+    } else {
+      throw new IllegalStateException("unexpected variable length code=" + code);
     }
+    return result;
   }
 
   /**
-   * A marker object for {@code DataSerializer}s that have not been registered. Using this marker
-   * object allows us to asynchronously send {@code DataSerializer} registration updates. If the
-   * serialized bytes arrive at a VM before the registration message does, the deserializer will
-   * wait an amount of time for the registration message to arrive. Made public for unit test
-   * access.
+   * Encode a long as a variable length array.
    *
-   * @since GemFire 5.7
+   * This method is appropriate for unsigned integers. For signed integers, negative values will
+   * always consume 10 bytes, so it is recommended to use writeSignedVL instead.
+   *
+   * This is taken from the varint encoding in protobufs (BSD licensed). See
+   * https://developers.google.com/protocol-buffers/docs/encoding
    */
-  public static class GetMarker extends Marker {
+  public static void writeUnsignedVL(long data, DataOutput out) throws IOException {
+    while (true) {
+      if ((data & ~0x7FL) == 0) {
+        out.writeByte((int) data);
+        return;
+      } else {
+        out.writeByte((int) data & 0x7F | 0x80);
+        data >>>= 7;
+      }
+    }
+  }
+
+  /**
+   * Decode a long as a variable length array.
+   *
+   * This is taken from the varint encoding in protobufs (BSD licensed). See
+   * https://developers.google.com/protocol-buffers/docs/encoding
+   */
+  public static long readUnsignedVL(DataInput in) throws IOException {
+    int shift = 0;
+    long result = 0;
+    while (shift < 64) {
+      final byte b = in.readByte();
+      result |= (long) (b & 0x7F) << shift;
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+      shift += 7;
+    }
+    throw new GemFireIOException("Malformed variable length integer");
+  }
+
+  /**
+   * Encode a signed long as a variable length array.
+   *
+   * This method is appropriate for signed integers. It uses zig zag encoding to so that negative
+   * numbers will be represented more compactly. For unsigned values, writeUnsignedVL will be more
+   * efficient.
+   */
+  public static void writeSignedVL(long data, DataOutput out) throws IOException {
+    writeUnsignedVL(encodeZigZag64(data), out);
+  }
+
+  /**
+   * Decode a signed long as a variable length array.
+   *
+   * This method is appropriate for signed integers. It uses zig zag encoding to so that negative
+   * numbers will be represented more compactly. For unsigned values, writeUnsignedVL will be more
+   * efficient.
+   */
+  public static long readSignedVL(DataInput in) throws IOException {
+    return decodeZigZag64(readUnsignedVL(in));
+  }
+
+  /**
+   * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
+   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
+   * to be varint encoded, thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 64-bit integer, stored in a signed int because Java has no explicit
+   *        unsigned support.
+   * @return A signed 64-bit integer.
+   *
+   *         This is taken from the varint encoding in protobufs (BSD licensed). See
+   *         https://developers.google.com/protocol-buffers/docs/encoding
+   */
+  private static long decodeZigZag64(final long n) {
+    return n >>> 1 ^ -(n & 1);
+  }
+
+  /**
+   * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
+   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
+   * to be varint encoded, thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 64-bit integer.
+   * @return An unsigned 64-bit integer, stored in a signed int because Java has no explicit
+   *         unsigned support.
+   *
+   *         This is taken from the varint encoding in protobufs (BSD licensed). See
+   *         https://developers.google.com/protocol-buffers/docs/encoding
+   */
+  private static long encodeZigZag64(final long n) {
+    // Note: the right-shift must be arithmetic
+    return n << 1 ^ n >> 63;
+  }
+
+  /* test only method */
+  public static int calculateBytesForTSandDSID(int dsid) {
+    HeapDataOutputStream out = new HeapDataOutputStream(4 + 8, Version.CURRENT);
+    long now = System.currentTimeMillis();
+    try {
+      writeUnsignedVL(now, out);
+      writeUnsignedVL(InternalDataSerializer.encodeZigZag64(dsid), out);
+    } catch (IOException ignored) {
+      return 0;
+    }
+    return out.size();
+  }
+
+  public static Class<?> getCachedClass(String p_className) throws ClassNotFoundException {
+    String className = processIncomingClassName(p_className);
+    if (LOAD_CLASS_EACH_TIME) {
+      return ClassPathLoader.getLatest().forName(className);
+    } else {
+      Class<?> result = getExistingCachedClass(className);
+      if (result == null) {
+        // Do the forName call outside the sync to fix bug 46172
+        result = ClassPathLoader.getLatest().forName(className);
+        synchronized (cacheAccessLock) {
+          Class<?> cachedClass = getExistingCachedClass(className);
+          if (cachedClass == null) {
+            classCache.put(className, new WeakReference<>(result));
+          } else {
+            result = cachedClass;
+          }
+        }
+      }
+      return result;
+    }
+  }
+
+  private static Class<?> getExistingCachedClass(String className) {
+    WeakReference<Class<?>> wr = classCache.get(className);
+    Class<?> result = null;
+    if (wr != null) {
+      result = wr.get();
+    }
+    return result;
+  }
+
+  public static void flushClassCache() {
+    if (classCache != null) {
+      // Not locking classCache during clear as doing so causes a deadlock in the DeployedJar
+      classCache.clear();
+    }
+  }
+
+  /**
+   * Serializes a list of Integers. The argument may be null. Deserialize with
+   * readListOfIntegers().
+   *
+   * TODO: writeListOfIntegers is unused
+   */
+  public void writeListOfIntegers(List<Integer> list, DataOutput out) throws IOException {
+    if (list != null) {
+      InternalDataSerializer.writeArrayLength(list.size(), out);
+      for (Integer entry : list) {
+        out.writeInt(entry);
+      }
+    } else {
+      InternalDataSerializer.writeArrayLength(-1, out);
+    }
+  }
+
+  /**
+   * Any time new serialization format is added then a new enum needs to be added here.
+   *
+   * @since GemFire 6.6.2
+   */
+  private enum SERIALIZATION_VERSION {
+    vINVALID,
+    // includes 6.6.0.x and 6.6.1.x. Note that no serialization changes were made in 6.6 until 6.6.2
+    v660,
+    // 6.6.2.x or later NOTE if you add a new constant make sure and update "latestVersion".
+    v662
+  }
+
+  /**
+   * A listener whose listener methods are invoked when {@link DataSerializer}s and {@link
+   * Instantiator}s are registered. This is part of the fix for bug 31422.
+   *
+   * @see InternalDataSerializer#addRegistrationListener
+   * @see InternalDataSerializer#removeRegistrationListener
+   */
+  public interface RegistrationListener {
+
+    /**
+     * Invoked when a new {@code Instantiator} is {@linkplain Instantiator#register(Instantiator)
+     * registered}.
+     */
+    void newInstantiator(Instantiator instantiator);
+
+    /**
+     * Invoked when a new {@code DataSerializer} is {@linkplain DataSerializer#register(Class)
+     * registered}.
+     */
+    void newDataSerializer(DataSerializer ds);
+  }
+
+  /**
+   * A SerializerAttributesHolder holds information required to load a DataSerializer and exists to
+   * allow client/server connections to be created more quickly than they would if the
+   * DataSerializer information downloaded from the server were used to immediately load the
+   * corresponding classes.
+   */
+  public static class SerializerAttributesHolder {
+    private String className = "";
+    private EventID eventId = null;
+    private ClientProxyMembershipID proxyId = null;
+    private int id = 0;
+
+    SerializerAttributesHolder() {}
+
+    SerializerAttributesHolder(String name, EventID event, ClientProxyMembershipID proxy, int id) {
+      this.className = name;
+      this.eventId = event;
+      this.proxyId = proxy;
+      this.id = id;
+    }
+
+    /**
+     * @return String the classname of the data serializer this instance represents.
+     */
+    public String getClassName() {
+      return this.className;
+    }
+
+    public EventID getEventId() {
+      return this.eventId;
+    }
+
+    public ClientProxyMembershipID getProxyId() {
+      return this.proxyId;
+    }
+
+    public int getId() {
+      return this.id;
+    }
+
+    @Override
+    public String toString() {
+      return "SerializerAttributesHolder[name=" + this.className + ",id=" + this.id + ",eventId="
+          + this.eventId + ']';
+    }
+  }
+
+  /**
+   * A marker object for {@code DataSerializer}s that have not been registered. Using this marker
+   * object allows us to asynchronously send {@code DataSerializer} registration updates. If the
+   * serialized bytes arrive at a VM before the registration message does, the deserializer will
+   * wait an amount of time for the registration message to arrive.
+   */
+  abstract static class Marker {
+    /**
+     * The DataSerializer that is filled in upon registration
+     */
+    protected DataSerializer serializer = null;
+
+    /**
+     * set to true once setSerializer is called.
+     */
+    boolean hasBeenSet = false;
+
+    abstract DataSerializer getSerializer();
+
+    /**
+     * Sets the serializer associated with this marker. It will notify any threads that are waiting
+     * for the serializer to be registered.
+     */
+    void setSerializer(DataSerializer serializer) {
+      synchronized (this) {
+        this.hasBeenSet = true;
+        this.serializer = serializer;
+        this.notifyAll();
+      }
+    }
+  }
+
+  /**
+   * A marker object for {@code DataSerializer}s that have not been registered. Using this marker
+   * object allows us to asynchronously send {@code DataSerializer} registration updates. If the
+   * serialized bytes arrive at a VM before the registration message does, the deserializer will
+   * wait an amount of time for the registration message to arrive. Made public for unit test
+   * access.
+   *
+   * @since GemFire 5.7
+   */
+  public static class GetMarker extends Marker {
     /**
      * Number of milliseconds to wait. Also used by InternalInstantiator. Note that some tests set
      * this to a small amount to speed up failures. Made public for unit test access.
@@ -3452,26 +3621,23 @@ public abstract class InternalDataSerializer extends DataSerializer {
    */
   public static class RegistrationMessage extends SerialDistributionMessage {
     /**
-     * The id of the {@code DataSerializer} that was registered since 5.7 an int instead of a byte
+     * The versions in which this message was modified
      */
-    private int id;
-
+    private static final Version[] dsfidVersions = new Version[] {};
     /**
      * The eventId of the {@code DataSerializer} that was registered
      */
     protected EventID eventId;
-
+    /**
+     * The id of the {@code DataSerializer} that was registered since 5.7 an int instead of a byte
+     */
+    private int id;
     /**
      * The name of the {@code DataSerializer} class
      */
     private String className;
 
     /**
-     * The versions in which this message was modified
-     */
-    private static final Version[] dsfidVersions = new Version[] {};
-
-    /**
      * Constructor for {@code DataSerializable}
      */
     public RegistrationMessage() {}
@@ -3592,28 +3758,6 @@ public abstract class InternalDataSerializer extends DataSerializer {
   }
 
   /**
-   * A listener whose listener methods are invoked when {@link DataSerializer}s and {@link
-   * Instantiator}s are registered. This is part of the fix for bug 31422.
-   *
-   * @see InternalDataSerializer#addRegistrationListener
-   * @see InternalDataSerializer#removeRegistrationListener
-   */
-  public interface RegistrationListener {
-
-    /**
-     * Invoked when a new {@code Instantiator} is {@linkplain Instantiator#register(Instantiator)
-     * registered}.
-     */
-    void newInstantiator(Instantiator instantiator);
-
-    /**
-     * Invoked when a new {@code DataSerializer} is {@linkplain DataSerializer#register(Class)
-     * registered}.
-     */
-    void newDataSerializer(DataSerializer ds);
-  }
-
-  /**
    * An {@code ObjectInputStream} whose {@link #resolveClass} method loads classes from the current
    * context class loader.
    */
@@ -3716,235 +3860,4 @@ public abstract class InternalDataSerializer extends DataSerializer {
   protected abstract static class WellKnownPdxDS extends WellKnownDS {
     // subclasses need to implement toData
   }
-
-  public static void writeObjectArray(Object[] array, DataOutput out, boolean ensureCompatibility)
-      throws IOException {
-    InternalDataSerializer.checkOut(out);
-    int length;
-    if (array == null) {
-      length = -1;
-    } else {
-      length = array.length;
-    }
-    InternalDataSerializer.writeArrayLength(length, out);
-    if (logger.isTraceEnabled(LogMarker.SERIALIZER_VERBOSE)) {
-      logger.trace(LogMarker.SERIALIZER_VERBOSE, "Writing Object array of length {}", length);
-    }
-    if (length >= 0) {
-      writeClass(array.getClass().getComponentType(), out);
-      for (int i = 0; i < length; i++) {
-        basicWriteObject(array[i], out, ensureCompatibility);
-      }
-    }
-  }
-
-  // Variable Length long encoded as int in next 4 bytes
-  private static final byte INT_VL = 126;
-
-  // Variable Length long encoded as long in next 8 bytes
-  private static final byte LONG_VL = 127;
-
-  private static final int MAX_BYTE_VL = 125;
-
-  /**
-   * Write a variable length long the old way (pre 7.0). Use this only in contexts where you might
-   * need to communicate with pre 7.0 members or files.
-   */
-  public static void writeVLOld(long data, DataOutput out) throws IOException {
-    if (data < 0) {
-      Assert.fail("Data expected to be >=0 is " + data);
-    }
-    if (data <= MAX_BYTE_VL) {
-      out.writeByte((byte) data);
-    } else if (data <= 0x7FFF) {
-      // set the sign bit to indicate a short
-      out.write(((int) data >>> 8 | 0x80) & 0xFF);
-      out.write((int) data >>> 0 & 0xFF);
-    } else if (data <= Integer.MAX_VALUE) {
-      out.writeByte(INT_VL);
-      out.writeInt((int) data);
-    } else {
-      out.writeByte(LONG_VL);
-      out.writeLong(data);
-    }
-  }
-
-  /**
-   * Write a variable length long the old way (pre 7.0). Use this only in contexts where you might
-   * need to communicate with pre 7.0 members or files.
-   */
-  public static long readVLOld(DataInput in) throws IOException {
-    byte code = in.readByte();
-    long result;
-    if (code < 0) {
-      // mask off sign bit
-      result = code & 0x7F;
-      result <<= 8;
-      result |= in.readByte() & 0xFF;
-    } else if (code <= MAX_BYTE_VL) {
-      result = code;
-    } else if (code == INT_VL) {
-      result = in.readInt();
-    } else if (code == LONG_VL) {
-      result = in.readLong();
-    } else {
-      throw new IllegalStateException("unexpected variable length code=" + code);
-    }
-    return result;
-  }
-
-  /**
-   * Encode a long as a variable length array.
-   *
-   * This method is appropriate for unsigned integers. For signed integers, negative values will
-   * always consume 10 bytes, so it is recommended to use writeSignedVL instead.
-   *
-   * This is taken from the varint encoding in protobufs (BSD licensed). See
-   * https://developers.google.com/protocol-buffers/docs/encoding
-   */
-  public static void writeUnsignedVL(long data, DataOutput out) throws IOException {
-    while (true) {
-      if ((data & ~0x7FL) == 0) {
-        out.writeByte((int) data);
-        return;
-      } else {
-        out.writeByte((int) data & 0x7F | 0x80);
-        data >>>= 7;
-      }
-    }
-  }
-
-  /**
-   * Decode a long as a variable length array.
-   *
-   * This is taken from the varint encoding in protobufs (BSD licensed). See
-   * https://developers.google.com/protocol-buffers/docs/encoding
-   */
-  public static long readUnsignedVL(DataInput in) throws IOException {
-    int shift = 0;
-    long result = 0;
-    while (shift < 64) {
-      final byte b = in.readByte();
-      result |= (long) (b & 0x7F) << shift;
-      if ((b & 0x80) == 0) {
-        return result;
-      }
-      shift += 7;
-    }
-    throw new GemFireIOException("Malformed variable length integer");
-  }
-
-  /**
-   * Encode a signed long as a variable length array.
-   *
-   * This method is appropriate for signed integers. It uses zig zag encoding to so that negative
-   * numbers will be represented more compactly. For unsigned values, writeUnsignedVL will be more
-   * efficient.
-   */
-  public static void writeSignedVL(long data, DataOutput out) throws IOException {
-    writeUnsignedVL(encodeZigZag64(data), out);
-  }
-
-  /**
-   * Decode a signed long as a variable length array.
-   *
-   * This method is appropriate for signed integers. It uses zig zag encoding to so that negative
-   * numbers will be represented more compactly. For unsigned values, writeUnsignedVL will be more
-   * efficient.
-   */
-  public static long readSignedVL(DataInput in) throws IOException {
-    return decodeZigZag64(readUnsignedVL(in));
-  }
-
-  /**
-   * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
-   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
-   * to be varint encoded, thus always taking 10 bytes on the wire.)
-   *
-   * @param n An unsigned 64-bit integer, stored in a signed int because Java has no explicit
-   *        unsigned support.
-   * @return A signed 64-bit integer.
-   *
-   *         This is taken from the varint encoding in protobufs (BSD licensed). See
-   *         https://developers.google.com/protocol-buffers/docs/encoding
-   */
-  private static long decodeZigZag64(final long n) {
-    return n >>> 1 ^ -(n & 1);
-  }
-
-  /**
-   * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
-   * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
-   * to be varint encoded, thus always taking 10 bytes on the wire.)
-   *
-   * @param n A signed 64-bit integer.
-   * @return An unsigned 64-bit integer, stored in a signed int because Java has no explicit
-   *         unsigned support.
-   *
-   *         This is taken from the varint encoding in protobufs (BSD licensed). See
-   *         https://developers.google.com/protocol-buffers/docs/encoding
-   */
-  private static long encodeZigZag64(final long n) {
-    // Note: the right-shift must be arithmetic
-    return n << 1 ^ n >> 63;
-  }
-
-  /* test only method */
-  public static int calculateBytesForTSandDSID(int dsid) {
-    HeapDataOutputStream out = new HeapDataOutputStream(4 + 8, Version.CURRENT);
-    long now = System.currentTimeMillis();
-    try {
-      writeUnsignedVL(now, out);
-      writeUnsignedVL(InternalDataSerializer.encodeZigZag64(dsid), out);
-    } catch (IOException ignored) {
-      return 0;
-    }
-    return out.size();
-  }
-
-  public static final boolean LOAD_CLASS_EACH_TIME =
-      Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "loadClassOnEveryDeserialization");
-
-  private static final CopyOnWriteHashMap<String, WeakReference<Class<?>>> classCache =
-      LOAD_CLASS_EACH_TIME ? null : new CopyOnWriteHashMap<>();
-
-  private static final Object cacheAccessLock = new Object();
-
-  public static Class<?> getCachedClass(String p_className) throws ClassNotFoundException {
-    String className = processIncomingClassName(p_className);
-    if (LOAD_CLASS_EACH_TIME) {
-      return ClassPathLoader.getLatest().forName(className);
-    } else {
-      Class<?> result = getExistingCachedClass(className);
-      if (result == null) {
-        // Do the forName call outside the sync to fix bug 46172
-        result = ClassPathLoader.getLatest().forName(className);
-        synchronized (cacheAccessLock) {
-          Class<?> cachedClass = getExistingCachedClass(className);
-          if (cachedClass == null) {
-            classCache.put(className, new WeakReference<>(result));
-          } else {
-            result = cachedClass;
-          }
-        }
-      }
-      return result;
-    }
-  }
-
-  private static Class<?> getExistingCachedClass(String className) {
-    WeakReference<Class<?>> wr = classCache.get(className);
-    Class<?> result = null;
-    if (wr != null) {
-      result = wr.get();
-    }
-    return result;
-  }
-
-  public static void flushClassCache() {
-    if (classCache != null) {
-      // Not locking classCache during clear as doing so causes a deadlock in the DeployedJar
-      classCache.clear();
-    }
-  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java b/geode-core/src/main/java/org/apache/geode/internal/util/DscodeHelper.java
similarity index 52%
copy from geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java
copy to geode-core/src/main/java/org/apache/geode/internal/util/DscodeHelper.java
index 7bc7684..30a9f9b 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/util/DscodeHelper.java
@@ -12,28 +12,27 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal;
+package org.apache.geode.internal.util;
 
-import static org.junit.Assert.assertFalse;
+import java.io.IOException;
+import java.util.Arrays;
 
-import java.util.HashSet;
-import java.util.Set;
+import org.apache.geode.internal.DSCODE;
 
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+public class DscodeHelper {
 
-import org.apache.geode.test.junit.categories.SerializationTest;
+  private static final DSCODE[] dscodes = new DSCODE[128];
 
-@Category({SerializationTest.class})
-public class DSCODETest {
-  @Test
-  public void testNoDuplicateByteValues() throws Exception {
-    Set<Integer> previouslySeen = new HashSet<>();
-    for (DSCODE value : DSCODE.values()) {
-      final int integerValue = (int) value.toByte();
-      assertFalse("Each byte value should only occur with a single header byte enumerate",
-          previouslySeen.contains(integerValue));
-      previouslySeen.add(integerValue);
+  static {
+    Arrays.stream(DSCODE.values()).filter(dscode -> dscode.toByte() >= 0)
+        .forEach(dscode -> dscodes[dscode.toByte()] = dscode);
+  }
+
+  public static DSCODE toDSCODE(final byte value) throws IOException {
+    try {
+      return dscodes[value];
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new IOException("Unknown header byte: " + value);
     }
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java b/geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java
index 7bc7684..7240825 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/DSCODETest.java
@@ -15,13 +15,18 @@
 package org.apache.geode.internal;
 
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
 
+import java.io.IOException;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.internal.util.DscodeHelper;
 import org.apache.geode.test.junit.categories.SerializationTest;
 
 @Category({SerializationTest.class})
@@ -36,4 +41,17 @@ public class DSCODETest {
       previouslySeen.add(integerValue);
     }
   }
+
+  @Test
+  public void testGetEnumFromByte() {
+    Arrays.stream(DSCODE.values())
+        .filter(dscode -> dscode != DSCODE.RESERVED_FOR_FUTURE_USE && dscode != DSCODE.ILLEGAL)
+        .forEach(dscode -> {
+          try {
+            Assert.assertEquals(dscode, DscodeHelper.toDSCODE(dscode.toByte()));
+          } catch (IOException e) {
+            fail("No exception should have been caught, as the \"error\" codes are filtered out.");
+          }
+        });
+  }
 }


Mime
View raw message