| | |
| | | |
| | | int startIndex = orderedOutStationList.indexOf(currentStationId); |
| | | int total = orderedOutStationList.size(); |
| | | List<Integer> reachableStationIdList = new ArrayList<>(); |
| | | List<CircleTargetCandidate> candidateList = new ArrayList<>(); |
| | | for (int offset = 1; offset < total; offset++) { |
| | | int candidateIndex = (startIndex + offset + total) % total; |
| | | Integer candidateStationId = orderedOutStationList.get(candidateIndex); |
| | |
| | | try { |
| | | List<NavigateNode> path = navigateUtils.calcByStationId(currentStationId, candidateStationId); |
| | | if (path != null && !path.isEmpty()) { |
| | | reachableStationIdList.add(candidateStationId); |
| | | candidateList.add(new CircleTargetCandidate(candidateStationId, path.size(), offset)); |
| | | } |
| | | } catch (Exception ignore) {} |
| | | } |
| | | if (reachableStationIdList.isEmpty()) { |
| | | if (candidateList.isEmpty()) { |
| | | return null; |
| | | } |
| | | int gradualIndex = resolveGradualCircleTargetIndex(expectedLoopIssueCount, reachableStationIdList.size()); |
| | | return reachableStationIdList.get(gradualIndex); |
| | | candidateList.sort(new Comparator<CircleTargetCandidate>() { |
| | | @Override |
| | | public int compare(CircleTargetCandidate left, CircleTargetCandidate right) { |
| | | if (left == right) { |
| | | return 0; |
| | | } |
| | | if (left == null) { |
| | | return 1; |
| | | } |
| | | if (right == null) { |
| | | return -1; |
| | | } |
| | | int pathCompare = Integer.compare(left.getPathLength(), right.getPathLength()); |
| | | if (pathCompare != 0) { |
| | | return pathCompare; |
| | | } |
| | | return Integer.compare(left.getOffset(), right.getOffset()); |
| | | } |
| | | }); |
| | | return resolveGradualCircleTargetByPathLength(expectedLoopIssueCount, candidateList); |
| | | } |
| | | |
| | | private int resolveGradualCircleTargetIndex(Integer expectedLoopIssueCount, int candidateCount) { |
| | | if (candidateCount <= 1) { |
| | | return 0; |
| | | private Integer resolveGradualCircleTargetByPathLength(Integer expectedLoopIssueCount, |
| | | List<CircleTargetCandidate> candidateList) { |
| | | if (candidateList == null || candidateList.isEmpty()) { |
| | | return null; |
| | | } |
| | | if (expectedLoopIssueCount == null || expectedLoopIssueCount <= 2) { |
| | | return 0; |
| | | return candidateList.get(0).getStationId(); |
| | | } |
| | | int gradualIndex = expectedLoopIssueCount - 2; |
| | | if (gradualIndex < 1) { |
| | | gradualIndex = 1; |
| | | |
| | | List<CircleTargetCandidate> tierList = new ArrayList<>(); |
| | | Integer lastPathLength = null; |
| | | for (CircleTargetCandidate candidate : candidateList) { |
| | | if (candidate == null) { |
| | | continue; |
| | | } |
| | | return Math.min(gradualIndex, candidateCount - 1); |
| | | if (lastPathLength == null || !Objects.equals(lastPathLength, candidate.getPathLength())) { |
| | | tierList.add(candidate); |
| | | lastPathLength = candidate.getPathLength(); |
| | | } |
| | | } |
| | | if (tierList.isEmpty()) { |
| | | return candidateList.get(0).getStationId(); |
| | | } |
| | | int tierIndex = Math.min(expectedLoopIssueCount - 2, tierList.size() - 1); |
| | | return tierList.get(tierIndex).getStationId(); |
| | | } |
| | | |
| | | private boolean tryAcquireOutOrderDispatchLock(Integer wrkNo, Integer stationId) { |
| | |
| | | } |
| | | } |
| | | |
| | | private static class CircleTargetCandidate { |
| | | private final Integer stationId; |
| | | private final Integer pathLength; |
| | | private final Integer offset; |
| | | |
| | | private CircleTargetCandidate(Integer stationId, Integer pathLength, Integer offset) { |
| | | this.stationId = stationId; |
| | | this.pathLength = pathLength == null ? 0 : pathLength; |
| | | this.offset = offset == null ? 0 : offset; |
| | | } |
| | | |
| | | private Integer getStationId() { |
| | | return stationId; |
| | | } |
| | | |
| | | private Integer getPathLength() { |
| | | return pathLength; |
| | | } |
| | | |
| | | private Integer getOffset() { |
| | | return offset; |
| | | } |
| | | } |
| | | |
| | | private void saveLoopLoadReserve(Integer wrkNo, LoopHitResult loopHitResult) { |
| | | if (wrkNo == null || wrkNo <= 0 || loopHitResult == null || !loopHitResult.isThroughLoop()) { |
| | | return; |