This commit is contained in:
redkale
2024-09-25 14:53:52 +08:00
parent 3e23c9143a
commit 133c280dc2
12 changed files with 106 additions and 65 deletions

View File

@@ -360,6 +360,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
} }
} }
objout.writeObjectE(value); objout.writeObjectE(value);
offerWriter(out, objout);
} }
// ---------------------------------- 可定制方法 ---------------------------------- // ---------------------------------- 可定制方法 ----------------------------------
@@ -375,6 +376,10 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
return out; return out;
} }
protected void offerWriter(W parent, W out) {
// do nothing
}
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
protected void setTag(EnMember member, int tag) { protected void setTag(EnMember member, int tag) {
member.tag = tag; member.tag = tag;

View File

@@ -28,16 +28,20 @@ import org.redkale.util.*;
* @param <T> 序列化的数据类型 * @param <T> 序列化的数据类型
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> { public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
protected final Class typeClass; protected final Class typeClass;
protected final ObjectEncoder<JsonWriter, T> objectEncoder; protected final ObjectEncoder<JsonWriter, T> objectEncoderSelf;
protected JsonDynEncoder(final JsonFactory factory, Type type) { protected JsonDynEncoder(JsonFactory factory, Type type, ObjectEncoder objectEncoderSelf) {
super(type);
this.typeClass = (Class) type; this.typeClass = (Class) type;
this.factory = factory;
this.objectEncoderSelf = objectEncoderSelf;
this.members = objectEncoderSelf.getMembers();
this.inited = true;
factory.register(type, this); factory.register(type, this);
this.objectEncoder = factory.createObjectEncoder(type);
} }
protected static JsonDynEncoder generateDyncEncoder( protected static JsonDynEncoder generateDyncEncoder(
@@ -70,11 +74,8 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz; Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
JsonDynEncoder resultEncoder = JsonDynEncoder resultEncoder =
(JsonDynEncoder) newClazz.getDeclaredConstructor(JsonFactory.class, Type.class) (JsonDynEncoder) newClazz.getConstructor(JsonFactory.class, Type.class, ObjectEncoder.class)
.newInstance(factory, clazz); .newInstance(factory, clazz, selfObjEncoder);
Field selfField = newClazz.getDeclaredField("objectEncoderSelf");
selfField.setAccessible(true);
selfField.set(resultEncoder, selfObjEncoder);
if (mixedNames != null) { if (mixedNames != null) {
for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) { for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) {
Field f = newClazz.getDeclaredField(en.getKey() + "Encoder"); Field f = newClazz.getDeclaredField(en.getKey() + "Encoder");
@@ -116,8 +117,6 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
supDynName, supDynName,
null); null);
fv = cw.visitField(ACC_PROTECTED, "objectEncoderSelf", objEncoderDesc, null, null);
fv.visitEnd();
final int membersSize = elements.size(); final int membersSize = elements.size();
boolean onlyTwoIntFieldObjectFlag = false; // 只包含两个int字段 boolean onlyTwoIntFieldObjectFlag = false; // 只包含两个int字段
boolean onlyOneLatin1FieldObjectFlag = false; // 只包含一个Latin1 String字段 boolean onlyOneLatin1FieldObjectFlag = false; // 只包含一个Latin1 String字段
@@ -161,12 +160,19 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
onlyShotIntLongLatin1MoreFieldObjectFlag = false; // 字段个数必须大于1 onlyShotIntLongLatin1MoreFieldObjectFlag = false; // 字段个数必须大于1
} }
{ // 构造函数 { // 构造函数
mv = (cw.visitMethod(ACC_PUBLIC, "<init>", "(" + jsonfactoryDesc + typeDesc + ")V", null, null)); mv = (cw.visitMethod(
ACC_PUBLIC, "<init>", "(" + jsonfactoryDesc + typeDesc + objEncoderDesc + ")V", null, null));
// mv.setDebug(true); // mv.setDebug(true);
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "(" + jsonfactoryDesc + typeDesc + ")V", false); mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(
INVOKESPECIAL,
supDynName,
"<init>",
"(" + jsonfactoryDesc + typeDesc + objEncoderDesc + ")V",
false);
for (AccessibleObject element : elements) { for (AccessibleObject element : elements) {
final String fieldName = factory.readConvertFieldName(clazz, element); final String fieldName = factory.readConvertFieldName(clazz, element);
@@ -684,12 +690,8 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
newClazz, newDynName.replace('/', '.'), JsonFactory.class, Type.class); newClazz, newDynName.replace('/', '.'), JsonFactory.class, Type.class);
try { try {
JsonDynEncoder resultEncoder = JsonDynEncoder resultEncoder =
(JsonDynEncoder) newClazz.getDeclaredConstructor(JsonFactory.class, Type.class) (JsonDynEncoder) newClazz.getConstructor(JsonFactory.class, Type.class, ObjectEncoder.class)
.newInstance(factory, clazz); .newInstance(factory, clazz, selfObjEncoder);
Field selfField = newClazz.getDeclaredField("objectEncoderSelf");
selfField.setAccessible(true);
selfField.set(resultEncoder, selfObjEncoder);
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), selfField);
if (mixedNames != null) { if (mixedNames != null) {
for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) { for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) {
Field f = newClazz.getDeclaredField(en.getKey() + "Encoder"); Field f = newClazz.getDeclaredField(en.getKey() + "Encoder");

View File

@@ -47,10 +47,11 @@ public class ProtobufArrayEncoder<T> extends ArrayEncoder<ProtobufWriter, T> {
} else if (item instanceof CharSequence) { } else if (item instanceof CharSequence) {
encoder.convertTo(out, item); encoder.convertTo(out, item);
} else { } else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = out.pollChild();
encoder.convertTo(tmp, item); encoder.convertTo(tmp, item);
out.writeLength(tmp.count()); out.writeLength(tmp.count());
out.writeTo(tmp.toArray()); out.writeTo(tmp.toArray());
out.offerChild(tmp);
} }
} }
} }

