/* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.optaplanner.core.impl.score.director; import java.util.List; import org.optaplanner.core.api.domain.solution.PlanningSolution; import org.optaplanner.core.api.score.Score; import org.optaplanner.core.api.score.constraint.ConstraintMatch; import org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor; import org.optaplanner.core.impl.domain.variable.listener.VariableListener; import org.optaplanner.core.impl.domain.variable.supply.SupplyManager; import org.optaplanner.core.impl.score.definition.ScoreDefinition; import org.optaplanner.core.impl.solver.ChildThreadType; /** * @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation */ public interface InnerScoreDirector<Solution_> extends ScoreDirector<Solution_> { /** * @param constraintMatchEnabledPreference false if a {@link ScoreDirector} implementation * should not do {@link ConstraintMatch} tracking even if it supports it. */ void overwriteConstraintMatchEnabledPreference(boolean constraintMatchEnabledPreference); /** * @return used to check {@link #isWorkingEntityListDirty(long)} later on */ long getWorkingEntityListRevision(); /** * @param expectedWorkingEntityListRevision an * @return true if the entityList might have a different set of instances now */ boolean isWorkingEntityListDirty(long expectedWorkingEntityListRevision); /** * @return never null */ InnerScoreDirectorFactory<Solution_> getScoreDirectorFactory(); /** * @return never null */ SolutionDescriptor<Solution_> getSolutionDescriptor(); /** * @return never null */ ScoreDefinition getScoreDefinition(); /** * Returns a planning clone of the solution, * which is not a shallow clone nor a deep clone nor a partition clone. * @return never null, planning clone */ Solution_ cloneWorkingSolution(); /** * Returns a planning clone of the solution, * which is not a shallow clone nor a deep clone nor a partition clone. * @param originalSolution never null * @return never null, planning clone */ Solution_ cloneSolution(Solution_ originalSolution); /** * @return {@code >= 0} */ int getWorkingEntityCount(); /** * @return never null: an empty list if there are none */ List<Object> getWorkingEntityList(); /** * @return {@code >= 0} */ int getWorkingValueCount(); /** * @return at least 0L */ long getCalculationCount(); void resetCalculationCount(); /** * @return never null */ SupplyManager getSupplyManager(); /** * Clones this {@link ScoreDirector} and its {@link PlanningSolution working solution}. * Use {@link #getWorkingSolution()} to retrieve the {@link PlanningSolution working solution} of that clone. * <p> * This is heavy method, because it usually breaks incremental score calculation. Use it sparingly. * Therefore it's best to clone lazily by delaying the clone call as long as possible. * @return never null */ ScoreDirector<Solution_> clone(); InnerScoreDirector<Solution_> createChildThreadScoreDirector(ChildThreadType childThreadType); /** * Do not waste performance by propagating changes to step (or higher) mechanisms. * @param allChangesWillBeUndoneBeforeStepEnds true if all changes will be undone */ void setAllChangesWillBeUndoneBeforeStepEnds(boolean allChangesWillBeUndoneBeforeStepEnds); /** * Asserts that if the {@link Score} is calculated for the current {@link PlanningSolution working solution} * in the current {@link ScoreDirector} (with possibly incremental calculation residue), * it is equal to the parameter {@link Score expectedWorkingScore}. * <p> * Used to assert that skipping {@link #calculateScore()} (when the score is otherwise determined) is correct. * @param expectedWorkingScore never null * @param completedAction sometimes null, when assertion fails then the completedAction's {@link Object#toString()} * is included in the exception message */ void assertExpectedWorkingScore(Score expectedWorkingScore, Object completedAction); /** * Asserts that if all {@link VariableListener}s are forcibly triggered, * and therefore all shadow variables are updated if needed, * that none of the shadow variables of the {@link PlanningSolution working solution} change, * Then also asserts that the {@link Score} calculated for the {@link PlanningSolution working solution} afterwards * is equal to the parameter {@link Score expectedWorkingScore}. * <p> * Used to assert that the shadow variables' state is consistent with the genuine variables' state. * @param expectedWorkingScore never null * @param completedAction sometimes null, when assertion fails then the completedAction's {@link Object#toString()} * is included in the exception message */ void assertShadowVariablesAreNotStale(Score expectedWorkingScore, Object completedAction); /** * Asserts that if the {@link Score} is calculated for the current {@link PlanningSolution working solution} * in a fresh {@link ScoreDirector} (with no incremental calculation residue), * it is equal to the parameter {@link Score workingScore}. * <p> * Furthermore, if the assert fails, a score corruption analysis might be included in the exception message. * @param workingScore never null * @param completedAction sometimes null, when assertion fails then the completedAction's {@link Object#toString()} * is included in the exception message * @see InnerScoreDirectorFactory#assertScoreFromScratch */ void assertWorkingScoreFromScratch(Score workingScore, Object completedAction); }