perf[protocol]: 如果所有协议Class返回的hashcode都不相同(大概率事件),则使用高性能的HashMapIntShort

This commit is contained in:
godotg committed 2022-10-08 10:17:49 +08:00
1 parent d71dac91c4
commit a43f7a0f85
3 files changed
+38 -22

No files matched your search

@@ -13,6 +13,7 @@
package com.zfoo.protocol;
import com.zfoo.protocol.buffer.ByteBufUtils;
import com.zfoo.protocol.collection.HashMapIntShort;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolAnalysis;
@@ -44,10 +45,10 @@ public class ProtocolManager {
public static final ProtocolModule[] modules = new ProtocolModule[MAX_MODULE_NUM];
/**
* key:协议class
* value:protocolId
* key:协议class,value:protocolId,如果所有协议Class返回的hashcode都不相同(大概率事件),则使用高性能的HashMapIntShort
*/
public static final Map<Class<?>, Short> protocolIdMap = new HashMap<>();
public static Map<Class<?>, Short> protocolIdMap = new HashMap<>();
public static HashMapIntShort protocolIdPrimitiveMap = new HashMapIntShort();
static {
// 初始化默认协议模块
@@ -79,9 +80,6 @@ public class ProtocolManager {
/**
* 根据模块id查找模块
*
* @param moduleId
* @return
*/
public static ProtocolModule moduleByModuleId(byte moduleId) {
var module = modules[moduleId];
@@ -91,13 +89,10 @@ public class ProtocolManager {
/**
* 根据模块名字查找模块
*
* @param name
* @return
*/
public static ProtocolModule moduleByModuleName(String name) {
var moduleOptional = Arrays.stream(modules)
.filter(it -> Objects.nonNull(it))
.filter(Objects::nonNull)
.filter(it -> it.getName().equals(name))
.findFirst();
if (moduleOptional.isEmpty()) {
@@ -107,10 +102,9 @@ public class ProtocolManager {
}
public static short protocolId(Class<?> clazz) {
var protocolId = protocolIdMap.get(clazz);
return protocolId;
return protocolIdMap == null ? protocolIdPrimitiveMap.getPrimitive(clazz.hashCode()) : protocolIdMap.get(clazz);
}
public static void initProtocol(Set<Class<?>> protocolClassSet) {
ProtocolAnalysis.analyze(protocolClassSet, GenerateOperation.NO_OPERATION);
}
@@ -104,6 +104,14 @@ public class HashMapIntShort implements Map<Integer, Short> {
return index == -1 ? null : values[index];
}
public short getPrimitive(int key) {
var index = indexOf(key);
if (index == -1) {
throw new NoSuchElementException();
}
return values[index];
}
@Override
public Short put(Integer key, Short value) {
return putPrimitive(ArrayUtils.intValue(key), ArrayUtils.shortValue(value));
@@ -93,9 +93,6 @@ public class ProtocolAnalysis {
/**
* 真正的注册协议,将协议id和协议信息关联起来
*
* @param protocolClassSet
* @param generateOperation
*/
public static synchronized void analyze(Set<Class<?>> protocolClassSet, GenerateOperation generateOperation) {
AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName());
@@ -112,7 +109,7 @@ public class ProtocolAnalysis {
}
// 通过指定类注册的协议,全部使用字节码增强
var enhanceList = Arrays.stream(protocols).filter(it -> Objects.nonNull(it)).collect(Collectors.toList());
var enhanceList = Arrays.stream(protocols).filter(Objects::nonNull).collect(Collectors.toList());
enhance(generateOperation, enhanceList);
} catch (Exception e) {
throw new RuntimeException(e);
@@ -172,11 +169,30 @@ public class ProtocolAnalysis {
}
private static void enhance(GenerateOperation generateOperation, List<IProtocolRegistration> enhanceList) throws IOException, ClassNotFoundException, NotFoundException, CannotCompileException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException {
initProtocolIdMap();
enhanceProtocolBefore(generateOperation);
enhanceProtocolRegistration(enhanceList);
enhanceProtocolAfter(generateOperation);
}
private static void initProtocolIdMap() {
for (var protocol : protocols) {
if (protocol == null) {
continue;
}
var clazz = protocol.protocolConstructor().getDeclaringClass();
var protocolId = protocol.protocolId();
protocolIdMap.put(clazz, protocolId);
protocolIdPrimitiveMap.putPrimitive(clazz.hashCode(), protocolId);
}
var distinctHashcode = protocolIdMap.keySet().stream().map(Object::hashCode).distinct().count();
if (distinctHashcode == protocolIdMap.size()) {
protocolIdMap = null;
} else {
protocolIdPrimitiveMap = null;
}
}
private static void enhanceProtocolBefore(GenerateOperation generateOperation) throws IOException, ClassNotFoundException {
// 检查协议格式
checkAllProtocolClass();
@@ -263,7 +279,7 @@ public class ProtocolAnalysis {
var compatibleFields = compatibleFieldMap.entrySet()
.stream()
.sorted((a, b) -> a.getKey() - b.getKey())
.map(it -> it.getValue())
.map(Map.Entry::getValue)
.collect(Collectors.toList());
notCompatibleFields.addAll(compatibleFields);
return notCompatibleFields;
@@ -483,8 +499,6 @@ public class ProtocolAnalysis {
if (previous != null) {
throw new RunException("[{}][{}]协议号[protocolId:{}]重复", clazz.getCanonicalName(), previous.getCanonicalName(), protocolId);
}
//存储class和protocolId的映射
protocolIdMap.put(clazz, protocolId);
}
public static short getProtocolIdByClass(Class<?> clazz) {
@@ -535,14 +549,14 @@ public class ProtocolAnalysis {
// 模块id不能重复
var moduleIdSet = new HashSet<Byte>();
Arrays.stream(modules)
.filter(it -> Objects.nonNull(it))
.filter(Objects::nonNull)
.peek(it -> AssertionUtils.isTrue(!moduleIdSet.contains(it.getId()), "模块[{}]存在重复的id,模块的id不能重复", it))
.forEach(it -> moduleIdSet.add(it.getId()));
// 模块名称不能重复
var moduleNameSet = new HashSet<String>();
Arrays.stream(modules)
.filter(it -> Objects.nonNull(it))
.filter(Objects::nonNull)
.peek(it -> AssertionUtils.isTrue(!moduleNameSet.contains(it.getName()), "模块[{}]存在重复的name,模块名称不能重复", it))
.forEach(it -> moduleNameSet.add(it.getName()));
}