View File

@@ -47,10 +47,11 @@ public class ProtobufCollectionEncoder<T> extends CollectionEncoder<ProtobufWrit
} else if (item instanceof CharSequence) { } else if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item); componentEncoder.convertTo(out, item);
} else { } else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = out.pollChild();
componentEncoder.convertTo(tmp, item); componentEncoder.convertTo(tmp, item);
out.writeLength(tmp.count()); out.writeLength(tmp.count());
out.writeTo(tmp.toArray()); out.writeTo(tmp.toArray());
out.offerChild(tmp);
} }
} }
} }

View File

@@ -4,9 +4,7 @@
*/ */
package org.redkale.convert.pb; package org.redkale.convert.pb;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -17,22 +15,7 @@ import org.redkale.asm.FieldVisitor;
import org.redkale.asm.Label; import org.redkale.asm.Label;
import org.redkale.asm.MethodVisitor; import org.redkale.asm.MethodVisitor;
import org.redkale.asm.Opcodes; import org.redkale.asm.Opcodes;
import static org.redkale.asm.Opcodes.ACC_BRIDGE; import static org.redkale.asm.Opcodes.*;
import static org.redkale.asm.Opcodes.ACC_FINAL;
import static org.redkale.asm.Opcodes.ACC_PROTECTED;
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
import static org.redkale.asm.Opcodes.ACC_SUPER;
import static org.redkale.asm.Opcodes.ACC_SYNTHETIC;
import static org.redkale.asm.Opcodes.ALOAD;
import static org.redkale.asm.Opcodes.ASTORE;
import static org.redkale.asm.Opcodes.CHECKCAST;
import static org.redkale.asm.Opcodes.GETFIELD;
import static org.redkale.asm.Opcodes.IFNONNULL;
import static org.redkale.asm.Opcodes.INVOKESPECIAL;
import static org.redkale.asm.Opcodes.INVOKEVIRTUAL;
import static org.redkale.asm.Opcodes.POP;
import static org.redkale.asm.Opcodes.RETURN;
import static org.redkale.asm.Opcodes.V11;
import org.redkale.convert.*; import org.redkale.convert.*;
import org.redkale.convert.ext.*; import org.redkale.convert.ext.*;
import org.redkale.util.AnyValue; import org.redkale.util.AnyValue;
@@ -59,7 +42,7 @@ public abstract class ProtobufDynEncoder<T> extends ProtobufObjectEncoder<T> {
// 动态字段: protected EnMember xxxEnMember; // 动态字段: protected EnMember xxxEnMember;
protected ProtobufDynEncoder(final ProtobufFactory factory, Type type, ObjectEncoder objectEncoderSelf) { protected ProtobufDynEncoder(ProtobufFactory factory, Type type, ObjectEncoder objectEncoderSelf) {
super((Class) type); super((Class) type);
this.typeClass = (Class) type; this.typeClass = (Class) type;
this.factory = factory; this.factory = factory;
@@ -431,13 +414,6 @@ public abstract class ProtobufDynEncoder<T> extends ProtobufObjectEncoder<T> {
return generateDyncEncoder(factory, (Class) type); return generateDyncEncoder(factory, (Class) type);
} }
protected static Class readGetSetFieldType(AccessibleObject element) {
if (element instanceof Field) {
return ((Field) element).getType();
}
return ((Method) element).getReturnType();
}
@Override @Override
public Type getType() { public Type getType() {
return typeClass; return typeClass;

View File

@@ -28,7 +28,7 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V> {
@Override @Override
protected void writeMemberValue(ProtobufWriter out, EnMember member, K key, V value, boolean first) { protected void writeMemberValue(ProtobufWriter out, EnMember member, K key, V value, boolean first) {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = out.pollChild();
if (member != null) { if (member != null) {
out.writeFieldName(member); out.writeFieldName(member);
} }
@@ -38,5 +38,6 @@ public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V> {
valueEncoder.convertTo(tmp, value); valueEncoder.convertTo(tmp, value);
out.writeLength(tmp.count()); out.writeLength(tmp.count());
out.writeTo(tmp.toArray()); out.writeTo(tmp.toArray());
out.offerChild(tmp);
} }
} }

View File

@@ -34,8 +34,15 @@ public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T> {
@Override @Override
protected ProtobufWriter objectWriter(ProtobufWriter out, T value) { protected ProtobufWriter objectWriter(ProtobufWriter out, T value) {
if (out.count() > out.initOffset) { if (out.count() > out.initOffset) {
return new ProtobufWriter(out, out.getFeatures()).configFieldFunc(out); return out.pollChild().configParentFunc(out);
} }
return out; return out;
} }
@Override
protected void offerWriter(ProtobufWriter parent, ProtobufWriter out) {
if (parent != out) {
parent.offerChild(out);
}
}
} }

View File

@@ -47,10 +47,11 @@ public class ProtobufStreamEncoder<T> extends StreamEncoder<ProtobufWriter, T> {
if (item instanceof CharSequence) { if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item); componentEncoder.convertTo(out, item);
} else { } else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = out.pollChild();
componentEncoder.convertTo(tmp, item); componentEncoder.convertTo(tmp, item);
out.writeUInt32(tmp.count()); out.writeUInt32(tmp.count());
out.writeTo(tmp.toArray()); out.writeTo(tmp.toArray());
out.offerChild(tmp);
} }
} }
} }

