明确 JfireSE 只能运行在单例中。SerializrFactory 和 JfireSE 都是有状态的类,无法共享。

master
linbin 2024-09-12 16:53:05 +08:00
parent c0e7307443
commit 5148e6544c
9 changed files with 100 additions and 225 deletions

View File

@ -1,5 +1,7 @@
package com.jfirer.se2;
import com.jfirer.se2.classinfo.ClassInfo;
public interface JfireSE
{
byte NULL = 0;
@ -28,7 +30,19 @@ public interface JfireSE
return new JfireSEConfig().build();
}
byte[] write(Object instance);
byte[] serialize(Object instance);
Object read(byte[] bytes);
Object deSerialize(byte[] bytes);
ClassInfo getOrCreateClassInfo(Class<?> clazz);
ClassInfo find(byte[] classNameBytes, int classId);
ClassInfo find(int classId);
Object readByNameIdContent(ByteArray byteArray, boolean refTracking);
Object readByIdInstanceId(ByteArray byteArray);
Object readByIdContent(ByteArray byteArray, boolean refTracking);
}

View File

@ -26,6 +26,7 @@ public class JfireSEImpl implements JfireSE
private ByteArray byteArray = new ByteArray(1000);
private ClassInfo classInfoCache;
private Map<Class<?>, ClassInfo> classInfoMap = new HashMap<>();
private SerializerFactory serializerFactory = new SerializerFactory(this);
private Map<byte[], ClassInfo> classInfoCacheMap = new HashMap<>();
public JfireSEImpl(boolean refTracking, StaticClasInfo[] staticClasInfos)
@ -39,6 +40,7 @@ public class JfireSEImpl implements JfireSE
dyncmicClassId = staticClassId + 1;
}
@Override
public ClassInfo getOrCreateClassInfo(Class<?> clazz)
{
if (classInfoCache != null && classInfoCache.getClazz() == clazz)
@ -60,7 +62,7 @@ public class JfireSEImpl implements JfireSE
DynamicClassInfo dynamicClassInfo = new DynamicClassInfo((short) dyncmicClassId, clazz, refTracking);
serializedClassInfos[dyncmicClassId] = dynamicClassInfo;
dyncmicClassId++;
Serializer serializer = SerializerFactory.getSerializer(clazz, this);
Serializer serializer = serializerFactory.getSerializer(clazz);
dynamicClassInfo.setSerializer(serializer);
classInfoCache = dynamicClassInfo;
return dynamicClassInfo;
@ -75,7 +77,7 @@ public class JfireSEImpl implements JfireSE
}
@Override
public byte[] write(Object instance)
public byte[] serialize(Object instance)
{
if (instance == null)
{
@ -93,7 +95,7 @@ public class JfireSEImpl implements JfireSE
}
@Override
public Object read(byte[] bytes)
public Object deSerialize(byte[] bytes)
{
ByteArray stream = new ByteArray(bytes);
byte b = stream.get();
@ -132,6 +134,7 @@ public class JfireSEImpl implements JfireSE
}
}
@Override
public ClassInfo find(byte[] classNameBytes, int classId)
{
try
@ -164,8 +167,32 @@ public class JfireSEImpl implements JfireSE
}
}
@Override
public ClassInfo find(int classId)
{
return deSerializedClassInfos[classId];
}
@Override
public Object readByNameIdContent(ByteArray byteArray, boolean refTracking)
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = find(classNameBytes, classId);
return refTracking ? classInfo.readWithTrack(byteArray) : classInfo.readWithoutTrack(byteArray);
}
@Override
public Object readByIdInstanceId(ByteArray byteArray)
{
int classId = byteArray.readPositiveVarInt();
return find(classId).getInstanceById(byteArray.readPositiveVarInt());
}
@Override
public Object readByIdContent(ByteArray byteArray, boolean refTracking)
{
ClassInfo classInfo = find(byteArray.readPositiveVarInt());
return refTracking ? classInfo.readWithTrack(byteArray) : classInfo.readWithoutTrack(byteArray);
}
}

View File

@ -1,5 +1,6 @@
package com.jfirer.se2.serializer;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.serializer.impl.ArraySerializer;
import com.jfirer.se2.serializer.impl.BoxedArraySerializer;
@ -11,10 +12,12 @@ import java.util.concurrent.ConcurrentHashMap;
public class SerializerFactory
{
private static Map<Class<?>, Serializer> store = new ConcurrentHashMap<>();
private Map<Class<?>, Serializer> store = new ConcurrentHashMap<>();
private JfireSE jfireSE;
static
public SerializerFactory(JfireSE jfireSE)
{
this.jfireSE = jfireSE;
store.put(int[].class, new PrimitiveArraySerializer.IntArraySerializer());
store.put(long[].class, new PrimitiveArraySerializer.LongArraySerializer());
store.put(byte[].class, new PrimitiveArraySerializer.ByteArraySerializer());
@ -34,7 +37,7 @@ public class SerializerFactory
store.put(String[].class, new BoxedArraySerializer.StringArraySerializer());
}
public static Serializer getSerializer(Class<?> clazz, JfireSEImpl jfireSE)
public Serializer getSerializer(Class<?> clazz)
{
if (clazz.isArray())
{

View File

@ -2,7 +2,6 @@ package com.jfirer.se2.serializer.impl;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.classinfo.ClassInfo;
import com.jfirer.se2.classinfo.RefTracking;
import com.jfirer.se2.serializer.Serializer;
@ -11,11 +10,11 @@ import java.lang.reflect.Array;
public class ArraySerializer<T> implements Serializer
{
private Class<?> componentType;
private final ClassInfo typeDefinedClassInfo;
private JfireSEImpl jfireSE;
private Class<?> componentType;
private final ClassInfo typeDefinedClassInfo;
private JfireSE jfireSE;
public ArraySerializer(Class<T[]> clazz, JfireSEImpl jfireSE)
public ArraySerializer(Class<T[]> clazz, JfireSE jfireSE)
{
this.jfireSE = jfireSE;
this.componentType = clazz.getComponentType();
@ -49,8 +48,6 @@ public class ArraySerializer<T> implements Serializer
}
}
@Override
public Object read(ByteArray byteArray, RefTracking refTracking)
{
@ -71,43 +68,12 @@ public class ArraySerializer<T> implements Serializer
{
switch (flag)
{
case JfireSE.NAME_ID_CONTENT_TRACK ->
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classNameBytes, classId);
arr[i] = (T) classInfo.readWithTrack(byteArray);
}
case JfireSE.NAME_ID_CONTENT_UN_TRACK ->
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classNameBytes, classId);
arr[i] = (T) classInfo.readWithoutTrack(byteArray);
}
case JfireSE.ID_INSTANCE_ID ->
{
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classId);
arr[i] = (T) classInfo.getInstanceById(byteArray.readPositiveVarInt());
}
case JfireSE.ID_CONTENT_TRACK ->
{
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classId);
arr[i] = (T) classInfo.readWithTrack(byteArray);
}
case JfireSE.ID_CONTENT_UN_TRACK ->
{
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classId);
arr[i] = (T) classInfo.readWithoutTrack(byteArray);
}
case JfireSE.INSTANCE_ID ->
{
int instanceId = byteArray.readPositiveVarInt();
arr[i] = (T) typeDefinedClassInfo.getInstanceById(instanceId);
}
case JfireSE.NAME_ID_CONTENT_TRACK -> arr[i] = (T) jfireSE.readByNameIdContent(byteArray, true);
case JfireSE.NAME_ID_CONTENT_UN_TRACK -> arr[i] = (T) jfireSE.readByNameIdContent(byteArray, false);
case JfireSE.ID_INSTANCE_ID -> arr[i] = (T) jfireSE.readByIdInstanceId(byteArray);
case JfireSE.ID_CONTENT_TRACK -> arr[i] = (T) jfireSE.readByIdContent(byteArray, true);
case JfireSE.ID_CONTENT_UN_TRACK -> arr[i] = (T) jfireSE.readByIdContent(byteArray, false);
case JfireSE.INSTANCE_ID -> arr[i] = (T) typeDefinedClassInfo.getInstanceById(byteArray.readPositiveVarInt());
case JfireSE.CONTENT_TRACK -> arr[i] = (T) typeDefinedClassInfo.readWithTrack(byteArray);
case JfireSE.CONTENT_UN_TRACK -> arr[i] = (T) typeDefinedClassInfo.readWithoutTrack(byteArray);
default -> throw new RuntimeException("未知的序列化类型");

View File

