Authored by hugufei

拆包

1 -package com.yoho.search.recall.scene.beans;  
2 -  
3 -  
4 -import com.yoho.search.base.utils.ISearchConstants;  
5 -import com.yoho.search.base.utils.ProductIndexEsField;  
6 -import com.yoho.search.core.es.model.SearchParam;  
7 -import com.yoho.search.core.es.model.SearchResult;  
8 -import com.yoho.search.recall.scene.cache.CacheRequestResponseComponent;  
9 -import com.yoho.search.recall.scene.cache.CacheSknInfoRequestResponse;  
10 -import com.yoho.search.recall.scene.models.SknInfoRequest;  
11 -import com.yoho.search.service.base.SearchCommonService;  
12 -import com.yoho.search.service.base.index.ProductIndexBaseService;  
13 -import org.apache.commons.collections.MapUtils;  
14 -import org.elasticsearch.index.query.QueryBuilders;  
15 -import org.springframework.beans.factory.annotation.Autowired;  
16 -import org.springframework.stereotype.Component;  
17 -  
18 -import java.util.ArrayList;  
19 -import java.util.HashMap;  
20 -import java.util.List;  
21 -import java.util.Map;  
22 -  
23 -@Component  
24 -public class BacthSknInfoComponent {  
25 -  
26 - @Autowired  
27 - private SearchCommonService searchCommonService;  
28 - @Autowired  
29 - private ProductIndexBaseService productIndexBaseService;  
30 - @Autowired  
31 - private CacheRequestResponseComponent cacheRequestResponseComponent;  
32 -  
33 - private static final boolean useEhCache = true;  
34 -  
35 - /**  
36 - * 按skn查询并按顺序返回  
37 - *  
38 - * @param productSkns  
39 - * @return  
40 - */  
41 - public List<Map<String, Object>> queryProductListBySkn(List<Integer> productSkns,int size){  
42 - //1、批量查询SKN信息  
43 - List<CacheSknInfoRequestResponse> sknInfoCacheRequestRespons = this.batchQuery(productSkns);  
44 - //2、构造返回结果  
45 - List<Map<String, Object>> finalResults = new ArrayList<>();  
46 - for (CacheSknInfoRequestResponse sknInfoCacheRequestResponse : sknInfoCacheRequestRespons) {  
47 - if(sknInfoCacheRequestResponse !=null && sknInfoCacheRequestResponse.getResponse()!=null){  
48 - finalResults.add(sknInfoCacheRequestResponse.getResponse());  
49 - }  
50 - if(finalResults.size()>=size){  
51 - break;  
52 - }  
53 - }  
54 - return finalResults;  
55 - }  
56 -  
57 - private List<CacheSknInfoRequestResponse> batchQuery(List<Integer> productSkns){  
58 - //1、构建请求与返回结果  
59 - final List<CacheSknInfoRequestResponse> sknInfoCacheRequestRespons = new ArrayList<>();  
60 - for (Integer productSkn : productSkns) {  
61 - sknInfoCacheRequestRespons.add(new CacheSknInfoRequestResponse(new SknInfoRequest(productSkn)));  
62 - }  
63 - //2、批量从缓存中获取  
64 - cacheRequestResponseComponent.batchFillResponseFromCache(sknInfoCacheRequestRespons,useEhCache);  
65 - //3、获取未命中缓存的请求  
66 - List<CacheSknInfoRequestResponse> missCacheRequests = cacheRequestResponseComponent.filterMissCacheRequests(sknInfoCacheRequestRespons);  
67 - //4、执行批量查询  
68 - Map<String,Map<String, Object>> queryResults = this.batchQueryMissCacheRequests(missCacheRequests);  
69 - //5、填充查询结果  
70 - cacheRequestResponseComponent.batchFillResponseWithQueryResults(sknInfoCacheRequestRespons,queryResults);  
71 - //6、将CacheRequestResponse中需要缓存的key加入缓存  
72 - cacheRequestResponseComponent.batchAddResponseToCache(sknInfoCacheRequestRespons,useEhCache);  
73 - return sknInfoCacheRequestRespons;  
74 - }  
75 -  
76 - private Map<String,Map<String, Object>> batchQueryMissCacheRequests(List<CacheSknInfoRequestResponse> notCachedRequestResponse) {  
77 - //1、合法性判断  
78 - Map<String,Map<String, Object>> results = new HashMap<>();  
79 - if(notCachedRequestResponse==null||notCachedRequestResponse.isEmpty()){  
80 - return results;  
81 - }  
82 - //2、获取skn  
83 - List<Integer> productSkns = new ArrayList<>();  
84 - for (CacheSknInfoRequestResponse sknInfoCacheRequestResponse : notCachedRequestResponse) {  
85 - productSkns.add(sknInfoCacheRequestResponse.getRequest().getProductSkn());  
86 - }  
87 - //3、构建SearchParam  
88 - SearchParam searchParam = new SearchParam();  
89 - searchParam.setOffset(0);  
90 - searchParam.setSize(productSkns.size());  
91 - searchParam.setFiter(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, productSkns));  
92 - searchParam.setIncludeFields(productIndexBaseService.getProductIndexIncludeFields());  
93 - SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);  
94 - List<Map<String, Object>> productList = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());  
95 - //4、构建SKN临时结果  
96 - Map<Integer,Map<String, Object>> productTempMap = new HashMap<>();  
97 - for (Map<String, Object> product: productList) {  
98 - productTempMap.put(MapUtils.getIntValue(product,"product_skn",0),product);  
99 - }  
100 - //5、构造最终结果  
101 - for (CacheSknInfoRequestResponse requestResponse :notCachedRequestResponse ) {  
102 - results.put(requestResponse.getRequest().redisKeyBuilder().getKey(),productTempMap.get(requestResponse.getRequest().getProductSkn()));  
103 - }  
104 - return results;  
105 - }  
106 -  
107 -  
108 -} 1 +package com.yoho.search.recall.scene.beans;
  2 +
  3 +
  4 +import com.yoho.search.base.utils.ISearchConstants;
  5 +import com.yoho.search.base.utils.ProductIndexEsField;
  6 +import com.yoho.search.core.es.model.SearchParam;
  7 +import com.yoho.search.core.es.model.SearchResult;
  8 +import com.yoho.search.recall.scene.cache.CacheRequestResponseComponent;
  9 +import com.yoho.search.recall.scene.cache.CacheSknInfoRequestResponse;
  10 +import com.yoho.search.recall.scene.models.SknInfoRequest;
  11 +import com.yoho.search.service.base.SearchCommonService;
  12 +import com.yoho.search.service.base.index.ProductIndexBaseService;
  13 +import org.apache.commons.collections.MapUtils;
  14 +import org.elasticsearch.index.query.QueryBuilders;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.stereotype.Component;
  17 +
  18 +import java.util.ArrayList;
  19 +import java.util.HashMap;
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +
  23 +@Component
  24 +public class BacthSknInfoComponent {
  25 +
  26 + @Autowired
  27 + private SearchCommonService searchCommonService;
  28 + @Autowired
  29 + private ProductIndexBaseService productIndexBaseService;
  30 + @Autowired
  31 + private CacheRequestResponseComponent cacheRequestResponseComponent;
  32 +
  33 + private static final boolean useEhCache = true;
  34 +
  35 + /**
  36 + * 按skn查询并按顺序返回
  37 + *
  38 + * @param productSkns
  39 + * @return
  40 + */
  41 + public List<Map<String, Object>> queryProductListBySkn(List<Integer> productSkns,int size){
  42 + //1、批量查询SKN信息
  43 + List<CacheSknInfoRequestResponse> sknInfoCacheRequestRespons = this.batchQuery(productSkns);
  44 + //2、构造返回结果
  45 + List<Map<String, Object>> finalResults = new ArrayList<>();
  46 + for (CacheSknInfoRequestResponse sknInfoCacheRequestResponse : sknInfoCacheRequestRespons) {
  47 + if(sknInfoCacheRequestResponse !=null && sknInfoCacheRequestResponse.getResponse()!=null){
  48 + finalResults.add(sknInfoCacheRequestResponse.getResponse());
  49 + }
  50 + if(finalResults.size()>=size){
  51 + break;
  52 + }
  53 + }
  54 + return finalResults;
  55 + }
  56 +
  57 + private List<CacheSknInfoRequestResponse> batchQuery(List<Integer> productSkns){
  58 + //1、构建请求与返回结果
  59 + final List<CacheSknInfoRequestResponse> sknInfoCacheRequestRespons = new ArrayList<>();
  60 + for (Integer productSkn : productSkns) {
  61 + sknInfoCacheRequestRespons.add(new CacheSknInfoRequestResponse(new SknInfoRequest(productSkn)));
  62 + }
  63 + //2、批量从缓存中获取
  64 + cacheRequestResponseComponent.batchFillResponseFromCache(sknInfoCacheRequestRespons,useEhCache);
  65 + //3、获取未命中缓存的请求
  66 + List<CacheSknInfoRequestResponse> missCacheRequests = cacheRequestResponseComponent.filterMissCacheRequests(sknInfoCacheRequestRespons);
  67 + //4、执行批量查询
  68 + Map<String,Map<String, Object>> queryResults = this.batchQueryMissCacheRequests(missCacheRequests);
  69 + //5、填充查询结果
  70 + cacheRequestResponseComponent.batchFillResponseWithQueryResults(sknInfoCacheRequestRespons,queryResults);
  71 + //6、将CacheRequestResponse中需要缓存的key加入缓存
  72 + cacheRequestResponseComponent.batchAddResponseToCache(sknInfoCacheRequestRespons,useEhCache);
  73 + return sknInfoCacheRequestRespons;
  74 + }
  75 +
  76 + private Map<String,Map<String, Object>> batchQueryMissCacheRequests(List<CacheSknInfoRequestResponse> notCachedRequestResponse) {
  77 + //1、合法性判断
  78 + Map<String,Map<String, Object>> results = new HashMap<>();
  79 + if(notCachedRequestResponse==null||notCachedRequestResponse.isEmpty()){
  80 + return results;
  81 + }
  82 + //2、获取skn
  83 + List<Integer> productSkns = new ArrayList<>();
  84 + for (CacheSknInfoRequestResponse sknInfoCacheRequestResponse : notCachedRequestResponse) {
  85 + productSkns.add(sknInfoCacheRequestResponse.getRequest().getProductSkn());
  86 + }
  87 + //3、构建SearchParam
  88 + SearchParam searchParam = new SearchParam();
  89 + searchParam.setOffset(0);
  90 + searchParam.setSize(productSkns.size());
  91 + searchParam.setFiter(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, productSkns));
  92 + searchParam.setIncludeFields(productIndexBaseService.getProductIndexIncludeFields());
  93 + SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
  94 + List<Map<String, Object>> productList = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());
  95 + //4、构建SKN临时结果
  96 + Map<Integer,Map<String, Object>> productTempMap = new HashMap<>();
  97 + for (Map<String, Object> product: productList) {
  98 + productTempMap.put(MapUtils.getIntValue(product,"product_skn",0),product);
  99 + }
  100 + //5、构造最终结果
  101 + for (CacheSknInfoRequestResponse requestResponse :notCachedRequestResponse ) {
  102 + results.put(requestResponse.getRequest().redisKeyBuilder().getKey(),productTempMap.get(requestResponse.getRequest().getProductSkn()));
  103 + }
  104 + return results;
  105 + }
  106 +
  107 +
  108 +}
1 -package com.yoho.search.recall.scene.beans;  
2 -  
3 -import com.yoho.search.base.utils.ISearchConstants;  
4 -import com.yoho.search.base.utils.ProductIndexEsField;  
5 -import com.yoho.search.core.es.model.SearchParam;  
6 -import com.yoho.search.core.es.model.SearchResult;  
7 -import com.yoho.search.recall.scene.cache.CacheRequestResponseComponent;  
8 -import com.yoho.search.recall.scene.cache.CacheRecallRequestResponse;  
9 -import com.yoho.search.recall.scene.models.RecallRequest;  
10 -import com.yoho.search.recall.scene.models.RecallResponse;  
11 -import com.yoho.search.service.base.SearchCommonService;  
12 -import org.apache.commons.collections.MapUtils;  
13 -import org.slf4j.Logger;  
14 -import org.slf4j.LoggerFactory;  
15 -import org.springframework.beans.factory.annotation.Autowired;  
16 -import org.springframework.stereotype.Component;  
17 -  
18 -import java.util.ArrayList;  
19 -import java.util.HashMap;  
20 -import java.util.List;  
21 -import java.util.Map;  
22 -  
23 -@Component  
24 -public class BatchRecallComponent {  
25 -  
26 - private static final Logger logger = LoggerFactory.getLogger(BatchRecallComponent.class);  
27 -  
28 - @Autowired  
29 - private CacheRequestResponseComponent cacheRequestResponseHelper;  
30 - @Autowired  
31 - private SearchCommonService searchCommonService;  
32 -  
33 - private static final boolean useEhCache = false;  
34 -  
35 - /**  
36 - * 批量召回入口  
37 - *  
38 - * @param batchRequests  
39 - * @return  
40 - */  
41 - public List<CacheRecallRequestResponse> batchRecallAndCache(final List<RecallRequest> batchRequests) {  
42 - //1、构造返回结果  
43 - final List<CacheRecallRequestResponse> recallRequestResponses = new ArrayList<>();  
44 - for (RecallRequest request : batchRequests) {  
45 - recallRequestResponses.add(new CacheRecallRequestResponse(request));  
46 - }  
47 - //2、先从缓存中填充response  
48 - cacheRequestResponseHelper.batchFillResponseFromCache(recallRequestResponses,useEhCache);  
49 -  
50 - //3、构造未命中缓存的请求-最多透传x个  
51 - final List<CacheRecallRequestResponse> missCacheRequests =cacheRequestResponseHelper.filterMissCacheRequests(recallRequestResponses);  
52 -  
53 - //4、如果remainRequests为空,则说明全部命中了缓存,直接返回即可  
54 - if (missCacheRequests.isEmpty()) {  
55 - return recallRequestResponses;  
56 - }  
57 -  
58 - //5、处理剩余请求  
59 - Map<String,RecallResponse> notCacheResults = this.queryNotCachedResult(missCacheRequests);  
60 -  
61 - //6、填充recallRequestResponses  
62 - cacheRequestResponseHelper.batchFillResponseWithQueryResults(recallRequestResponses,notCacheResults);  
63 -  
64 - //7、将尚未缓存的对象加入缓存  
65 - cacheRequestResponseHelper.batchAddResponseToCache(recallRequestResponses,useEhCache);  
66 -  
67 - return recallRequestResponses;  
68 -  
69 - }  
70 -  
71 - /**  
72 - * 查询命中缓存的请求  
73 - * @param notCachedRequests  
74 - * @return  
75 - */  
76 - private Map<String,RecallResponse> queryNotCachedResult(List<CacheRecallRequestResponse> notCachedRequests) {  
77 - //1、构造请求参数  
78 - List<SearchParam> searchParams = new ArrayList<>();  
79 - for (CacheRecallRequestResponse requestResponse : notCachedRequests) {  
80 - searchParams.add(requestResponse.getRequest().searchParam());  
81 - }  
82 - //2、执行搜索  
83 - List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);  
84 - //3、构造返回结果  
85 - Map<String,RecallResponse> notCachedResults = new HashMap<>();  
86 - for (int i = 0; i < notCachedRequests.size(); i++) {  
87 - RecallRequest request = notCachedRequests.get(i).getRequest();  
88 - SearchResult searchResult = searchResults.get(i);  
89 - RecallResponse response = this.buildResonse(searchResult);  
90 - notCachedResults.put(request.redisKeyBuilder().getKey(),response);  
91 - }  
92 - return notCachedResults;  
93 - }  
94 -  
95 - private RecallResponse buildResonse(SearchResult searchResult) {  
96 - List<Map<String, Object>> results = searchResult.getResultList();  
97 - List<RecallResponse.RecallSkn> recallSkns = new ArrayList<>();  
98 - for (Map<String, Object> result : results) {  
99 - Integer productSkn = MapUtils.getInteger(result, ProductIndexEsField.productSkn, 0);  
100 - Integer brandId = MapUtils.getInteger(result, ProductIndexEsField.brandId, 0);  
101 - Integer middleSortId = MapUtils.getInteger(result, ProductIndexEsField.middleSortId, 0);  
102 - recallSkns.add(new RecallResponse.RecallSkn(productSkn, brandId, middleSortId));  
103 - }  
104 - return new RecallResponse(searchResult.getTotal(), recallSkns);  
105 - }  
106 -  
107 -} 1 +package com.yoho.search.recall.scene.beans;
  2 +
  3 +import com.yoho.search.base.utils.ISearchConstants;
  4 +import com.yoho.search.base.utils.ProductIndexEsField;
  5 +import com.yoho.search.core.es.model.SearchParam;
  6 +import com.yoho.search.core.es.model.SearchResult;
  7 +import com.yoho.search.recall.scene.cache.CacheRequestResponseComponent;
  8 +import com.yoho.search.recall.scene.cache.CacheRecallRequestResponse;
  9 +import com.yoho.search.recall.scene.models.RecallRequest;
  10 +import com.yoho.search.recall.scene.models.RecallResponse;
  11 +import com.yoho.search.service.base.SearchCommonService;
  12 +import org.apache.commons.collections.MapUtils;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.stereotype.Component;
  17 +
  18 +import java.util.ArrayList;
  19 +import java.util.HashMap;
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +
  23 +@Component
  24 +public class BatchRecallComponent {
  25 +
  26 + private static final Logger logger = LoggerFactory.getLogger(BatchRecallComponent.class);
  27 +
  28 + @Autowired
  29 + private CacheRequestResponseComponent cacheRequestResponseHelper;
  30 + @Autowired
  31 + private SearchCommonService searchCommonService;
  32 +
  33 + private static final boolean useEhCache = false;
  34 +
  35 + /**
  36 + * 批量召回入口
  37 + *
  38 + * @param batchRequests
  39 + * @return
  40 + */
  41 + public List<CacheRecallRequestResponse> batchRecallAndCache(final List<RecallRequest> batchRequests) {
  42 + //1、构造返回结果
  43 + final List<CacheRecallRequestResponse> recallRequestResponses = new ArrayList<>();
  44 + for (RecallRequest request : batchRequests) {
  45 + recallRequestResponses.add(new CacheRecallRequestResponse(request));
  46 + }
  47 + //2、先从缓存中填充response
  48 + cacheRequestResponseHelper.batchFillResponseFromCache(recallRequestResponses,useEhCache);
  49 +
  50 + //3、构造未命中缓存的请求-最多透传x个
  51 + final List<CacheRecallRequestResponse> missCacheRequests =cacheRequestResponseHelper.filterMissCacheRequests(recallRequestResponses);
  52 +
  53 + //4、如果remainRequests为空,则说明全部命中了缓存,直接返回即可
  54 + if (missCacheRequests.isEmpty()) {
  55 + return recallRequestResponses;
  56 + }
  57 +
  58 + //5、处理剩余请求
  59 + Map<String,RecallResponse> notCacheResults = this.queryNotCachedResult(missCacheRequests);
  60 +
  61 + //6、填充recallRequestResponses
  62 + cacheRequestResponseHelper.batchFillResponseWithQueryResults(recallRequestResponses,notCacheResults);
  63 +
  64 + //7、将尚未缓存的对象加入缓存
  65 + cacheRequestResponseHelper.batchAddResponseToCache(recallRequestResponses,useEhCache);
  66 +
  67 + return recallRequestResponses;
  68 +
  69 + }
  70 +
  71 + /**
  72 + * 查询命中缓存的请求
  73 + * @param notCachedRequests
  74 + * @return
  75 + */
  76 + private Map<String,RecallResponse> queryNotCachedResult(List<CacheRecallRequestResponse> notCachedRequests) {
  77 + //1、构造请求参数
  78 + List<SearchParam> searchParams = new ArrayList<>();
  79 + for (CacheRecallRequestResponse requestResponse : notCachedRequests) {
  80 + searchParams.add(requestResponse.getRequest().searchParam());
  81 + }
  82 + //2、执行搜索
  83 + List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
  84 + //3、构造返回结果
  85 + Map<String,RecallResponse> notCachedResults = new HashMap<>();
  86 + for (int i = 0; i < notCachedRequests.size(); i++) {
  87 + RecallRequest request = notCachedRequests.get(i).getRequest();
  88 + SearchResult searchResult = searchResults.get(i);
  89 + RecallResponse response = this.buildResonse(searchResult);
  90 + notCachedResults.put(request.redisKeyBuilder().getKey(),response);
  91 + }
  92 + return notCachedResults;
  93 + }
  94 +
  95 + private RecallResponse buildResonse(SearchResult searchResult) {
  96 + List<Map<String, Object>> results = searchResult.getResultList();
  97 + List<RecallResponse.RecallSkn> recallSkns = new ArrayList<>();
  98 + for (Map<String, Object> result : results) {
  99 + Integer productSkn = MapUtils.getInteger(result, ProductIndexEsField.productSkn, 0);
  100 + Integer brandId = MapUtils.getInteger(result, ProductIndexEsField.brandId, 0);
  101 + Integer middleSortId = MapUtils.getInteger(result, ProductIndexEsField.middleSortId, 0);
  102 + recallSkns.add(new RecallResponse.RecallSkn(productSkn, brandId, middleSortId));
  103 + }
  104 + return new RecallResponse(searchResult.getTotal(), recallSkns);
  105 + }
  106 +
  107 +}
1 -package com.yoho.search.recall.scene.beans;  
2 -  
3 -public class RecallSknComponent {  
4 -} 1 +package com.yoho.search.recall.scene.beans;
  2 +
  3 +public class RecallSknComponent {
  4 +}
1 -package com.yoho.search.recall.scene.cache;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
5 -import com.yoho.search.base.utils.Transfer;  
6 -import com.yoho.search.recall.scene.cache.CacheRequestResponse;  
7 -import com.yoho.search.recall.scene.models.RecallRequest;  
8 -import com.yoho.search.recall.scene.models.RecallResponse;  
9 -  
10 -public class CacheRecallRequestResponse extends CacheRequestResponse<RecallRequest,RecallResponse> {  
11 -  
12 - public CacheRecallRequestResponse(RecallRequest request) {  
13 - super(request);  
14 - }  
15 -  
16 - @Override  
17 - public Transfer<String, RecallResponse> getToResponseTransfer() {  
18 - return toResponseTransfer;  
19 - }  
20 -  
21 - @Override  
22 - public Transfer<RecallResponse, String> getFromResponseTransfer() {  
23 - return fromResponseTransfer;  
24 - }  
25 -  
26 - private static Transfer<String,RecallResponse> toResponseTransfer = new Transfer<String, RecallResponse>() {  
27 - @Override  
28 - public RecallResponse transfer(String jsonValue) {  
29 - return JSON.parseObject(jsonValue, RecallResponse.class);  
30 - }  
31 - };  
32 -  
33 - private static Transfer<RecallResponse,String> fromResponseTransfer = new Transfer<RecallResponse, String>() {  
34 - @Override  
35 - public String transfer(RecallResponse recallResponse) {  
36 - return JSON.toJSONString(recallResponse);  
37 - }  
38 - };  
39 -} 1 +package com.yoho.search.recall.scene.cache;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
  5 +import com.yoho.search.base.utils.Transfer;
  6 +import com.yoho.search.recall.scene.cache.CacheRequestResponse;
  7 +import com.yoho.search.recall.scene.models.RecallRequest;
  8 +import com.yoho.search.recall.scene.models.RecallResponse;
  9 +
  10 +public class CacheRecallRequestResponse extends CacheRequestResponse<RecallRequest,RecallResponse> {
  11 +
  12 + public CacheRecallRequestResponse(RecallRequest request) {
  13 + super(request);
  14 + }
  15 +
  16 + @Override
  17 + public Transfer<String, RecallResponse> getToResponseTransfer() {
  18 + return toResponseTransfer;
  19 + }
  20 +
  21 + @Override
  22 + public Transfer<RecallResponse, String> getFromResponseTransfer() {
  23 + return fromResponseTransfer;
  24 + }
  25 +
  26 + private static Transfer<String,RecallResponse> toResponseTransfer = new Transfer<String, RecallResponse>() {
  27 + @Override
  28 + public RecallResponse transfer(String jsonValue) {
  29 + return JSON.parseObject(jsonValue, RecallResponse.class);
  30 + }
  31 + };
  32 +
  33 + private static Transfer<RecallResponse,String> fromResponseTransfer = new Transfer<RecallResponse, String>() {
  34 + @Override
  35 + public String transfer(RecallResponse recallResponse) {
  36 + return JSON.toJSONString(recallResponse);
  37 + }
  38 + };
  39 +}
1 -package com.yoho.search.recall.scene.cache;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.yoho.search.base.utils.Transfer;  
5 -import com.yoho.search.recall.scene.cache.CacheRequestResponse;  
6 -import com.yoho.search.recall.scene.models.RecallSknParams;  
7 -import com.yoho.search.recall.scene.models.RecallSknResult;  
8 -  
9 -public class CacheRecallSknRequestResponse extends CacheRequestResponse<RecallSknParams,RecallSknResult> {  
10 -  
11 - public CacheRecallSknRequestResponse(RecallSknParams request) {  
12 - super(request);  
13 - }  
14 -  
15 - private static Transfer<String,RecallSknResult> toResponseTransfer = new Transfer<String, RecallSknResult>() {  
16 - @Override  
17 - public RecallSknResult transfer(String jsonValue) {  
18 - return JSON.parseObject(jsonValue, RecallSknResult.class);  
19 - }  
20 - };  
21 -  
22 - private static Transfer<RecallSknResult,String> fromResponseTransfer = new Transfer<RecallSknResult, String>() {  
23 - @Override  
24 - public String transfer(RecallSknResult recallSknResult) {  
25 - return JSON.toJSONString(recallSknResult);  
26 - }  
27 - };  
28 -  
29 - @Override  
30 - public Transfer<String, RecallSknResult> getToResponseTransfer() {  
31 - return toResponseTransfer;  
32 - }  
33 -  
34 - @Override  
35 - public Transfer<RecallSknResult, String> getFromResponseTransfer() {  
36 - return fromResponseTransfer;  
37 - }  
38 -} 1 +package com.yoho.search.recall.scene.cache;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.yoho.search.base.utils.Transfer;
  5 +import com.yoho.search.recall.scene.cache.CacheRequestResponse;
  6 +import com.yoho.search.recall.scene.models.RecallSknParams;
  7 +import com.yoho.search.recall.scene.models.RecallSknResult;
  8 +
  9 +public class CacheRecallSknRequestResponse extends CacheRequestResponse<RecallSknParams,RecallSknResult> {
  10 +
  11 + public CacheRecallSknRequestResponse(RecallSknParams request) {
  12 + super(request);
  13 + }
  14 +
  15 + private static Transfer<String,RecallSknResult> toResponseTransfer = new Transfer<String, RecallSknResult>() {
  16 + @Override
  17 + public RecallSknResult transfer(String jsonValue) {
  18 + return JSON.parseObject(jsonValue, RecallSknResult.class);
  19 + }
  20 + };
  21 +
  22 + private static Transfer<RecallSknResult,String> fromResponseTransfer = new Transfer<RecallSknResult, String>() {
  23 + @Override
  24 + public String transfer(RecallSknResult recallSknResult) {
  25 + return JSON.toJSONString(recallSknResult);
  26 + }
  27 + };
  28 +
  29 + @Override
  30 + public Transfer<String, RecallSknResult> getToResponseTransfer() {
  31 + return toResponseTransfer;
  32 + }
  33 +
  34 + @Override
  35 + public Transfer<RecallSknResult, String> getFromResponseTransfer() {
  36 + return fromResponseTransfer;
  37 + }
  38 +}