View File

@@ -23,6 +23,8 @@ public class ProtobufWriter extends Writer implements ByteTuple {
"redkale.convert.protobuf.writer.buffer.defsize", "redkale.convert.protobuf.writer.buffer.defsize",
Integer.getInteger("redkale.convert.writer.buffer.defsize", 1024)); Integer.getInteger("redkale.convert.writer.buffer.defsize", 1024));
private static final int CHILD_SIZE = 8;
private static final int TENTHOUSAND_MAX = 10001; private static final int TENTHOUSAND_MAX = 10001;
private static final byte[][] TENTHOUSAND_UINT_BYTES = new byte[TENTHOUSAND_MAX][]; private static final byte[][] TENTHOUSAND_UINT_BYTES = new byte[TENTHOUSAND_MAX][];
@@ -69,11 +71,13 @@ public class ProtobufWriter extends Writer implements ByteTuple {
protected ProtobufWriter parent; protected ProtobufWriter parent;
protected ProtobufWriter(ProtobufWriter parent, int features) { private ArrayDeque<ProtobufWriter> childWriters;
protected ProtobufWriter(ProtobufWriter parent) {
this(); this();
this.parent = parent; this.parent = parent;
this.features = features;
if (parent != null) { if (parent != null) {
this.features = parent.features;
this.enumtostring = parent.enumtostring; this.enumtostring = parent.enumtostring;
} }
} }
@@ -88,6 +92,15 @@ public class ProtobufWriter extends Writer implements ByteTuple {
return this; return this;
} }
protected ProtobufWriter configParentFunc(ProtobufWriter parent) {
this.parent = parent;
if (parent != null) {
this.features = parent.features;
this.enumtostring = parent.enumtostring;
}
return this;
}
protected ProtobufWriter configFieldFunc(ProtobufWriter out) { protected ProtobufWriter configFieldFunc(ProtobufWriter out) {
if (out == null) { if (out == null) {
return this; return this;
@@ -116,6 +129,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
@Override @Override
protected boolean recycle() { protected boolean recycle() {
super.recycle(); super.recycle();
this.parent = null;
this.mapFieldFunc = null;
this.objFieldFunc = null;
this.objExtFunc = null;
this.features = 0;
this.enumtostring = false;
this.count = 0; this.count = 0;
this.initOffset = 0; this.initOffset = 0;
if (this.content.length > DEFAULT_SIZE) { if (this.content.length > DEFAULT_SIZE) {
@@ -124,6 +143,27 @@ public class ProtobufWriter extends Writer implements ByteTuple {
return true; return true;
} }
public final ProtobufWriter pollChild() {
Queue<ProtobufWriter> queue = this.childWriters;
if (queue == null) {
this.childWriters = new ArrayDeque<>(CHILD_SIZE);
queue = this.childWriters;
}
ProtobufWriter result = queue.poll();
if (result == null) {
result = new ProtobufWriter();
}
return result.configFieldFunc(this);
}
public final void offerChild(final ProtobufWriter child) {
Queue<ProtobufWriter> queue = this.childWriters;
if (child != null && queue != null && queue.size() < CHILD_SIZE) {
child.recycle();
queue.offer(child);
}
}
@Override @Override
public byte[] content() { public byte[] content() {
return content; return content;
@@ -270,7 +310,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
return length; return length;
} else { } else {
final Class type = obj.getClass(); final Class type = obj.getClass();
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(this); ProtobufWriter tmp = pollChild();
if (type == boolean[].class) { if (type == boolean[].class) {
for (boolean item : (boolean[]) obj) { for (boolean item : (boolean[]) obj) {
tmp.writeBoolean(item); tmp.writeBoolean(item);
@@ -405,6 +445,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
int length = tmp.count(); int length = tmp.count();
writeLength(length); writeLength(length);
writeTo(tmp.toArray()); writeTo(tmp.toArray());
offerChild(tmp);
return length; return length;
} }
} }
@@ -1309,11 +1350,12 @@ public class ProtobufWriter extends Writer implements ByteTuple {
if (arrayEncoder.simple) { if (arrayEncoder.simple) {
if (((Object[]) value).length < 1) { if (((Object[]) value).length < 1) {
this.writeFieldName(member); this.writeFieldName(member);
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(this); ProtobufWriter tmp = pollChild();
arrayEncoder.convertTo(tmp, member, (Object[]) value); arrayEncoder.convertTo(tmp, member, (Object[]) value);
// int length = tmp.count(); // int length = tmp.count();
// this.writeUInt32(length); // this.writeUInt32(length);
this.writeTo(tmp.toArray()); this.writeTo(tmp.toArray());
offerChild(tmp);
} }
} else { } else {
arrayEncoder.convertTo(this, member, (Object[]) value); arrayEncoder.convertTo(this, member, (Object[]) value);
@@ -1323,10 +1365,11 @@ public class ProtobufWriter extends Writer implements ByteTuple {
if (collectionEncoder.simple) { if (collectionEncoder.simple) {
if (!((Collection) value).isEmpty()) { if (!((Collection) value).isEmpty()) {
this.writeFieldName(member); this.writeFieldName(member);
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(this); ProtobufWriter tmp = pollChild();
collectionEncoder.convertTo(tmp, member, (Collection) value); collectionEncoder.convertTo(tmp, member, (Collection) value);
this.writeLength(tmp.count()); this.writeLength(tmp.count());
this.writeTo(tmp.toArray()); this.writeTo(tmp.toArray());
offerChild(tmp);
} }
} else { } else {
collectionEncoder.convertTo(this, member, (Collection) value); collectionEncoder.convertTo(this, member, (Collection) value);
@@ -1335,10 +1378,11 @@ public class ProtobufWriter extends Writer implements ByteTuple {
ProtobufStreamEncoder streamEncoder = (ProtobufStreamEncoder) encoder; ProtobufStreamEncoder streamEncoder = (ProtobufStreamEncoder) encoder;
if (streamEncoder.simple) { if (streamEncoder.simple) {
this.writeFieldName(member); this.writeFieldName(member);
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(this); ProtobufWriter tmp = pollChild();
streamEncoder.convertTo(tmp, member, (Stream) value); streamEncoder.convertTo(tmp, member, (Stream) value);
this.writeLength(tmp.count()); this.writeLength(tmp.count());
this.writeTo(tmp.toArray()); this.writeTo(tmp.toArray());
offerChild(tmp);
} else { } else {
streamEncoder.convertTo(this, member, (Stream) value); streamEncoder.convertTo(this, member, (Stream) value);
} }

View File

@@ -6,6 +6,7 @@
package org.redkale.test.convert; package org.redkale.test.convert;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.redkale.convert.ObjectEncoder;
import org.redkale.convert.json.*; import org.redkale.convert.json.*;
/** @author zhangjx */ /** @author zhangjx */
@@ -15,8 +16,8 @@ public class _DyncFortuneJsonEncoder extends JsonDynEncoder<Fortune> {
protected final byte[] messageCommaFieldBytes = ",\"message\":".getBytes(); protected final byte[] messageCommaFieldBytes = ",\"message\":".getBytes();
public _DyncFortuneJsonEncoder(JsonFactory factory, Type type) { public _DyncFortuneJsonEncoder(JsonFactory factory, Type type, ObjectEncoder objectEncoderSelf) {
super(factory, type); super(factory, type, objectEncoderSelf);
} }
@Override @Override
@@ -26,7 +27,7 @@ public class _DyncFortuneJsonEncoder extends JsonDynEncoder<Fortune> {
return; return;
} }
if (!out.isExtFuncEmpty()) { if (!out.isExtFuncEmpty()) {
objectEncoder.convertTo(out, value); objectEncoderSelf.convertTo(out, value);
return; return;
} }

View File

@@ -6,6 +6,7 @@
package org.redkale.test.convert; package org.redkale.test.convert;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.redkale.convert.ObjectEncoder;
import org.redkale.convert.json.*; import org.redkale.convert.json.*;
/** @author zhangjx */ /** @author zhangjx */
@@ -15,8 +16,8 @@ public class _DyncMessageJsonEncoder extends JsonDynEncoder<Message> {
protected final byte[] messageCommaFieldBytes = ",\"message\":".getBytes(); protected final byte[] messageCommaFieldBytes = ",\"message\":".getBytes();
public _DyncMessageJsonEncoder(JsonFactory factory, Type type) { public _DyncMessageJsonEncoder(JsonFactory factory, Type type, ObjectEncoder objectEncoderSelf) {
super(factory, type); super(factory, type, objectEncoderSelf);
} }
@Override @Override
@@ -26,7 +27,7 @@ public class _DyncMessageJsonEncoder extends JsonDynEncoder<Message> {
return; return;
} }
if (!out.isExtFuncEmpty()) { if (!out.isExtFuncEmpty()) {
objectEncoder.convertTo(out, value); objectEncoderSelf.convertTo(out, value);
return; return;
} }

View File

@@ -6,6 +6,7 @@
package org.redkale.test.convert; package org.redkale.test.convert;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.redkale.convert.ObjectEncoder;
import org.redkale.convert.json.*; import org.redkale.convert.json.*;
/** @author zhangjx */ /** @author zhangjx */
@@ -15,8 +16,8 @@ public class _DyncWorldJsonEncoder extends JsonDynEncoder<World> {
protected final byte[] randomNumberFieldBytes = ",\"randomNumber\":".getBytes(); protected final byte[] randomNumberFieldBytes = ",\"randomNumber\":".getBytes();
public _DyncWorldJsonEncoder(JsonFactory factory, Type type) { public _DyncWorldJsonEncoder(JsonFactory factory, Type type, ObjectEncoder objectEncoderSelf) {
super(factory, type); super(factory, type, objectEncoderSelf);
} }
@Override @Override
@@ -26,7 +27,7 @@ public class _DyncWorldJsonEncoder extends JsonDynEncoder<World> {
return; return;
} }
if (!out.isExtFuncEmpty()) { if (!out.isExtFuncEmpty()) {
objectEncoder.convertTo(out, value); objectEncoderSelf.convertTo(out, value);
return; return;
} }