Skip to content

Instantly share code, notes, and snippets.

@buma
Created November 25, 2015 17:17
Show Gist options
  • Save buma/54601d12481ba88ee49e to your computer and use it in GitHub Desktop.
Save buma/54601d12481ba88ee49e to your computer and use it in GitHub Desktop.
custom FST serializers
package com.conveyal.r5;
import org.nustaq.serialization.FSTClazzInfo;
import org.nustaq.serialization.FSTObjectInput;
import org.nustaq.serialization.FSTObjectOutput;
import org.nustaq.serialization.serializers.FSTArrayListSerializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
public class MyEnumSetListSerializer extends FSTArrayListSerializer {
@Override
public void writeObject(FSTObjectOutput out, Object toWrite, FSTClazzInfo clzInfo, FSTClazzInfo.FSTFieldInfo referencedBy, int streamPosition) throws
IOException {
ArrayList col = (ArrayList)toWrite;
int size = col.size();
if (col.get(0).getClass().getSimpleName().equals("RegularEnumSet")) {
//System.out.println("EnumSet");
EnumSet compl = EnumSet.complementOf((EnumSet)col.get(0));
int[] enums = new int[col.size()];
for (int i = 0; i < size; i++) {
EnumSet o = (EnumSet) col.get(i);
int flag = getBitFlag(o);
enums[i] = flag;
}
out.writeBoolean(true);
out.writeClassTag(compl.iterator().next().getClass());
out.writeObjectInternal(enums, null, null);
} else {
out.writeBoolean(false);
super.writeObject(out, toWrite, clzInfo, referencedBy, streamPosition);
}
}
public <T extends Enum<T>> int getBitFlag(EnumSet<T> enumType) {
int flag = 0;
for (T c : enumType) {
flag |= (1 << c.ordinal());
}
return flag;
}
public <T extends Enum<T>> EnumSet<T> fromBitFlag(Class<T> enumType, int flags) {
EnumSet<T> enumSet = EnumSet.noneOf(enumType);
for (T c : enumType.getEnumConstants()) {
if ((flags & (1 << c.ordinal())) != 0) {
enumSet.add(c);
}
}
return enumSet;
}
@Override
public Object instantiate(Class objectClass, FSTObjectInput in, FSTClazzInfo serializationInfo, FSTClazzInfo.FSTFieldInfo referencee, int streamPosition) throws Exception {
boolean isEnumSetList = in.readBoolean();
if (isEnumSetList) {
Class elemCL = in.readClass().getClazz();
int[] enums = (int[]) in.readObjectInternal(null);
ArrayList res = new ArrayList(enums.length);
for (int i = 0; i < enums.length; i++) {
res.add(fromBitFlag(elemCL, enums[i]));
}
return res;
} else {
return super.instantiate(objectClass, in, serializationInfo, referencee, streamPosition);
}
}
}
package com.conveyal.r5;
import org.nustaq.serialization.FSTBasicObjectSerializer;
import org.nustaq.serialization.FSTClazzInfo;
import org.nustaq.serialization.FSTObjectInput;
import org.nustaq.serialization.FSTObjectOutput;
import java.io.IOException;
import java.util.EnumSet;
/**
* Created by mabu on 25.11.2015.
*/
public class MyEnumSetSerializer extends FSTBasicObjectSerializer {
/**
* @return true if FST can skip a search for same instances in the serialized ObjectGraph. This speeds up reading and writing and makes
* sense for short immutable such as Integer, Short, Character, Date, .. . For those classes it is more expensive (CPU, size) to do a lookup than to just
* write the Object twice in case.
*/
@Override
public boolean alwaysCopy() {
return false;
}
/**
* write the contents of a given object
*
* @param out
* @param toWrite
* @param clzInfo
* @param referencedBy
* @param streamPosition
*/
@Override public void writeObject(FSTObjectOutput out, Object toWrite, FSTClazzInfo clzInfo,
FSTClazzInfo.FSTFieldInfo referencedBy, int streamPosition) throws IOException {
EnumSet enset = (EnumSet) toWrite;
EnumSet compl = EnumSet.complementOf(enset);
out.writeBoolean(enset.size() > 0);
if ( enset.isEmpty() ) { //WTF only way to determine enumtype ..
out.writeClassTag(compl.iterator().next().getClass());
} else {
out.writeClassTag(compl.iterator().next().getClass());
int flag = getBitFlag(enset);
out.writeInt(flag);
}
}
public <T extends Enum<T>> int getBitFlag(EnumSet<T> enumType) {
int flag = 0;
for (T c : enumType) {
flag |= (1 << c.ordinal());
}
return flag;
}
public <T extends Enum<T>> EnumSet<T> fromBitFlag(Class<T> enumType, int flags) {
EnumSet<T> enumSet = EnumSet.noneOf(enumType);
for (T c : enumType.getEnumConstants()) {
if ((flags & (1 << c.ordinal())) != 0) {
enumSet.add(c);
}
}
return enumSet;
}
@Override public Object instantiate(Class objectClass, FSTObjectInput in,
FSTClazzInfo serializationInfo, FSTClazzInfo.FSTFieldInfo referencee, int streamPosition)
throws Exception {
byte len = in.readByte();
Class elemCL = in.readClass().getClazz();
if (len > 0) {
return fromBitFlag(elemCL, in.readInt());
} else {
return EnumSet.noneOf(elemCL);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment