public AbstractCachingMoveSelector(MoveSelector childMoveSelector, SelectionCacheType cacheType) {
   this.childMoveSelector = childMoveSelector;
   this.cacheType = cacheType;
   if (childMoveSelector.isNeverEnding()) {
     throw new IllegalStateException(
         "The selector ("
             + this
             + ") has a childMoveSelector ("
             + childMoveSelector
             + ") with neverEnding ("
             + childMoveSelector.isNeverEnding()
             + ").");
   }
   phaseLifecycleSupport.addEventListener(childMoveSelector);
   if (cacheType.isNotCached()) {
     throw new IllegalArgumentException(
         "The selector (" + this + ") does not support the cacheType (" + cacheType + ").");
   }
   phaseLifecycleSupport.addEventListener(new SelectionCacheLifecycleBridge(cacheType, this));
 }
 protected boolean determineBaseRandomSelection(
     PlanningVariableDescriptor variableDescriptor,
     SelectionCacheType resolvedCacheType,
     SelectionOrder resolvedSelectionOrder) {
   switch (resolvedSelectionOrder) {
     case ORIGINAL:
       return false;
     case SORTED:
     case SHUFFLED:
     case PROBABILISTIC:
       // baseValueSelector and lower should be ORIGINAL if they are going to get cached completely
       return false;
     case RANDOM:
       // Predict if caching will occur
       return resolvedCacheType.isNotCached()
           || (isBaseInherentlyCached(variableDescriptor) && !hasFiltering());
     default:
       throw new IllegalStateException(
           "The selectionOrder (" + resolvedSelectionOrder + ") is not implemented.");
   }
 }
 public ProbabilityValueSelector(
     EntityIndependentValueSelector childValueSelector,
     SelectionCacheType cacheType,
     SelectionProbabilityWeightFactory probabilityWeightFactory) {
   this.childValueSelector = childValueSelector;
   this.cacheType = cacheType;
   this.probabilityWeightFactory = probabilityWeightFactory;
   if (childValueSelector.isNeverEnding()) {
     throw new IllegalStateException(
         "The selector ("
             + this
             + ") has a childValueSelector ("
             + childValueSelector
             + ") with neverEnding ("
             + childValueSelector.isNeverEnding()
             + ").");
   }
   phaseLifecycleSupport.addEventListener(childValueSelector);
   if (cacheType.isNotCached()) {
     throw new IllegalArgumentException(
         "The selector (" + this + ") does not support the cacheType (" + cacheType + ").");
   }
   phaseLifecycleSupport.addEventListener(new SelectionCacheLifecycleBridge(cacheType, this));
 }
  public void runCacheType(SelectionCacheType cacheType, int timesCalled) {
    MoveSelector childMoveSelector =
        SelectorTestUtils.mockMoveSelector(
            DummyMove.class,
            new DummyMove("e1"),
            new DummyMove("e2"),
            new DummyMove("e3"),
            new DummyMove("e4"));

    SelectionFilter<DummyMove> filter =
        new SelectionFilter<DummyMove>() {
          public boolean accept(ScoreDirector scoreDirector, DummyMove move) {
            return !move.getCode().equals("e3");
          }
        };
    List<SelectionFilter> filterList = Arrays.<SelectionFilter>asList(filter);
    MoveSelector moveSelector = new FilteringMoveSelector(childMoveSelector, filterList);
    if (cacheType.isCached()) {
      moveSelector = new CachingMoveSelector(moveSelector, cacheType, false);
    }

    DefaultSolverScope solverScope = mock(DefaultSolverScope.class);
    moveSelector.solvingStarted(solverScope);

    AbstractSolverPhaseScope phaseScopeA = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeA.getSolverScope()).thenReturn(solverScope);
    moveSelector.phaseStarted(phaseScopeA);

    AbstractStepScope stepScopeA1 = mock(AbstractStepScope.class);
    when(stepScopeA1.getPhaseScope()).thenReturn(phaseScopeA);
    moveSelector.stepStarted(stepScopeA1);
    assertAllCodesOfMoveSelector(
        moveSelector, (cacheType.isNotCached() ? 4L : 3L), "e1", "e2", "e4");
    moveSelector.stepEnded(stepScopeA1);

    AbstractStepScope stepScopeA2 = mock(AbstractStepScope.class);
    when(stepScopeA2.getPhaseScope()).thenReturn(phaseScopeA);
    moveSelector.stepStarted(stepScopeA2);
    assertAllCodesOfMoveSelector(
        moveSelector, (cacheType.isNotCached() ? 4L : 3L), "e1", "e2", "e4");
    moveSelector.stepEnded(stepScopeA2);

    moveSelector.phaseEnded(phaseScopeA);

    AbstractSolverPhaseScope phaseScopeB = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeB.getSolverScope()).thenReturn(solverScope);
    moveSelector.phaseStarted(phaseScopeB);

    AbstractStepScope stepScopeB1 = mock(AbstractStepScope.class);
    when(stepScopeB1.getPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB1);
    assertAllCodesOfMoveSelector(
        moveSelector, (cacheType.isNotCached() ? 4L : 3L), "e1", "e2", "e4");
    moveSelector.stepEnded(stepScopeB1);

    AbstractStepScope stepScopeB2 = mock(AbstractStepScope.class);
    when(stepScopeB2.getPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB2);
    assertAllCodesOfMoveSelector(
        moveSelector, (cacheType.isNotCached() ? 4L : 3L), "e1", "e2", "e4");
    moveSelector.stepEnded(stepScopeB2);

    AbstractStepScope stepScopeB3 = mock(AbstractStepScope.class);
    when(stepScopeB3.getPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB3);
    assertAllCodesOfMoveSelector(
        moveSelector, (cacheType.isNotCached() ? 4L : 3L), "e1", "e2", "e4");
    moveSelector.stepEnded(stepScopeB3);

    moveSelector.phaseEnded(phaseScopeB);

    moveSelector.solvingEnded(solverScope);

    verifySolverPhaseLifecycle(childMoveSelector, 1, 2, 5);
    verify(childMoveSelector, times(timesCalled)).iterator();
    verify(childMoveSelector, times(timesCalled)).getSize();
  }