perf[wrapper]: generic type interface

This commit is contained in:
godotg committed 2024-07-01 17:42:46 +08:00
1 parent 10bd52f626
commit 62290fb35f
4 files changed
+66 -69

No files matched your search

+7 -17
View File
@@ -56,28 +56,21 @@ public class EntityCache<PK extends Comparable<PK>, E extends IEntity<PK>> imple
private final Class<E> clazz; private final Class<E> clazz;
private final EntityDef entityDef; private final EntityDef entityDef;
private final LazyCache<PK, PNode<PK, E>> cache; private final LazyCache<PK, PNode<PK, E>> cache;
private final IEntityWrapper<PK, E> wrapper;
private IEntityWrapper wrapper;
@SuppressWarnings("unchecked") public EntityCache(Class<E> entityClass, EntityDef entityDef) {
public EntityCache(Class<? extends IEntity<?>> entityClass, EntityDef entityDef) { this.clazz = entityClass;
this.clazz = (Class<E>) entityClass; this.entityDef = entityDef;
// 创建CacheVersion // 创建CacheVersion
var entityWrapper = new EntityWrapper(entityClass); var entityWrapper = new EntityWrapper<>(clazz);
if (GraalVmUtils.isGraalVM()) { if (GraalVmUtils.isGraalVM()) {
wrapper = entityWrapper; wrapper = entityWrapper;
} else { } else {
try { wrapper = EnhanceUtils.createEntityWrapper(entityWrapper);
wrapper = EnhanceUtils.createEntityWrapper(entityWrapper);
} catch (Exception e) {
throw new RuntimeException(e);
}
} }
var removeCallback = new BiConsumer<Pair<PK, PNode<PK, E>>, LazyCache.RemovalCause>() { var removeCallback = new BiConsumer<Pair<PK, PNode<PK, E>>, LazyCache.RemovalCause>() {
@Override @Override
public void accept(Pair<PK, PNode<PK, E>> pair, LazyCache.RemovalCause removalCause) { public void accept(Pair<PK, PNode<PK, E>> pair, LazyCache.RemovalCause removalCause) {
@@ -114,7 +107,6 @@ public class EntityCache<PK extends Comparable<PK>, E extends IEntity<PK>> imple
} }
}; };
var expireCheckIntervalMillis = Math.max(3 * TimeUtils.MILLIS_PER_SECOND, entityDef.getExpireMillisecond() / 10); var expireCheckIntervalMillis = Math.max(3 * TimeUtils.MILLIS_PER_SECOND, entityDef.getExpireMillisecond() / 10);
this.entityDef = entityDef;
this.cache = new LazyCache<>(entityDef.getCacheSize(), entityDef.getExpireMillisecond(), expireCheckIntervalMillis, removeCallback); this.cache = new LazyCache<>(entityDef.getCacheSize(), entityDef.getExpireMillisecond(), expireCheckIntervalMillis, removeCallback);
if (CollectionUtils.isNotEmpty(entityDef.getIndexDefMap())) { if (CollectionUtils.isNotEmpty(entityDef.getIndexDefMap())) {
@@ -151,7 +143,6 @@ public class EntityCache<PK extends Comparable<PK>, E extends IEntity<PK>> imple
return entity; return entity;
} }
@SuppressWarnings("unchecked")
@Override @Override
public E loadOrCreate(PK pk) { public E loadOrCreate(PK pk) {
AssertionUtils.notNull(pk); AssertionUtils.notNull(pk);
@@ -164,7 +155,7 @@ public class EntityCache<PK extends Comparable<PK>, E extends IEntity<PK>> imple
// 如果数据库中不存在则给一个默认值 // 如果数据库中不存在则给一个默认值
if (entity == null) { if (entity == null) {
entity = (E) wrapper.newEntity(pk); entity = wrapper.newEntity(pk);
OrmContext.getAccessor().insert(entity); OrmContext.getAccessor().insert(entity);
} }
pnode = new PNode<>(entity); pnode = new PNode<>(entity);
@@ -403,7 +394,6 @@ public class EntityCache<PK extends Comparable<PK>, E extends IEntity<PK>> imple
cache.remove(id); cache.remove(id);
load(id); load(id);
logger.warn("[database:{}] document of entity [id:{}] version [{}] is greater than cache [vs:{}]", clazz.getSimpleName(), id, dbEntityVersion, entityVersion); logger.warn("[database:{}] document of entity [id:{}] version [{}] is greater than cache [vs:{}]", clazz.getSimpleName(), id, dbEntityVersion, entityVersion);
continue;
} }
} }
@@ -16,11 +16,13 @@ import com.zfoo.orm.model.IEntity;
import com.zfoo.orm.schema.NamespaceHandler; import com.zfoo.orm.schema.NamespaceHandler;
import com.zfoo.protocol.util.StringUtils; import com.zfoo.protocol.util.StringUtils;
import com.zfoo.protocol.util.UuidUtils; import com.zfoo.protocol.util.UuidUtils;
import javassist.*; import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
@@ -62,52 +64,57 @@ public abstract class EnhanceUtils {
} }
} }
public static IEntityWrapper createEntityWrapper(EntityWrapper entityWrapper) throws NotFoundException, CannotCompileException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { @SuppressWarnings("unchecked")
var classPool = ClassPool.getDefault(); public static <PK extends Comparable<PK>, E extends IEntity<PK>> IEntityWrapper<PK, E> createEntityWrapper(EntityWrapper<PK, E> entityWrapper) {
try {
var classPool = ClassPool.getDefault();
Class<?> clazz = entityWrapper.getEntityClass(); Class<?> clazz = entityWrapper.getEntityClass();
Field idField = entityWrapper.getIdField(); Field idField = entityWrapper.getIdField();
Method setIdMethod = entityWrapper.getSetIdMethod(); Method setIdMethod = entityWrapper.getSetIdMethod();
Field versionField = entityWrapper.getVersionField(); Field versionField = entityWrapper.getVersionField();
Method getVersionMethod = entityWrapper.getGetVersionMethod(); Method getVersionMethod = entityWrapper.getGetVersionMethod();
Method setVersionMethod = entityWrapper.getSetVersionMethod(); Method setVersionMethod = entityWrapper.getSetVersionMethod();
// 定义类名称 // 定义类名称
CtClass enhanceClazz = classPool.makeClass(EnhanceUtils.class.getName() + StringUtils.capitalize(NamespaceHandler.ORM) + UuidUtils.getLocalIntId()); CtClass enhanceClazz = classPool.makeClass(EnhanceUtils.class.getName() + StringUtils.capitalize(NamespaceHandler.ORM) + UuidUtils.getLocalIntId());
enhanceClazz.addInterface(classPool.get(IEntityWrapper.class.getName())); enhanceClazz.addInterface(classPool.get(IEntityWrapper.class.getName()));
// 定义类实现的接口方法name // 定义类实现的接口方法name
CtMethod newEntityMethod = new CtMethod(classPool.get(IEntity.class.getName()), "newEntity", classPool.get(new String[]{Object.class.getName()}), enhanceClazz); CtMethod newEntityMethod = new CtMethod(classPool.get(IEntity.class.getName()), "newEntity", classPool.get(new String[]{Comparable.class.getName()}), enhanceClazz);
newEntityMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); newEntityMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
String newEntityMethodBody = StringUtils.format("{ {} entity = new {}(); entity.{}({}); return entity; }", clazz.getName(), clazz.getName(), setIdMethod.getName(), rawObjectId(idField)); String newEntityMethodBody = StringUtils.format("{ {} entity = new {}(); entity.{}({}); return entity; }", clazz.getName(), clazz.getName(), setIdMethod.getName(), rawObjectId(idField));
newEntityMethod.setBody(newEntityMethodBody); newEntityMethod.setBody(newEntityMethodBody);
enhanceClazz.addMethod(newEntityMethod); enhanceClazz.addMethod(newEntityMethod);
// 定义类实现的接口方法name // 定义类实现的接口方法name
CtMethod versionFieldNameMethod = new CtMethod(classPool.get(String.class.getName()), "versionFieldName", null, enhanceClazz); CtMethod versionFieldNameMethod = new CtMethod(classPool.get(String.class.getName()), "versionFieldName", null, enhanceClazz);
versionFieldNameMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); versionFieldNameMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
String versionFieldNameMethodBody = versionField == null ? "{ return null; }" : StringUtils.format("{ return \"{}\"; }", entityWrapper.versionFieldName()); String versionFieldNameMethodBody = versionField == null ? "{ return null; }" : StringUtils.format("{ return \"{}\"; }", entityWrapper.versionFieldName());
versionFieldNameMethod.setBody(versionFieldNameMethodBody); versionFieldNameMethod.setBody(versionFieldNameMethodBody);
enhanceClazz.addMethod(versionFieldNameMethod); enhanceClazz.addMethod(versionFieldNameMethod);
// 定义类实现的接口方法gvs // 定义类实现的接口方法gvs
CtMethod gvsMethod = new CtMethod(classPool.get(long.class.getName()), "gvs", classPool.get(new String[]{IEntity.class.getName()}), enhanceClazz); CtMethod gvsMethod = new CtMethod(classPool.get(long.class.getName()), "gvs", classPool.get(new String[]{IEntity.class.getName()}), enhanceClazz);
gvsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); gvsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
String gvsMethodBody = getVersionMethod == null ? "{ return 0L; }" : StringUtils.format("{ return (({})$1).{}(); }", clazz.getName(), getVersionMethod.getName()); String gvsMethodBody = getVersionMethod == null ? "{ return 0L; }" : StringUtils.format("{ return (({})$1).{}(); }", clazz.getName(), getVersionMethod.getName());
gvsMethod.setBody(gvsMethodBody); gvsMethod.setBody(gvsMethodBody);
enhanceClazz.addMethod(gvsMethod); enhanceClazz.addMethod(gvsMethod);
// 定义类实现的接口方法svs // 定义类实现的接口方法svs
CtMethod svsMethod = new CtMethod(classPool.get(void.class.getName()), "svs", classPool.get(new String[]{IEntity.class.getName(), long.class.getName()}), enhanceClazz); CtMethod svsMethod = new CtMethod(classPool.get(void.class.getName()), "svs", classPool.get(new String[]{IEntity.class.getName(), long.class.getName()}), enhanceClazz);
svsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL); svsMethod.setModifiers(Modifier.PUBLIC + Modifier.FINAL);
String svsMethodBody = setVersionMethod == null ? "{}" : StringUtils.format("{ (({})$1).{}($2); }", clazz.getName(), setVersionMethod.getName()); String svsMethodBody = setVersionMethod == null ? "{}" : StringUtils.format("{ (({})$1).{}($2); }", clazz.getName(), setVersionMethod.getName());
svsMethod.setBody(svsMethodBody); svsMethod.setBody(svsMethodBody);
enhanceClazz.addMethod(svsMethod); enhanceClazz.addMethod(svsMethod);
// 释放缓存 // 释放缓存
enhanceClazz.detach(); enhanceClazz.detach();
Class<?> resultClazz = enhanceClazz.toClass(IEntityWrapper.class); Class<?> resultClazz = enhanceClazz.toClass(IEntityWrapper.class);
return (IEntityWrapper) resultClazz.newInstance(); return (IEntityWrapper<PK, E>) resultClazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
} }
} }
@@ -25,9 +25,9 @@ import java.lang.reflect.Method;
/** /**
* @author godotg * @author godotg
*/ */
public class EntityWrapper implements IEntityWrapper { public class EntityWrapper<PK extends Comparable<PK>, E extends IEntity<PK>> implements IEntityWrapper<PK, E> {
private Class<? extends IEntity<?>> entityClass; private Class<E> entityClass;
private Field idField; private Field idField;
private Method setIdMethod; private Method setIdMethod;
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
@@ -35,7 +35,7 @@ public class EntityWrapper implements IEntityWrapper {
private Method getVersionMethod; private Method getVersionMethod;
private Method setVersionMethod; private Method setVersionMethod;
public EntityWrapper(Class<? extends IEntity<?>> entityClass) { public EntityWrapper(Class<E> entityClass) {
this.entityClass = entityClass; this.entityClass = entityClass;
var idFields = ReflectionUtils.getFieldsByAnnoInPOJOClass(entityClass, Id.class); var idFields = ReflectionUtils.getFieldsByAnnoInPOJOClass(entityClass, Id.class);
@@ -54,7 +54,7 @@ public class EntityWrapper implements IEntityWrapper {
} }
@Override @Override
public IEntity<?> newEntity(Object id) { public E newEntity(PK id) {
var entity = ReflectionUtils.newInstance(entityClass); var entity = ReflectionUtils.newInstance(entityClass);
ReflectionUtils.invokeMethod(entity, setIdMethod, id); ReflectionUtils.invokeMethod(entity, setIdMethod, id);
return entity; return entity;
@@ -69,7 +69,7 @@ public class EntityWrapper implements IEntityWrapper {
} }
@Override @Override
public long gvs(IEntity<?> entity) { public long gvs(E entity) {
if (getVersionMethod == null) { if (getVersionMethod == null) {
return 0; return 0;
} }
@@ -77,14 +77,14 @@ public class EntityWrapper implements IEntityWrapper {
} }
@Override @Override
public void svs(IEntity<?> entity, long vs) { public void svs(E entity, long vs) {
if (setVersionMethod == null) { if (setVersionMethod == null) {
return; return;
} }
ReflectionUtils.invokeMethod(entity, setVersionMethod, vs); ReflectionUtils.invokeMethod(entity, setVersionMethod, vs);
} }
public Class<? extends IEntity<?>> getEntityClass() { public Class<E> getEntityClass() {
return entityClass; return entityClass;
} }
@@ -18,9 +18,9 @@ import com.zfoo.orm.model.IEntity;
/** /**
* @author godotg * @author godotg
*/ */
public interface IEntityWrapper { public interface IEntityWrapper<PK extends Comparable<PK>, E extends IEntity<PK>> {
IEntity<?> newEntity(Object id); E newEntity(PK id);
/** /**
* version field的名称 * version field的名称
@@ -41,8 +41,8 @@ public interface IEntityWrapper {
* <p> * <p>
* 分布式环境下,要想服务器性能好,就要做成有状态的,有状态就要遇到这种多服对同一条数据写入问题,这是一个千古难以解决的问题,进退两难。 * 分布式环境下,要想服务器性能好,就要做成有状态的,有状态就要遇到这种多服对同一条数据写入问题,这是一个千古难以解决的问题,进退两难。
*/ */
long gvs(IEntity<?> entity); long gvs(E entity);
void svs(IEntity<?> entity, long vs); void svs(E entity, long vs);
} }