@ -2,7 +2,6 @@ package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.classinfo.ClassInfo;
import java.lang.reflect.Field;
@ -10,9 +9,9 @@ import java.lang.reflect.Field;
public class FinalFieldInfo extends FieldInfo
{
private ClassInfo classInfo;
private JfireSEImpl jfireSE;
private JfireSE jfireSE;
public FinalFieldInfo(Field field, JfireSEImpl jfireSE)
public FinalFieldInfo(Field field, JfireSE jfireSE)
{
super(field);
classInfo = jfireSE.getOrCreateClassInfo(field.getType());
@ -45,22 +44,9 @@ public class FinalFieldInfo extends FieldInfo
{
switch (flag)
{
case JfireSE.INSTANCE_ID ->
{
int instanceId = byteArray.readPositiveVarInt();
Object property = classInfo.getInstanceById(instanceId);
accessor.setObject(instance, property);
}
case JfireSE.CONTENT_TRACK ->
{
Object property = classInfo.readWithTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.CONTENT_UN_TRACK ->
{
Object property = classInfo.readWithoutTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.INSTANCE_ID -> accessor.setObject(instance, classInfo.getInstanceById(byteArray.readPositiveVarInt()));
case JfireSE.CONTENT_TRACK -> accessor.setObject(instance, classInfo.readWithTrack(byteArray));
case JfireSE.CONTENT_UN_TRACK -> accessor.setObject(instance, classInfo.readWithoutTrack(byteArray));
default -> throw new RuntimeException("flag:" + flag);
}
}

View File

@ -65,7 +65,7 @@ public class ObjectSerializer implements Serializer
}
}
public static List<FieldInfo> parse(Class<?> clazz, JfireSEImpl jfireSE)
public static List<FieldInfo> parse(Class<?> clazz, JfireSE jfireSE)
{
Class type = clazz;
List<Field> fields = new ArrayList<>();
@ -106,7 +106,7 @@ public class ObjectSerializer implements Serializer
return list;
}
public static Serializer buildCompileVersion(Class<?> clazz, JfireSEImpl jfireSE)
public static Serializer buildCompileVersion(Class<?> clazz, JfireSE jfireSE)
{
List<FieldInfo> parse = parse(clazz, jfireSE);
ClassModel classModel = new ClassModel("ObjectSerializer_compile_" + COMPILE_COUNT);
@ -129,10 +129,10 @@ public class ObjectSerializer implements Serializer
classModel.addImport(FieldInfo.class);
classModel.addImport(ByteArray.class);
classModel.addField(new FieldModel("UNSAFE", Unsafe.class, "Unsafe.getUnsafe()", classModel));
classModel.addField(new FieldModel("jfireSE", JfireSEImpl.class, classModel));
classModel.addField(new FieldModel("jfireSE", JfireSE.class, classModel));
classModel.addField(new FieldModel("clazz", Class.class, classModel));
ConstructorModel constructorModel = new ConstructorModel(classModel);
constructorModel.setParamTypes(Class.class, JfireSEImpl.class, List.class);
constructorModel.setParamTypes(Class.class, JfireSE.class, List.class);
constructorModel.setParamNames("clazz", "jfireSE", "list");
StringBuilder constructorBody = new StringBuilder();
constructorBody.append("""
@ -471,76 +471,15 @@ public class ObjectSerializer implements Serializer
readBody.append("else{\r\n");
readBody.append("switch(" + flagName + "){\r\n");
readBody.append("""
case JfireSE.NAME_ID_CONTENT_TRACK->
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classNameBytes, classId);
Object property = classInfo.readWithTrack(byteArray);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)));
readBody.append("""
case JfireSE.NAME_ID_CONTENT_UN_TRACK->
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classNameBytes,classId);
Object property = classInfo.readWithoutTrack(byteArray);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)));
readBody.append("""
case JfireSE.ID_INSTANCE_ID->
{
int classId = byteArray.readPositiveVarInt();
int instanceId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classId);
Object property = classInfo.getInstanceById(instanceId);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)));
readBody.append("""
case JfireSE.ID_CONTENT_TRACK->
{
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classId);
Object property = classInfo.readWithTrack(byteArray);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)));
readBody.append("""
case JfireSE.ID_CONTENT_UN_TRACK->
{
int classId = byteArray.readPositiveVarInt();
ClassInfo classInfo = jfireSE.find(classId);
Object property = classInfo.readWithoutTrack(byteArray);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)));
readBody.append("""
case JfireSE.INSTANCE_ID ->
{
int instanceId = byteArray.readPositiveVarInt();
Object property = firstClassInfo.getInstanceById(instanceId);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l))//
.replace("firstClassInfo", firstClassInfoProperty));
readBody.append("""
case JfireSE.CONTENT_TRACK ->
{
Object property = firstClassInfo.readWithTrack(byteArray);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)).replace("firstClassInfo", firstClassInfoProperty));
readBody.append("""
case JfireSE.CONTENT_UN_TRACK ->
{
Object property = firstClassInfo.readWithoutTrack(byteArray);
UNSAFE.putReference(instance,offset, property);
}
""".replace("offset", String.valueOf(l)).replace("firstClassInfo", firstClassInfoProperty));
case JfireSE.NAME_ID_CONTENT_TRACK-> UNSAFE.putReference(instance,offset, jfireSE.readByNameIdContent(byteArray, true));
case JfireSE.NAME_ID_CONTENT_UN_TRACK->UNSAFE.putReference(instance,offset, jfireSE.readByNameIdContent(byteArray, false));
case JfireSE.ID_INSTANCE_ID->UNSAFE.putReference(instance,offset, jfireSE.readByIdInstanceId(byteArray));
case JfireSE.ID_CONTENT_TRACK->UNSAFE.putReference(instance,offset, jfireSE.readByIdContent(byteArray, true));
case JfireSE.ID_CONTENT_UN_TRACK-> UNSAFE.putReference(instance,offset, jfireSE.readByIdContent(byteArray, false));
case JfireSE.INSTANCE_ID -> UNSAFE.putReference(instance,offset, firstClassInfo.getInstanceById(byteArray.readPositiveVarInt()));
case JfireSE.CONTENT_TRACK -> UNSAFE.putReference(instance,offset, firstClassInfo.readWithTrack(byteArray));
case JfireSE.CONTENT_UN_TRACK -> UNSAFE.putReference(instance,offset, firstClassInfo.readWithoutTrack(byteArray));
""".replace("offset", String.valueOf(l)) .replace("firstClassInfo", firstClassInfoProperty));
readBody.append("default -> throw new RuntimeException(\"flag:\" + " + flagName + ");\r\n");
readBody.append("}\r\n");
readBody.append("}\r\n");
@ -575,22 +514,9 @@ public class ObjectSerializer implements Serializer
{
switch (flag)
{
case JfireSE.INSTANCE_ID ->
{
int instanceId = byteArray.readPositiveVarInt();
Object property = classInfo.getInstanceById(instanceId);
UNSAFE.putReference(instance,offset,property);
}
case JfireSE.CONTENT_TRACK ->
{
Object property = classInfo.readWithTrack(byteArray);
UNSAFE.putReference(instance,offset,property);
}
case JfireSE.CONTENT_UN_TRACK ->
{
Object property = classInfo.readWithoutTrack(byteArray);
UNSAFE.putReference(instance,offset,property);
}
case JfireSE.INSTANCE_ID -> UNSAFE.putReference(instance,offset,classInfo.getInstanceById(byteArray.readPositiveVarInt()));
case JfireSE.CONTENT_TRACK -> UNSAFE.putReference(instance,offset,classInfo.readWithTrack(byteArray));
case JfireSE.CONTENT_UN_TRACK -> UNSAFE.putReference(instance,offset,classInfo.readWithoutTrack(byteArray));
default -> throw new RuntimeException("flag:" + flag);
}
}
@ -620,7 +546,7 @@ public class ObjectSerializer implements Serializer
classModel.putMethodModel(readMethod);
CompileHelper compiler = new CompileHelper(Thread.currentThread().getContextClassLoader());
Class<?> compile = compiler.compile(classModel);
Serializer compiledObjectSerializer = (Serializer) compile.getDeclaredConstructor(Class.class, JfireSEImpl.class, List.class).newInstance(clazz, jfireSE, parse);
Serializer compiledObjectSerializer = (Serializer) compile.getDeclaredConstructor(Class.class, JfireSE.class, List.class).newInstance(clazz, jfireSE, parse);
return compiledObjectSerializer;
}
catch (NoSuchMethodException | IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e)

View File

@ -2,18 +2,17 @@ package com.jfirer.se2.serializer.impl.ObjectSerializer;
import com.jfirer.se2.ByteArray;
import com.jfirer.se2.JfireSE;
import com.jfirer.se2.JfireSEImpl;
import com.jfirer.se2.classinfo.ClassInfo;
import java.lang.reflect.Field;
public class VariableFieldInfo extends FieldInfo
{
private final JfireSEImpl jfireSE;
private ClassInfo classInfo;
private final ClassInfo firstClassInfo;
private final JfireSE jfireSE;
private ClassInfo classInfo;
private final ClassInfo firstClassInfo;
public VariableFieldInfo(Field field, JfireSEImpl jfireSE)
public VariableFieldInfo(Field field, JfireSE jfireSE)
{
super(field);
classInfo = jfireSE.getOrCreateClassInfo(field.getType());
@ -77,60 +76,14 @@ public class VariableFieldInfo extends FieldInfo
{
switch (flag)
{
case JfireSE.NAME_ID_CONTENT_TRACK ->
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
classInfo = jfireSE.find(classNameBytes, classId);
Object property = classInfo.readWithTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.NAME_ID_CONTENT_UN_TRACK ->
{
byte[] classNameBytes = byteArray.readBytesWithSizeEmbedded();
int classId = byteArray.readPositiveVarInt();
classInfo = jfireSE.find(classNameBytes, classId);
Object property = classInfo.readWithoutTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.ID_INSTANCE_ID ->
{
int classId = byteArray.readPositiveVarInt();
int instanceId = byteArray.readPositiveVarInt();
classInfo = jfireSE.find(classId);
Object proeprty = classInfo.getInstanceById(instanceId);
accessor.setObject(instance, proeprty);
}
case JfireSE.ID_CONTENT_TRACK ->
{
int classId = byteArray.readPositiveVarInt();
classInfo = jfireSE.find(classId);
Object property = classInfo.readWithTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.ID_CONTENT_UN_TRACK ->
{
int classId = byteArray.readPositiveVarInt();
classInfo = jfireSE.find(classId);
Object property = classInfo.readWithoutTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.INSTANCE_ID ->
{
int instanceId = byteArray.readPositiveVarInt();
Object property = firstClassInfo.getInstanceById(instanceId);
accessor.setObject(instance, property);
}
case JfireSE.CONTENT_TRACK ->
{
Object property = firstClassInfo.readWithTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.CONTENT_UN_TRACK ->
{
Object property = firstClassInfo.readWithoutTrack(byteArray);
accessor.setObject(instance, property);
}
case JfireSE.NAME_ID_CONTENT_TRACK -> accessor.setObject(instance, jfireSE.readByNameIdContent(byteArray, true));
case JfireSE.NAME_ID_CONTENT_UN_TRACK -> accessor.setObject(instance, jfireSE.readByNameIdContent(byteArray, false));
case JfireSE.ID_INSTANCE_ID -> accessor.setObject(instance, jfireSE.readByIdInstanceId(byteArray));
case JfireSE.ID_CONTENT_TRACK -> accessor.setObject(instance, jfireSE.readByIdContent(byteArray, true));
case JfireSE.ID_CONTENT_UN_TRACK -> accessor.setObject(instance, jfireSE.readByIdContent(byteArray, false));
case JfireSE.INSTANCE_ID -> accessor.setObject(instance, firstClassInfo.getInstanceById(byteArray.readPositiveVarInt()));
case JfireSE.CONTENT_TRACK -> accessor.setObject(instance, firstClassInfo.readWithTrack(byteArray));
case JfireSE.CONTENT_UN_TRACK -> accessor.setObject(instance, firstClassInfo.readWithoutTrack(byteArray));
default -> throw new RuntimeException("flag:" + flag);
}
}

View File

@ -55,7 +55,7 @@ public class BenchMark
@Benchmark
public void testJfireSE()
{
jfireSE.write(data);
jfireSE.serialize(data);
}
public static void main(String[] args) throws RunnerException

View File

@ -37,9 +37,9 @@ public class FunctionTest
sms[0] = new TestDataSm().setC("xx");
testData.setSms(sms);
JfireSE jfireSE = JfireSE.build();
byte[] bytes = jfireSE.write(testData);
Assert.assertEquals(testData, jfireSE.read(bytes));
TestData read = (TestData) jfireSE.read(bytes);
byte[] bytes = jfireSE.serialize(testData);
Assert.assertEquals(testData, jfireSE.deSerialize(bytes));
TestData read = (TestData) jfireSE.deSerialize(bytes);
Assert.assertEquals("xx", read.getSms()[0].getC());
Assert.assertNull(read.getSms()[1]);
}