1 -package com.yoho.search.recall.scene.cache;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.alibaba.fastjson.JSONObject;  
5 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
6 -import com.yoho.search.base.utils.Transfer;  
7 -import com.yoho.search.recall.scene.cache.CacheRequestResponse;  
8 -import com.yoho.search.recall.scene.models.SknInfoRequest;  
9 -  
10 -import java.util.HashMap;  
11 -import java.util.Map;  
12 -  
13 -public class CacheSknInfoRequestResponse extends CacheRequestResponse<SknInfoRequest, Map<String, Object>> {  
14 -  
15 - public CacheSknInfoRequestResponse(SknInfoRequest sknInfoRequest) {  
16 - super(sknInfoRequest);  
17 - }  
18 -  
19 - static Transfer<String, Map<String, Object>> toResponseTransfer = new Transfer<String, Map<String, Object>>() {  
20 - @Override  
21 - public Map<String, Object> transfer(String value) {  
22 - Map<String, Object> product = new HashMap<>();  
23 - product.putAll(JSONObject.parseObject(value));  
24 - return product;  
25 - }  
26 - };  
27 -  
28 - static Transfer<Map<String, Object>, String> fromResponseTransfer = new Transfer<Map<String, Object>, String>() {  
29 - @Override  
30 - public String transfer(Map<String, Object> product) {  
31 - return JSON.toJSONString(product);  
32 - }  
33 - };  
34 -  
35 - @Override  
36 - public Transfer<String, Map<String, Object>> getToResponseTransfer() {  
37 - return toResponseTransfer;  
38 - }  
39 -  
40 - @Override  
41 - public Transfer<Map<String, Object>, String> getFromResponseTransfer() {  
42 - return fromResponseTransfer;  
43 - }  
44 -} 1 +package com.yoho.search.recall.scene.cache;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
  6 +import com.yoho.search.base.utils.Transfer;
  7 +import com.yoho.search.recall.scene.cache.CacheRequestResponse;
  8 +import com.yoho.search.recall.scene.models.SknInfoRequest;
  9 +
  10 +import java.util.HashMap;
  11 +import java.util.Map;
  12 +
  13 +public class CacheSknInfoRequestResponse extends CacheRequestResponse<SknInfoRequest, Map<String, Object>> {
  14 +
  15 + public CacheSknInfoRequestResponse(SknInfoRequest sknInfoRequest) {
  16 + super(sknInfoRequest);
  17 + }
  18 +
  19 + static Transfer<String, Map<String, Object>> toResponseTransfer = new Transfer<String, Map<String, Object>>() {
  20 + @Override
  21 + public Map<String, Object> transfer(String value) {
  22 + Map<String, Object> product = new HashMap<>();
  23 + product.putAll(JSONObject.parseObject(value));
  24 + return product;
  25 + }
  26 + };
  27 +
  28 + static Transfer<Map<String, Object>, String> fromResponseTransfer = new Transfer<Map<String, Object>, String>() {
  29 + @Override
  30 + public String transfer(Map<String, Object> product) {
  31 + return JSON.toJSONString(product);
  32 + }
  33 + };
  34 +
  35 + @Override
  36 + public Transfer<String, Map<String, Object>> getToResponseTransfer() {
  37 + return toResponseTransfer;
  38 + }
  39 +
  40 + @Override
  41 + public Transfer<Map<String, Object>, String> getFromResponseTransfer() {
  42 + return fromResponseTransfer;
  43 + }
  44 +}
