io.deephaven.tuple.serialization.SerializationUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of deephaven-engine-tuple Show documentation
Show all versions of deephaven-engine-tuple Show documentation
Engine Tuples: Value sequences for use in aggregations, joins, and indexing
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.tuple.serialization;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.util.function.ThrowingConsumer;
import io.deephaven.util.function.ThrowingSupplier;
import org.jetbrains.annotations.NotNull;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Constructor;
import java.time.Instant;
import java.util.Date;
/**
* Utility class for faster type-specific Object serialization and deserialization.
*/
public class SerializationUtils {
public interface Writer extends ThrowingConsumer {
}
/**
* Get a serializing consumer for the supplied item class and output.
*
* @param itemClass The item class
* @param out The output
* @return A new serializing consumer
*/
public static Writer getWriter(@NotNull final Class itemClass,
@NotNull final ObjectOutput out) {
if (itemClass == Byte.class) {
return k -> out.writeByte((Byte) k);
}
if (itemClass == Short.class) {
return k -> out.writeShort((Short) k);
}
if (itemClass == Integer.class) {
return k -> out.writeInt((Integer) k);
}
if (itemClass == Long.class) {
return k -> out.writeLong((Long) k);
}
if (itemClass == Float.class) {
return k -> out.writeFloat((Float) k);
}
if (itemClass == Double.class) {
return k -> out.writeDouble((Double) k);
}
if (itemClass == Boolean.class) {
return k -> out.writeBoolean((Boolean) k);
}
if (itemClass == Character.class) {
return k -> out.writeChar((Character) k);
}
if (itemClass == String.class) {
return k -> out.writeUTF((String) k);
}
if (itemClass == Instant.class) {
return k -> out.writeLong(DateTimeUtils.epochNanos(((Instant) k)));
}
if (itemClass == Date.class) {
return k -> out.writeLong(((Date) k).getTime());
}
if (StreamingExternalizable.class.isAssignableFrom(itemClass)) {
final TIntObjectMap cachedWriters = new TIntObjectHashMap<>();
return k -> ((StreamingExternalizable) k).writeExternalStreaming(out, cachedWriters);
}
if (Externalizable.class.isAssignableFrom(itemClass)) {
return k -> ((Externalizable) k).writeExternal(out);
}
return out::writeObject;
}
public interface Reader extends ThrowingSupplier {
}
/**
* Get a deserializing supplier for the supplied item class and input.
*
* @param itemClass The item class
* @param in The input
* @return A new deserializing supplier
*/
@SuppressWarnings("unchecked")
public static Reader getReader(@NotNull final Class itemClass,
@NotNull final ObjectInput in) {
if (itemClass == Byte.class) {
return () -> (ITEM_TYPE) Byte.valueOf(in.readByte());
}
if (itemClass == Short.class) {
return () -> (ITEM_TYPE) Short.valueOf(in.readShort());
}
if (itemClass == Integer.class) {
return () -> (ITEM_TYPE) Integer.valueOf(in.readInt());
}
if (itemClass == Long.class) {
return () -> (ITEM_TYPE) Long.valueOf(in.readLong());
}
if (itemClass == Float.class) {
return () -> (ITEM_TYPE) Float.valueOf(in.readFloat());
}
if (itemClass == Double.class) {
return () -> (ITEM_TYPE) Double.valueOf(in.readDouble());
}
if (itemClass == Boolean.class) {
return () -> (ITEM_TYPE) Boolean.valueOf(in.readBoolean());
}
if (itemClass == Character.class) {
return () -> (ITEM_TYPE) Character.valueOf(in.readChar());
}
if (itemClass == String.class) {
return () -> (ITEM_TYPE) in.readUTF();
}
if (itemClass == Instant.class) {
return () -> (ITEM_TYPE) DateTimeUtils.epochNanosToInstant(in.readLong());
}
if (itemClass == Date.class) {
return () -> (ITEM_TYPE) new Date(in.readLong());
}
if (StreamingExternalizable.class.isAssignableFrom(itemClass)) {
final Constructor constructor;
try {
constructor = itemClass.getConstructor();
} catch (NoSuchMethodException e) {
throw new UnsupportedOperationException("Can't deserialize keys of type " + itemClass
+ ", could not get no-arg constructor for StreamingExternalizable type");
}
final TIntObjectMap cachedReaders = new TIntObjectHashMap<>();
return () -> {
final StreamingExternalizable key = (StreamingExternalizable) constructor.newInstance();
key.readExternalStreaming(in, cachedReaders);
return (ITEM_TYPE) key;
};
}
if (Externalizable.class.isAssignableFrom(itemClass)) {
final Constructor constructor;
try {
constructor = itemClass.getConstructor();
} catch (NoSuchMethodException e) {
throw new UnsupportedOperationException("Can't deserialize keys of type " + itemClass
+ ", could not get no-arg constructor for Externalizable type");
}
return () -> {
final Externalizable key = (Externalizable) constructor.newInstance();
key.readExternal(in);
return (ITEM_TYPE) key;
};
}
return () -> (ITEM_TYPE) in.readObject();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy