optaplanner-core/src/main/java/org/optaplanner/core/impl/heuristic/selector/value/chained/DefaultSubChainSelector.java
@Override
    public void constructCache(DefaultSolverScope solverScope) {
        InnerScoreDirector scoreDirector = solverScope.getScoreDirector();
        GenuineVariableDescriptor variableDescriptor = valueSelector.getVariableDescriptor();
        long valueSize = valueSelector.getSize();
        // Fail-fast when anchorTrailingChainList.size() could ever be too big
        if (valueSize > (long) Integer.MAX_VALUE) {
            throw new IllegalStateException("The selector (" + this
                    + ") has a valueSelector (" + valueSelector
                    + ") with valueSize (" + valueSize
                    + ") which is higher than Integer.MAX_VALUE.");
        }
        List<Object> anchorList = new ArrayList<>();
        for (Object value : valueSelector) {
            if (variableDescriptor.isValuePotentialAnchor(value)) {
                anchorList.add(value);
            }
        }
        int anchorListSize = Math.max(anchorList.size(), 1);
        anchorTrailingChainList = new ArrayList<>(anchorListSize);
        int anchorChainInitialCapacity = ((int) valueSize / anchorListSize) + 1;
        for (Object anchor : anchorList) {
            List<Object> anchorChain = new ArrayList<>(anchorChainInitialCapacity);
            Object trailingEntity = inverseVariableSupply.getInverseSingleton(anchor);
            while (trailingEntity != null) {
                anchorChain.add(trailingEntity);
                trailingEntity = inverseVariableSupply.getInverseSingleton(trailingEntity);
            }
            if (anchorChain.size() >= minimumSubChainSize) {
                anchorTrailingChainList.add(new SubChain(anchorChain));
            }
        }
    }
@Override
    public void constructCache(DefaultSolverScope solverScope) {
        InnerScoreDirector scoreDirector = solverScope.getScoreDirector();
        GenuineVariableDescriptor variableDescriptor = valueSelector.getVariableDescriptor();
        long valueSize = valueSelector.getSize();
        // Fail-fast when anchorTrailingChainList.size() could ever be too big
        if (valueSize > (long) Integer.MAX_VALUE) {
            throw new IllegalStateException("The selector (" + this
                    + ") has a valueSelector (" + valueSelector
                    + ") with valueSize (" + valueSize
                    + ") which is higher than Integer.MAX_VALUE.");
        }
        List<Object> anchorList = new ArrayList<>();
        for (Object value : valueSelector) {
            if (variableDescriptor.isValuePotentialAnchor(value)) {
                anchorList.add(value);
            }
        }
        int anchorListSize = Math.max(anchorList.size(), 1);
        anchorTrailingChainList = new ArrayList<>(anchorListSize);
        int anchorChainInitialCapacity = ((int) valueSize / anchorListSize) + 1;
        for (Object anchor : anchorList) {
            List<Object> anchorChain = new ArrayList<>(anchorChainInitialCapacity);
            Object trailingEntity = inverseVariableSupply.getInverseSingleton(anchor);
            while (trailingEntity != null) {
                anchorChain.add(trailingEntity);
                trailingEntity = inverseVariableSupply.getInverseSingleton(trailingEntity);
            }
            if (anchorChain.size() >= minimumSubChainSize) {
                anchorTrailingChainList.add(new SubChain(anchorChain));
            }
        }
    }
************************************************************************