1 -package com.yoho.search.recall.scene.cache;  
2 -  
3 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
4 -  
5 -public interface ICacheRequest {  
6 - /**  
7 - * 缓存key  
8 - * @return  
9 - */  
10 - RedisKeyBuilder redisKeyBuilder();  
11 -  
12 - /**  
13 - * 缓存时间  
14 - * @return  
15 - */  
16 - int cacheTimeInSecond();  
17 -} 1 +package com.yoho.search.recall.scene.cache;
  2 +
  3 +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
  4 +
  5 +public interface ICacheRequest {
  6 + /**
  7 + * 缓存key
  8 + * @return
  9 + */
  10 + RedisKeyBuilder redisKeyBuilder();
  11 +
  12 + /**
  13 + * 缓存时间
  14 + * @return
  15 + */
  16 + int cacheTimeInSecond();
  17 +}
1 -package com.yoho.search.recall.scene.cache;  
2 -  
3 -import com.yoho.search.base.utils.Transfer;  
4 -  
5 -public abstract class ICacheResponse<V> {  
6 -  
7 - public abstract Transfer<String, V> getToResponseTransfer();  
8 -  
9 - public abstract Transfer<V, String> getFromResponseTransfer();  
10 -  
11 -} 1 +package com.yoho.search.recall.scene.cache;
  2 +
  3 +import com.yoho.search.base.utils.Transfer;
  4 +
  5 +public abstract class ICacheResponse<V> {
  6 +
  7 + public abstract Transfer<String, V> getToResponseTransfer();
  8 +
  9 + public abstract Transfer<V, String> getFromResponseTransfer();
  10 +
  11 +}
