mirror of
https://github.com/tencentmusic/supersonic.git
synced 2025-12-12 04:27:39 +00:00
(improvement)(Headless) refactor code by spi (#818)
This commit is contained in:
@@ -20,5 +20,8 @@ public class CacheCommonConfig {
|
||||
@Value("${cache.common.expire.after.write:10}")
|
||||
private Integer cacheCommonExpireAfterWrite;
|
||||
|
||||
@Value("${query.cache.enable:true}")
|
||||
private Boolean cacheEnable;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,26 +1,21 @@
|
||||
package com.tencent.supersonic.headless.core.cache;
|
||||
|
||||
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.headless.api.pojo.request.SemanticQueryReq;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DefaultQueryCache implements QueryCache {
|
||||
|
||||
@Value("${query.cache.enable:true}")
|
||||
private Boolean cacheEnable;
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
public Object query(SemanticQueryReq semanticQueryReq, String cacheKey) {
|
||||
CacheManager cacheManager = ContextUtils.getBean(CacheManager.class);
|
||||
if (isCache(semanticQueryReq)) {
|
||||
Object result = cacheManager.get(cacheKey);
|
||||
log.info("query from cache, key:{}", cacheKey);
|
||||
@@ -30,7 +25,9 @@ public class DefaultQueryCache implements QueryCache {
|
||||
}
|
||||
|
||||
public Boolean put(String cacheKey, Object value) {
|
||||
if (cacheEnable && Objects.nonNull(value)) {
|
||||
CacheManager cacheManager = ContextUtils.getBean(CacheManager.class);
|
||||
CacheCommonConfig cacheCommonConfig = ContextUtils.getBean(CacheCommonConfig.class);
|
||||
if (cacheCommonConfig.getCacheEnable() && Objects.nonNull(value)) {
|
||||
CompletableFuture.supplyAsync(() -> cacheManager.put(cacheKey, value))
|
||||
.exceptionally(exception -> {
|
||||
log.warn("exception:", exception);
|
||||
@@ -43,6 +40,7 @@ public class DefaultQueryCache implements QueryCache {
|
||||
}
|
||||
|
||||
public String getCacheKey(SemanticQueryReq semanticQueryReq) {
|
||||
CacheManager cacheManager = ContextUtils.getBean(CacheManager.class);
|
||||
String commandMd5 = semanticQueryReq.generateCommandMd5();
|
||||
String keyByModelIds = getKeyByModelIds(semanticQueryReq.getModelIds());
|
||||
return cacheManager.generateCacheKey(keyByModelIds, commandMd5);
|
||||
@@ -53,7 +51,8 @@ public class DefaultQueryCache implements QueryCache {
|
||||
}
|
||||
|
||||
private boolean isCache(SemanticQueryReq semanticQueryReq) {
|
||||
if (!cacheEnable) {
|
||||
CacheCommonConfig cacheCommonConfig = ContextUtils.getBean(CacheCommonConfig.class);
|
||||
if (!cacheCommonConfig.getCacheEnable()) {
|
||||
return false;
|
||||
}
|
||||
if (semanticQueryReq.getCacheInfo() != null) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.tencent.supersonic.headless.core.executor;
|
||||
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.headless.api.pojo.response.SemanticQueryResp;
|
||||
import com.tencent.supersonic.headless.core.pojo.Database;
|
||||
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
|
||||
@@ -11,13 +12,6 @@ import org.springframework.stereotype.Component;
|
||||
@Component("JdbcExecutor")
|
||||
@Slf4j
|
||||
public class JdbcExecutor implements QueryExecutor {
|
||||
|
||||
private final SqlUtils sqlUtils;
|
||||
|
||||
public JdbcExecutor(SqlUtils sqlUtils) {
|
||||
this.sqlUtils = sqlUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(QueryStatement queryStatement) {
|
||||
return true;
|
||||
@@ -25,6 +19,7 @@ public class JdbcExecutor implements QueryExecutor {
|
||||
|
||||
@Override
|
||||
public SemanticQueryResp execute(QueryStatement queryStatement) {
|
||||
SqlUtils sqlUtils = ContextUtils.getBean(SqlUtils.class);
|
||||
if (Strings.isEmpty(queryStatement.getSourceId())) {
|
||||
log.warn("data base id is empty");
|
||||
return null;
|
||||
@@ -32,8 +27,8 @@ public class JdbcExecutor implements QueryExecutor {
|
||||
log.info("query SQL: {}", queryStatement.getSql());
|
||||
Database database = queryStatement.getSemanticModel().getDatabase();
|
||||
SemanticQueryResp queryResultWithColumns = new SemanticQueryResp();
|
||||
SqlUtils sqlUtils = this.sqlUtils.init(database);
|
||||
sqlUtils.queryInternal(queryStatement.getSql(), queryResultWithColumns);
|
||||
SqlUtils sqlUtil = sqlUtils.init(database);
|
||||
sqlUtil.queryInternal(queryStatement.getSql(), queryResultWithColumns);
|
||||
queryResultWithColumns.setSql(queryStatement.getSql());
|
||||
return queryResultWithColumns;
|
||||
}
|
||||
|
||||
@@ -9,19 +9,18 @@ import com.tencent.supersonic.headless.api.pojo.MetricTable;
|
||||
import com.tencent.supersonic.headless.api.pojo.QueryParam;
|
||||
import com.tencent.supersonic.headless.api.pojo.enums.AggOption;
|
||||
import com.tencent.supersonic.headless.api.pojo.enums.EngineType;
|
||||
import com.tencent.supersonic.headless.core.pojo.DataSetQueryParam;
|
||||
import com.tencent.supersonic.headless.core.pojo.Database;
|
||||
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.headless.core.pojo.DataSetQueryParam;
|
||||
import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* supplement the QueryStatement when query with custom aggregation method
|
||||
@@ -30,12 +29,6 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class CalculateAggConverter implements HeadlessConverter {
|
||||
|
||||
private final SqlGenerateUtils sqlGenerateUtils;
|
||||
|
||||
|
||||
public CalculateAggConverter(SqlGenerateUtils sqlGenerateUtils) {
|
||||
this.sqlGenerateUtils = sqlGenerateUtils;
|
||||
}
|
||||
|
||||
public interface EngineSql {
|
||||
|
||||
@@ -45,6 +38,7 @@ public class CalculateAggConverter implements HeadlessConverter {
|
||||
public DataSetQueryParam generateSqlCommend(QueryStatement queryStatement,
|
||||
EngineType engineTypeEnum, String version)
|
||||
throws Exception {
|
||||
SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class);
|
||||
QueryParam queryParam = queryStatement.getQueryParam();
|
||||
// 同环比
|
||||
if (isRatioAccept(queryParam)) {
|
||||
@@ -132,6 +126,7 @@ public class CalculateAggConverter implements HeadlessConverter {
|
||||
public DataSetQueryParam generateRatioSqlCommand(QueryStatement queryStatement, EngineType engineTypeEnum,
|
||||
String version)
|
||||
throws Exception {
|
||||
SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class);
|
||||
QueryParam queryParam = queryStatement.getQueryParam();
|
||||
check(queryParam);
|
||||
queryStatement.setEnableOptimize(false);
|
||||
@@ -412,6 +407,7 @@ public class CalculateAggConverter implements HeadlessConverter {
|
||||
}
|
||||
|
||||
private String getSelectField(final Aggregator agg, String alias) {
|
||||
SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class);
|
||||
if (agg.getFunc().equals(AggOperatorEnum.RATIO_OVER) || agg.getFunc().equals(AggOperatorEnum.RATIO_ROLL)) {
|
||||
return alias + agg.getColumn();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package com.tencent.supersonic.headless.core.parser.converter;
|
||||
|
||||
import com.tencent.supersonic.common.pojo.ColumnOrder;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.headless.api.pojo.QueryParam;
|
||||
import com.tencent.supersonic.headless.core.parser.calcite.s2sql.DataSource;
|
||||
import com.tencent.supersonic.headless.core.pojo.MetricQueryParam;
|
||||
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* HeadlessConverter default implement
|
||||
*/
|
||||
@@ -22,26 +22,18 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class ParserDefaultConverter implements HeadlessConverter {
|
||||
|
||||
private final SqlGenerateUtils sqlGenerateUtils;
|
||||
|
||||
private final CalculateAggConverter calculateConverterAgg;
|
||||
|
||||
public ParserDefaultConverter(CalculateAggConverter calculateConverterAgg,
|
||||
SqlGenerateUtils sqlGenerateUtils) {
|
||||
this.calculateConverterAgg = calculateConverterAgg;
|
||||
this.sqlGenerateUtils = sqlGenerateUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(QueryStatement queryStatement) {
|
||||
if (Objects.isNull(queryStatement.getQueryParam()) || queryStatement.getIsS2SQL()) {
|
||||
return false;
|
||||
}
|
||||
CalculateAggConverter calculateConverterAgg = ContextUtils.getBean(CalculateAggConverter.class);
|
||||
return !calculateConverterAgg.accept(queryStatement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convert(QueryStatement queryStatement) throws Exception {
|
||||
SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class);
|
||||
QueryParam queryParam = queryStatement.getQueryParam();
|
||||
MetricQueryParam metricQueryParam = queryStatement.getMetricQueryParam();
|
||||
MetricQueryParam metricReq = generateSqlCommand(queryStatement.getQueryParam(), queryStatement);
|
||||
@@ -50,6 +42,7 @@ public class ParserDefaultConverter implements HeadlessConverter {
|
||||
}
|
||||
|
||||
public MetricQueryParam generateSqlCommand(QueryParam queryParam, QueryStatement queryStatement) {
|
||||
SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class);
|
||||
MetricQueryParam metricQueryParam = new MetricQueryParam();
|
||||
metricQueryParam.setMetrics(queryParam.getMetrics());
|
||||
metricQueryParam.setDimensions(queryParam.getGroups());
|
||||
|
||||
@@ -1,30 +1,23 @@
|
||||
package com.tencent.supersonic.headless.core.utils;
|
||||
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import com.tencent.supersonic.headless.core.cache.QueryCache;
|
||||
import com.tencent.supersonic.headless.core.chat.parser.JavaLLMProxy;
|
||||
import com.tencent.supersonic.headless.core.chat.parser.LLMProxy;
|
||||
import com.tencent.supersonic.headless.core.chat.parser.llm.DataSetResolver;
|
||||
import com.tencent.supersonic.headless.core.executor.JdbcExecutor;
|
||||
import com.tencent.supersonic.headless.core.executor.QueryExecutor;
|
||||
import com.tencent.supersonic.headless.core.parser.SqlParser;
|
||||
import com.tencent.supersonic.headless.core.parser.calcite.CalciteSqlParser;
|
||||
import com.tencent.supersonic.headless.core.parser.converter.CalculateAggConverter;
|
||||
import com.tencent.supersonic.headless.core.parser.converter.DefaultDimValueConverter;
|
||||
import com.tencent.supersonic.headless.core.parser.converter.HeadlessConverter;
|
||||
import com.tencent.supersonic.headless.core.parser.converter.ParserDefaultConverter;
|
||||
import com.tencent.supersonic.headless.core.parser.converter.SqlVariableParseConverter;
|
||||
import com.tencent.supersonic.headless.core.planner.DetailQueryOptimizer;
|
||||
import com.tencent.supersonic.headless.core.planner.QueryOptimizer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
||||
/**
|
||||
* HeadlessConverter QueryOptimizer QueryExecutor object factory
|
||||
@@ -36,6 +29,7 @@ public class ComponentFactory {
|
||||
private static Map<String, QueryOptimizer> queryOptimizers = new HashMap<>();
|
||||
private static List<QueryExecutor> queryExecutors = new ArrayList<>();
|
||||
private static SqlParser sqlParser;
|
||||
private static QueryCache queryCache;
|
||||
|
||||
private static LLMProxy llmProxy;
|
||||
private static DataSetResolver modelResolver;
|
||||
@@ -69,11 +63,18 @@ public class ComponentFactory {
|
||||
|
||||
public static SqlParser getSqlParser() {
|
||||
if (sqlParser == null) {
|
||||
sqlParser = ContextUtils.getContext().getBean("CalciteSqlParser", CalciteSqlParser.class);
|
||||
initQueryParser();
|
||||
}
|
||||
return sqlParser;
|
||||
}
|
||||
|
||||
public static QueryCache getQueryCache() {
|
||||
if (queryCache == null) {
|
||||
initQueryCache();
|
||||
}
|
||||
return queryCache;
|
||||
}
|
||||
|
||||
public static void setSqlParser(SqlParser parser) {
|
||||
sqlParser = parser;
|
||||
}
|
||||
@@ -82,23 +83,29 @@ public class ComponentFactory {
|
||||
queryOptimizers.put(name, queryOptimizer);
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> tClass) {
|
||||
return ContextUtils.getContext().getBean(name, tClass);
|
||||
}
|
||||
|
||||
private static void initQueryOptimizer() {
|
||||
queryOptimizers.put("DetailQueryOptimizer", getBean("DetailQueryOptimizer", DetailQueryOptimizer.class));
|
||||
List<QueryOptimizer> queryOptimizerList = new ArrayList<>();
|
||||
init(QueryOptimizer.class, queryOptimizerList);
|
||||
if (!queryOptimizerList.isEmpty()) {
|
||||
queryOptimizerList.stream().forEach(q -> addQueryOptimizer(q.getClass().getSimpleName(), q));
|
||||
}
|
||||
}
|
||||
|
||||
private static void initQueryExecutors() {
|
||||
queryExecutors.add(ContextUtils.getContext().getBean("JdbcExecutor", JdbcExecutor.class));
|
||||
//queryExecutors.add(ContextUtils.getContext().getBean("JdbcExecutor", JdbcExecutor.class));
|
||||
init(QueryExecutor.class, queryExecutors);
|
||||
}
|
||||
|
||||
private static void initSemanticConverter() {
|
||||
headlessConverters.add(getBean("DefaultDimValueConverter", DefaultDimValueConverter.class));
|
||||
headlessConverters.add(getBean("SqlVariableParseConverter", SqlVariableParseConverter.class));
|
||||
headlessConverters.add(getBean("CalculateAggConverter", CalculateAggConverter.class));
|
||||
headlessConverters.add(getBean("ParserDefaultConverter", ParserDefaultConverter.class));
|
||||
init(HeadlessConverter.class, headlessConverters);
|
||||
}
|
||||
|
||||
private static void initQueryParser() {
|
||||
sqlParser = init(SqlParser.class);
|
||||
}
|
||||
|
||||
private static void initQueryCache() {
|
||||
queryCache = init(QueryCache.class);
|
||||
}
|
||||
|
||||
public static LLMProxy getLLMProxy() {
|
||||
@@ -127,6 +134,10 @@ public class ComponentFactory {
|
||||
return modelResolver;
|
||||
}
|
||||
|
||||
public static <T> T getBean(String name, Class<T> tClass) {
|
||||
return ContextUtils.getContext().getBean(name, tClass);
|
||||
}
|
||||
|
||||
private static <T> List<T> init(Class<T> factoryType, List list) {
|
||||
list.addAll(SpringFactoriesLoader.loadFactories(factoryType,
|
||||
Thread.currentThread().getContextClassLoader()));
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.tencent.supersonic.headless.core.parser.QueryParser;
|
||||
import com.tencent.supersonic.headless.core.parser.calcite.s2sql.SemanticModel;
|
||||
import com.tencent.supersonic.headless.core.planner.QueryPlanner;
|
||||
import com.tencent.supersonic.headless.core.pojo.QueryStatement;
|
||||
import com.tencent.supersonic.headless.core.utils.ComponentFactory;
|
||||
import com.tencent.supersonic.headless.server.annotation.S2DataPermission;
|
||||
import com.tencent.supersonic.headless.server.aspect.ApiHeaderCheckAspect;
|
||||
import com.tencent.supersonic.headless.server.manager.SemanticSchemaManager;
|
||||
@@ -75,7 +76,6 @@ public class QueryServiceImpl implements QueryService {
|
||||
private final TagConverter tagConverter;
|
||||
private final Catalog catalog;
|
||||
private final AppService appService;
|
||||
private final QueryCache queryCache;
|
||||
private final SemanticSchemaManager semanticSchemaManager;
|
||||
private final QueryParser queryParser;
|
||||
private final QueryPlanner queryPlanner;
|
||||
@@ -86,7 +86,6 @@ public class QueryServiceImpl implements QueryService {
|
||||
QueryReqConverter queryReqConverter,
|
||||
TagConverter tagConverter, Catalog catalog,
|
||||
AppService appService,
|
||||
QueryCache queryCache,
|
||||
SemanticSchemaManager semanticSchemaManager,
|
||||
DefaultQueryParser queryParser,
|
||||
QueryPlanner queryPlanner) {
|
||||
@@ -96,7 +95,6 @@ public class QueryServiceImpl implements QueryService {
|
||||
this.tagConverter = tagConverter;
|
||||
this.catalog = catalog;
|
||||
this.appService = appService;
|
||||
this.queryCache = queryCache;
|
||||
this.semanticSchemaManager = semanticSchemaManager;
|
||||
this.queryParser = queryParser;
|
||||
this.queryPlanner = queryPlanner;
|
||||
@@ -112,6 +110,7 @@ public class QueryServiceImpl implements QueryService {
|
||||
//1.initStatInfo
|
||||
statUtils.initStatInfo(queryReq, user);
|
||||
//2.query from cache
|
||||
QueryCache queryCache = ComponentFactory.getQueryCache();
|
||||
String cacheKey = queryCache.getCacheKey(queryReq);
|
||||
Object query = queryCache.query(queryReq, cacheKey);
|
||||
if (Objects.nonNull(query)) {
|
||||
|
||||
@@ -6,3 +6,22 @@ com.tencent.supersonic.auth.api.authentication.adaptor.UserAdaptor=\
|
||||
|
||||
com.tencent.supersonic.common.util.embedding.S2EmbeddingStore=\
|
||||
com.tencent.supersonic.common.util.embedding.InMemoryS2EmbeddingStore
|
||||
|
||||
|
||||
com.tencent.supersonic.headless.core.parser.converter.HeadlessConverter=\
|
||||
com.tencent.supersonic.headless.core.parser.converter.DefaultDimValueConverter,\
|
||||
com.tencent.supersonic.headless.core.parser.converter.SqlVariableParseConverter,\
|
||||
com.tencent.supersonic.headless.core.parser.converter.CalculateAggConverter,\
|
||||
com.tencent.supersonic.headless.core.parser.converter.ParserDefaultConverter
|
||||
|
||||
com.tencent.supersonic.headless.core.planner.QueryOptimizer=\
|
||||
com.tencent.supersonic.headless.core.planner.DetailQueryOptimizer
|
||||
|
||||
com.tencent.supersonic.headless.core.executor.QueryExecutor=\
|
||||
com.tencent.supersonic.headless.core.executor.JdbcExecutor
|
||||
|
||||
com.tencent.supersonic.headless.core.parser.SqlParser=\
|
||||
com.tencent.supersonic.headless.core.parser.calcite.CalciteSqlParser
|
||||
|
||||
com.tencent.supersonic.headless.core.cache.QueryCache=\
|
||||
com.tencent.supersonic.headless.core.cache.DefaultQueryCache
|
||||
@@ -14,6 +14,24 @@ com.tencent.supersonic.headless.core.chat.corrector.SemanticCorrector=\
|
||||
com.tencent.supersonic.headless.core.chat.corrector.TimeCorrector, \
|
||||
com.tencent.supersonic.headless.core.chat.corrector.GrammarCorrector
|
||||
|
||||
com.tencent.supersonic.headless.core.parser.converter.HeadlessConverter=\
|
||||
com.tencent.supersonic.headless.core.parser.converter.DefaultDimValueConverter,\
|
||||
com.tencent.supersonic.headless.core.parser.converter.SqlVariableParseConverter,\
|
||||
com.tencent.supersonic.headless.core.parser.converter.CalculateAggConverter,\
|
||||
com.tencent.supersonic.headless.core.parser.converter.ParserDefaultConverter
|
||||
|
||||
com.tencent.supersonic.headless.core.planner.QueryOptimizer=\
|
||||
com.tencent.supersonic.headless.core.planner.DetailQueryOptimizer
|
||||
|
||||
com.tencent.supersonic.headless.core.executor.QueryExecutor=\
|
||||
com.tencent.supersonic.headless.core.executor.JdbcExecutor
|
||||
|
||||
com.tencent.supersonic.headless.core.parser.SqlParser=\
|
||||
com.tencent.supersonic.headless.core.parser.calcite.CalciteSqlParser
|
||||
|
||||
com.tencent.supersonic.headless.core.cache.QueryCache=\
|
||||
com.tencent.supersonic.headless.core.cache.DefaultQueryCache
|
||||
|
||||
com.tencent.supersonic.headless.server.processor.ResultProcessor=\
|
||||
com.tencent.supersonic.headless.server.processor.ParseInfoProcessor, \
|
||||
com.tencent.supersonic.headless.server.processor.QueryRankProcessor, \
|
||||
|
||||
Reference in New Issue
Block a user