Skip to content

Commit

Permalink
Merge pull request #221 from tiandankanfeng/branch_security_and_effic…
Browse files Browse the repository at this point in the history
…ient_local_cache

feat: use ConcurrentHashMap instead of HashMap with Sync
  • Loading branch information
DQinYuan authored Dec 13, 2022
2 parents 115412d + 9d6f584 commit e9469df
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 23 deletions.
57 changes: 39 additions & 18 deletions src/main/java/com/ql/util/express/ExpressRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;

import com.ql.util.express.config.QLExpressTimer;
import com.ql.util.express.exception.QLCompileException;
Expand Down Expand Up @@ -60,8 +62,9 @@ public class ExpressRunner {

/**
* 一段文本对应的指令集的缓存
* default: ConcurrentHashMap with no eviction policy
*/
private final Map<String, InstructionSet> expressInstructionSetCache = new HashMap<>();
private final Map<String, InstructionSet> expressInstructionSetCache;

private final ExpressLoader loader;

Expand Down Expand Up @@ -123,6 +126,18 @@ public ExpressRunner(boolean isPrecise, boolean isTrace) {
this(isPrecise, isTrace, new DefaultExpressResourceLoader(), null);
}

/**
*
* @param isPrecise
* @param isTrace
* @param cacheMap user can define safe and efficient cache or use default concurrentMap
*/
public ExpressRunner(boolean isPrecise, boolean isTrace,
Map<String, InstructionSet> cacheMap) {
this(isPrecise, isTrace, new DefaultExpressResourceLoader(), null, cacheMap);
}


public ExpressRunner(boolean isPrecise, boolean isStrace, NodeTypeManager nodeTypeManager) {
this(isPrecise, isStrace, new DefaultExpressResourceLoader(), nodeTypeManager);
}
Expand All @@ -134,6 +149,18 @@ public ExpressRunner(boolean isPrecise, boolean isStrace, NodeTypeManager nodeTy
*/
public ExpressRunner(boolean isPrecise, boolean isTrace, IExpressResourceLoader iExpressResourceLoader,
NodeTypeManager nodeTypeManager) {
this(isPrecise, isTrace, iExpressResourceLoader,
nodeTypeManager, null);
}

/**
* @param isPrecise 是否需要高精度计算支持
* @param isTrace 是否跟踪执行指令的过程
* @param iExpressResourceLoader 表达式的资源装载器
* @param cacheMap 指令集缓存
*/
public ExpressRunner(boolean isPrecise, boolean isTrace, IExpressResourceLoader iExpressResourceLoader,
NodeTypeManager nodeTypeManager, Map<String, InstructionSet> cacheMap) {
this.isTrace = isTrace;
this.isPrecise = isPrecise;
this.expressResourceLoader = iExpressResourceLoader;
Expand All @@ -142,6 +169,12 @@ public ExpressRunner(boolean isPrecise, boolean isTrace, IExpressResourceLoader
} else {
manager = nodeTypeManager;
}

if (Objects.isNull(cacheMap)) {
expressInstructionSetCache = new ConcurrentHashMap<>();
} else {
expressInstructionSetCache = cacheMap;
}
this.operatorManager = new OperatorFactory(this.isPrecise);
this.loader = new ExpressLoader(this);
this.parse = new ExpressParse(manager, this.expressResourceLoader, this.isPrecise);
Expand Down Expand Up @@ -192,6 +225,7 @@ public IExpressResourceLoader getExpressResourceLoader() {
return this.expressResourceLoader;
}


/**
* 添加宏定义
* 例如: macro 宏名称 { abc(userInfo.userId);}
Expand Down Expand Up @@ -531,9 +565,7 @@ public ExpressPackage getRootExpressPackage() {
* 清除缓存
*/
public void clearExpressCache() {
synchronized (expressInstructionSetCache) {
this.expressInstructionSetCache.clear();
}
expressInstructionSetCache.clear();
}

/**
Expand Down Expand Up @@ -650,13 +682,8 @@ public Object execute(String expressString, IExpressContext<String, Object> cont
if (isCache) {
parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
synchronized (expressInstructionSetCache) {
parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
parseResult = this.parseInstructionSet(expressString);
expressInstructionSetCache.put(expressString, parseResult);
}
}
expressInstructionSetCache.putIfAbsent(expressString,
parseResult = this.parseInstructionSet(expressString));
}
} else {
parseResult = this.parseInstructionSet(expressString);
Expand Down Expand Up @@ -729,13 +756,7 @@ public ExportItem[] getExportInfo() {
public InstructionSet getInstructionSetFromLocalCache(String expressString) throws Exception {
InstructionSet parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
synchronized (expressInstructionSetCache) {
parseResult = expressInstructionSetCache.get(expressString);
if (parseResult == null) {
parseResult = this.parseInstructionSet(expressString);
expressInstructionSetCache.put(expressString, parseResult);
}
}
expressInstructionSetCache.putIfAbsent(expressString, parseResult = this.parseInstructionSet(expressString));
}
return parseResult;
}
Expand Down
14 changes: 9 additions & 5 deletions src/test/java/com/ql/util/express/test/ExpressCacheTest.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.ql.util.express.test;

import java.util.Date;

import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRemoteCacheRunner;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import com.ql.util.express.LocalExpressCacheRunner;
import org.junit.Assert;
import org.junit.Test;

/**
Expand All @@ -17,6 +17,9 @@
public class ExpressCacheTest {
private final ExpressRunner runner = new ExpressRunner();

/**
* Single td invoke
*/
@Test
public void testScriptCache() throws Exception {
runner.addMacro("计算平均成绩", "(语文+数学+英语)/3.0");
Expand All @@ -29,16 +32,17 @@ public void testScriptCache() throws Exception {
while (times-- > 0) {
calculateTask(false, context);
}
long end = new Date().getTime();
echo("不做缓存耗时:" + (end - start) + " ms");
long a = new Date().getTime() - start;
echo("不做缓存耗时:" + a + " ms");

times = 10000;
start = new Date().getTime();
while (times-- > 0) {
calculateTask(true, context);
}
end = new Date().getTime();
echo("做缓存耗时:" + (end - start) + " ms");
long b = new Date().getTime() - start;
echo("做缓存耗时:" + b + " ms");
Assert.assertTrue(b < a);
}

@Test
Expand Down

0 comments on commit e9469df

Please sign in to comment.