1 -package com.yoho.search.recall.scene.component;  
2 -  
3 -  
4 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
5 -import com.yoho.search.base.utils.ISearchConstants;  
6 -import com.yoho.search.base.utils.ProductIndexEsField;  
7 -import com.yoho.search.core.es.model.SearchParam;  
8 -import com.yoho.search.core.es.model.SearchResult;  
9 -import com.yoho.search.recall.scene.cache.CacheRequestResponseComponent;  
10 -import com.yoho.search.recall.scene.constants.CacheTimeConstants;  
11 -import com.yoho.search.recall.scene.models.CacheSknInfoRequestResponse;  
12 -import com.yoho.search.recall.scene.models.SknInfoRequest;  
13 -import com.yoho.search.service.base.SearchCommonService;  
14 -import com.yoho.search.service.base.index.ProductIndexBaseService;  
15 -import org.apache.commons.collections.MapUtils;  
16 -import org.elasticsearch.index.query.QueryBuilders;  
17 -import org.slf4j.Logger;  
18 -import org.slf4j.LoggerFactory;  
19 -import org.springframework.beans.factory.annotation.Autowired;  
20 -import org.springframework.stereotype.Component;  
21 -  
22 -import java.util.ArrayList;  
23 -import java.util.HashMap;  
24 -import java.util.List;  
25 -import java.util.Map;  
26 -  
27 -@Component  
28 -public class BacthSknInfoComponent {  
29 -  
30 - @Autowired  
31 - private SearchCommonService searchCommonService;  
32 - @Autowired  
33 - private ProductIndexBaseService productIndexBaseService;  
34 - @Autowired  
35 - private CacheRequestResponseComponent cacheRequestResponseComponent;  
36 -  
37 - private static final boolean useEhCache = true;  
38 -  
39 - /**  
40 - * 按skn查询并按顺序返回  
41 - *  
42 - * @param productSkns  
43 - * @return  
44 - */  
45 - public List<Map<String, Object>> queryProductListBySkn(List<Integer> productSkns,int size){  
46 - //1、批量查询SKN信息  
47 - List<CacheSknInfoRequestResponse> sknInfoCacheRequestRespons = this.batchQuery(productSkns);  
48 - //2、构造返回结果  
49 - List<Map<String, Object>> finalResults = new ArrayList<>();  
50 - for (CacheSknInfoRequestResponse sknInfoCacheRequestResponse : sknInfoCacheRequestRespons) {  
51 - if(sknInfoCacheRequestResponse !=null && sknInfoCacheRequestResponse.getResponse()!=null){  
52 - finalResults.add(sknInfoCacheRequestResponse.getResponse());  
53 - }  
54 - if(finalResults.size()>=size){  
55 - break;  
56 - }  
57 - }  
58 - return finalResults;  
59 - }  
60 -  
61 - private List<CacheSknInfoRequestResponse> batchQuery(List<Integer> productSkns){  
62 - //1、构建请求与返回结果  
63 - final List<CacheSknInfoRequestResponse> sknInfoCacheRequestRespons = new ArrayList<>();  
64 - for (Integer productSkn : productSkns) {  
65 - sknInfoCacheRequestRespons.add(new CacheSknInfoRequestResponse(new SknInfoRequest(productSkn)));  
66 - }  
67 - //2、批量从缓存中获取  
68 - cacheRequestResponseComponent.batchFillResponseFromCache(sknInfoCacheRequestRespons,useEhCache);  
69 - //3、获取未命中缓存的请求  
70 - List<CacheSknInfoRequestResponse> missCacheRequests = cacheRequestResponseComponent.filterMissCacheRequests(sknInfoCacheRequestRespons);  
71 - //4、执行批量查询  
72 - Map<String,Map<String, Object>> queryResults = this.batchQueryMissCacheRequests(missCacheRequests);  
73 - //5、填充查询结果  
74 - cacheRequestResponseComponent.batchFillResponseWithQueryResults(sknInfoCacheRequestRespons,queryResults);  
75 - //6、将CacheRequestResponse中需要缓存的key加入缓存  
76 - cacheRequestResponseComponent.batchAddResponseToCache(sknInfoCacheRequestRespons,useEhCache);  
77 - return sknInfoCacheRequestRespons;  
78 - }  
79 -  
80 - private Map<String,Map<String, Object>> batchQueryMissCacheRequests(List<CacheSknInfoRequestResponse> notCachedRequestResponse) {  
81 - //1、合法性判断  
82 - Map<String,Map<String, Object>> results = new HashMap<>();  
83 - if(notCachedRequestResponse==null||notCachedRequestResponse.isEmpty()){  
84 - return results;  
85 - }  
86 - //2、获取skn  
87 - List<Integer> productSkns = new ArrayList<>();  
88 - for (CacheSknInfoRequestResponse sknInfoCacheRequestResponse : notCachedRequestResponse) {  
89 - productSkns.add(sknInfoCacheRequestResponse.getRequest().getProductSkn());  
90 - }  
91 - //3、构建SearchParam  
92 - SearchParam searchParam = new SearchParam();  
93 - searchParam.setOffset(0);  
94 - searchParam.setSize(productSkns.size());  
95 - searchParam.setFiter(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, productSkns));  
96 - searchParam.setIncludeFields(productIndexBaseService.getProductIndexIncludeFields());  
97 - SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);  
98 - List<Map<String, Object>> productList = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());  
99 - //4、构建SKN临时结果  
100 - Map<Integer,Map<String, Object>> productTempMap = new HashMap<>();  
101 - for (Map<String, Object> product: productList) {  
102 - productTempMap.put(MapUtils.getIntValue(product,"product_skn",0),product);  
103 - }  
104 - //5、构造最终结果  
105 - for (CacheSknInfoRequestResponse requestResponse :notCachedRequestResponse ) {  
106 - results.put(requestResponse.getRequest().redisKeyBuilder().getKey(),productTempMap.get(requestResponse.getRequest().getProductSkn()));  
107 - }  
108 - return results;  
109 - }  
110 -  
111 -  
112 -}  
1 -package com.yoho.search.recall.scene.component;  
2 -  
3 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
4 -import com.yoho.search.base.utils.ISearchConstants;  
5 -import com.yoho.search.base.utils.ProductIndexEsField;  
6 -import com.yoho.search.core.es.model.SearchParam;  
7 -import com.yoho.search.core.es.model.SearchResult;  
8 -import com.yoho.search.recall.scene.cache.CacheRequestResponseComponent;  
9 -import com.yoho.search.recall.scene.models.CacheRecallRequestResponse;  
10 -import com.yoho.search.recall.scene.models.RecallRequest;  
11 -import com.yoho.search.recall.scene.models.RecallResponse;  
12 -import com.yoho.search.service.base.SearchCommonService;  
13 -import org.apache.commons.collections.MapUtils;  
14 -import org.slf4j.Logger;  
15 -import org.slf4j.LoggerFactory;  
16 -import org.springframework.beans.factory.annotation.Autowired;  
17 -import org.springframework.stereotype.Component;  
18 -  
19 -import java.util.ArrayList;  
20 -import java.util.HashMap;  
21 -import java.util.List;  
22 -import java.util.Map;  
23 -  
24 -@Component  
25 -public class BatchRecallComponent {  
26 -  
27 - private static final Logger logger = LoggerFactory.getLogger(BatchRecallComponent.class);  
28 -  
29 - @Autowired  
30 - private CacheRequestResponseComponent cacheRequestResponseHelper;  
31 - @Autowired  
32 - private SearchCommonService searchCommonService;  
33 -  
34 - private static final boolean useEhCache = false;  
35 -  
36 - /**  
37 - * 批量召回入口  
38 - *  
39 - * @param batchRequests  
40 - * @return  
41 - */  
42 - public List<CacheRecallRequestResponse> batchRecallAndCache(final List<RecallRequest> batchRequests) {  
43 - //1、构造返回结果  
44 - final List<CacheRecallRequestResponse> recallRequestResponses = new ArrayList<>();  
45 - for (RecallRequest request : batchRequests) {  
46 - recallRequestResponses.add(new CacheRecallRequestResponse(request));  
47 - }  
48 - //2、先从缓存中填充response  
49 - cacheRequestResponseHelper.batchFillResponseFromCache(recallRequestResponses,useEhCache);  
50 -  
51 - //3、构造未命中缓存的请求-最多透传x个  
52 - final List<CacheRecallRequestResponse> missCacheRequests =cacheRequestResponseHelper.filterMissCacheRequests(recallRequestResponses);  
53 -  
54 - //4、如果remainRequests为空,则说明全部命中了缓存,直接返回即可  
55 - if (missCacheRequests.isEmpty()) {  
56 - return recallRequestResponses;  
57 - }  
58 -  
59 - //5、处理剩余请求  
60 - Map<String,RecallResponse> notCacheResults = this.queryNotCachedResult(missCacheRequests);  
61 -  
62 - //6、填充recallRequestResponses  
63 - cacheRequestResponseHelper.batchFillResponseWithQueryResults(recallRequestResponses,notCacheResults);  
64 -  
65 - //7、将尚未缓存的对象加入缓存  
66 - cacheRequestResponseHelper.batchAddResponseToCache(recallRequestResponses,useEhCache);  
67 -  
68 - return recallRequestResponses;  
69 -  
70 - }  
71 -  
72 - /**  
73 - * 查询命中缓存的请求  
74 - * @param notCachedRequests  
75 - * @return  
76 - */  
77 - private Map<String,RecallResponse> queryNotCachedResult(List<CacheRecallRequestResponse> notCachedRequests) {  
78 - //1、构造请求参数  
79 - List<SearchParam> searchParams = new ArrayList<>();  
80 - for (CacheRecallRequestResponse requestResponse : notCachedRequests) {  
81 - searchParams.add(requestResponse.getRequest().searchParam());  
82 - }  
83 - //2、执行搜索  
84 - List<SearchResult> searchResults = searchCommonService.doMutiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);  
85 - //3、构造返回结果  
86 - Map<String,RecallResponse> notCachedResults = new HashMap<>();  
87 - for (int i = 0; i < notCachedRequests.size(); i++) {  
88 - RecallRequest request = notCachedRequests.get(i).getRequest();  
89 - SearchResult searchResult = searchResults.get(i);  
90 - RecallResponse response = this.buildResonse(searchResult);  
91 - notCachedResults.put(request.redisKeyBuilder().getKey(),response);  
92 - }  
93 - return notCachedResults;  
94 - }  
95 -  
96 - private RecallResponse buildResonse(SearchResult searchResult) {  
97 - List<Map<String, Object>> results = searchResult.getResultList();  
98 - List<RecallResponse.RecallSkn> recallSkns = new ArrayList<>();  
99 - for (Map<String, Object> result : results) {  
100 - Integer productSkn = MapUtils.getInteger(result, ProductIndexEsField.productSkn, 0);  
101 - Integer brandId = MapUtils.getInteger(result, ProductIndexEsField.brandId, 0);  
102 - Integer middleSortId = MapUtils.getInteger(result, ProductIndexEsField.middleSortId, 0);  
103 - recallSkns.add(new RecallResponse.RecallSkn(productSkn, brandId, middleSortId));  
104 - }  
105 - return new RecallResponse(searchResult.getTotal(), recallSkns);  
106 - }  
107 -  
108 -}  
1 -package com.yoho.search.recall.scene.models;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
5 -import com.yoho.search.base.utils.Transfer;  
6 -import com.yoho.search.recall.scene.cache.CacheRequestResponse;  
7 -  
8 -public class CacheRecallRequestResponse extends CacheRequestResponse<RecallRequest,RecallResponse> {  
9 -  
10 - public CacheRecallRequestResponse(RecallRequest request) {  
11 - super(request, toResponseTransfer,fromResponseTransfer);  
12 - }  
13 -  
14 - private static Transfer<String,RecallResponse> toResponseTransfer = new Transfer<String, RecallResponse>() {  
15 - @Override  
16 - public RecallResponse transfer(String jsonValue) {  
17 - return JSON.parseObject(jsonValue, RecallResponse.class);  
18 - }  
19 - };  
20 -  
21 - private static Transfer<RecallResponse,String> fromResponseTransfer = new Transfer<RecallResponse, String>() {  
22 - @Override  
23 - public String transfer(RecallResponse recallResponse) {  
24 - return JSON.toJSONString(recallResponse);  
25 - }  
26 - };  
27 -  
28 -}  
1 -package com.yoho.search.recall.scene.models;  
2 -  
3 -import com.alibaba.fastjson.JSON;  
4 -import com.alibaba.fastjson.JSONObject;  
5 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
6 -import com.yoho.search.base.utils.Transfer;  
7 -import com.yoho.search.recall.scene.cache.CacheRequestResponse;  
8 -  
9 -import java.util.HashMap;  
10 -import java.util.Map;  
11 -  
12 -public class CacheSknInfoRequestResponse extends CacheRequestResponse<SknInfoRequest, Map<String, Object>> {  
13 -  
14 - public CacheSknInfoRequestResponse(SknInfoRequest sknInfoRequest) {  
15 - super(sknInfoRequest, toResponseTransfer, fromResponseTransfer);  
16 - }  
17 -  
18 - static Transfer<String, Map<String, Object>> toResponseTransfer = new Transfer<String, Map<String, Object>>() {  
19 - @Override  
20 - public Map<String, Object> transfer(String value) {  
21 - Map<String, Object> product = new HashMap<>();  
22 - product.putAll(JSONObject.parseObject(value));  
23 - return product;  
24 - }  
25 - };  
26 -  
27 - static Transfer<Map<String, Object>, String> fromResponseTransfer = new Transfer<Map<String, Object>, String>() {  
28 - @Override  
29 - public String transfer(Map<String, Object> product) {  
30 - return JSON.toJSONString(product);  
31 - }  
32 - };  
33 -  
34 -}  
1 -package com.yoho.search.recall.scene.models;  
2 -  
3 -import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;  
4 -  
5 -public interface ICacheRequest {  
6 - /**  
7 - * 缓存key  
8 - * @return  
9 - */  
10 - RedisKeyBuilder redisKeyBuilder();  
11 -  
12 - /**  
13 - * 缓存时间  
14 - * @return  
15 - */  
16 - int cacheTimeInSecond();  
17 -}