shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.walker.etaa.extractor;
 
import com.walker.etaa.AbstractQuestionExtractor;
import com.walker.etaa.ExtractFailedException;
import com.walker.etaa.ExtractNotEnoughException;
import com.walker.etaa.ExtractStrategy;
import com.walker.etaa.QuestionExtractOptions;
import com.walker.etaa.QuestionType;
import com.walker.etaa.util.AlgorithmUtils;
import com.walker.infrastructure.utils.StringUtils;
 
import java.util.List;
 
/**
 * 基于平均分布的抽取规则实现。
 * @author 时克英
 * @date 2023-03-07
 */
public abstract class SimpleQuestionExtractor<T> extends AbstractQuestionExtractor<T> {
 
    @Override
    protected List<T> acquireGlobalList(QuestionExtractOptions option) throws ExtractFailedException {
        long existGlobalCount = this.acquireGlobalTotal(option.getOwnerId(), option.getDeptId(), option.getRootCatalog());
        if(existGlobalCount <= 0){
            throw new IllegalArgumentException("业务系统未找到任何'全局条件'试题数量:0");
        }
        if(existGlobalCount < option.getExtractTotal()){
            throw new ExtractNotEnoughException("抽取数量不足", null, existGlobalCount);
        }
 
//        int[] indexList = AlgorithmUtils.getAverageIndexArray((int)existGlobalCount, (int)option.getExtractTotal());
        int[] indexList = this.getIndexList(option.getExtractStrategy(), (int)existGlobalCount, (int)option.getExtractTotal());
        List<Integer> hashCodeList = null;
        if(StringUtils.isEmpty(option.getRootCatalog())){
            logger.debug("......only ownerId");
            hashCodeList = AlgorithmUtils.getHashCode(option.getOwnerId(), indexList);
            return this.loadGlobalList(hashCodeList, null);
        } else {
            logger.debug("......root catalog");
            hashCodeList = AlgorithmUtils.getHashCode(option.getOwnerId() + option.getRootCatalog(), indexList);
            return this.loadGlobalList(null, hashCodeList);
        }
    }
 
    protected int[] getIndexList(ExtractStrategy extractStrategy, int existDataCount, int requiredTotal){
        int[] indexList = null;
        if(extractStrategy == ExtractStrategy.Average){
            indexList = AlgorithmUtils.getAverageIndexArray(existDataCount, requiredTotal);
        } else if(extractStrategy == ExtractStrategy.Random){
            indexList = AlgorithmUtils.getRandomIndexArray(existDataCount, requiredTotal);
        } else {
            throw new UnsupportedOperationException("不支持的抽取策略:" + extractStrategy);
        }
        return indexList;
    }
 
    /**
     * 获取全局配置条件下,返回的可用试题总数量。
     * @param ownerId 归属id,如:顶级机构ID
     * @param deptId 暂未使用
     * @param rootCatalog 题库根分类ID
     * @return
     */
    protected abstract long acquireGlobalTotal(String ownerId, String deptId, String rootCatalog);
 
    /**
     * 加载试题集合。
     * @param ownerHashCodeList 给定的只有归属索引集合
     * @param rootCatalogHashCodeList 给定的归属、根分类索引集合
     * @return
     * @date 2023-03-08
     */
    protected abstract List<T> loadGlobalList(List<Integer> ownerHashCodeList, List<Integer> rootCatalogHashCodeList);
 
    @Override
    protected List<T> acquireOptionItemList(QuestionExtractOptions option
            , QuestionExtractOptions.ExtractOptionItem item) throws ExtractFailedException {
        long existOptionCount = this.acquireOptionItemTotal(option.getOwnerId()
                , option.getRootCatalog(), item.getMajorCatalog(), item.getQuestionType());
        if(existOptionCount <= 0){
            throw new IllegalArgumentException("业务系统未找到任何'抽取规则明细'试题数量:0, item=" + item);
        }
        if(existOptionCount < item.getCount()){
            throw new ExtractNotEnoughException("抽取数量不足," + item.toString(), null, existOptionCount);
        }
//        int[] indexList = AlgorithmUtils.getAverageIndexArray((int)existOptionCount, (int)item.getCount());
        int[] indexList = this.getIndexList(option.getExtractStrategy(), (int)existOptionCount, (int)item.getCount());
        List<Integer> hashCodeList = null;
 
        StringBuilder prefix = new StringBuilder(option.getOwnerId());
        prefix.append(option.getRootCatalog());
 
        if(item.getQuestionType() == null){
            logger.debug("......only catalog");
            prefix.append(item.getMajorCatalog());
            hashCodeList = AlgorithmUtils.getHashCode(prefix.toString(), indexList);
            return this.loadOptionList(hashCodeList, null);
 
        } else {
            logger.debug("......type");
            prefix.append(item.getMajorCatalog()).append(item.getQuestionType().getIndex());
            hashCodeList = AlgorithmUtils.getHashCode(prefix.toString(), indexList);
            return this.loadOptionList(null, hashCodeList);
        }
    }
 
    protected abstract long acquireOptionItemTotal(String owner
            , String rootCatalog, String catalog, QuestionType questionType);
 
    /**
     * 从业务数据中加载获取试题集合。
     * @param catalogHashCodeList 二级分类HashCode集合
     * @param typeHashCodeList 试题类型HashCode集合
     * @return
     */
    protected abstract List<T> loadOptionList(List<Integer> catalogHashCodeList, List<Integer> typeHashCodeList);
}