EvolutionDurations.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-8.0.0).
003  * Copyright (c) 2007-2024 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.engine;
021 
022 import static java.util.Objects.requireNonNull;
023 import static io.jenetics.internal.util.SerialIO.readInt;
024 import static io.jenetics.internal.util.SerialIO.readLong;
025 import static io.jenetics.internal.util.SerialIO.writeInt;
026 import static io.jenetics.internal.util.SerialIO.writeLong;
027 
028 import java.io.DataInput;
029 import java.io.DataOutput;
030 import java.io.IOException;
031 import java.io.ObjectInput;
032 import java.io.ObjectOutput;
033 import java.io.Serial;
034 import java.io.Serializable;
035 import java.time.Duration;
036 
037 /**
038  * This class contains timing information about one evolution step.
039  *
040  @param offspringSelectionDuration the duration needed for selecting the
041  *        offspring population
042  @param survivorsSelectionDuration the duration needed for selecting the
043  *        survivor population
044  @param offspringAlterDuration the duration needed for altering the
045  *        offspring population
046  @param offspringFilterDuration the duration needed for removing and
047  *        replacing invalid offspring individuals
048  @param survivorFilterDuration the duration needed for removing and
049  *        replacing old and invalid survivor individuals
050  @param evaluationDuration the duration needed for evaluating the fitness
051  *        function of the new individuals
052  @param evolveDuration the duration needed for the whole evolve step
053  *
054  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
055  @since 3.0
056  @version 7.0
057  */
058 public record EvolutionDurations(
059     Duration offspringSelectionDuration,
060     Duration survivorsSelectionDuration,
061     Duration offspringAlterDuration,
062     Duration offspringFilterDuration,
063     Duration survivorFilterDuration,
064     Duration evaluationDuration,
065     Duration evolveDuration
066 )
067     implements
068         Comparable<EvolutionDurations>,
069         Serializable
070 {
071     @Serial
072     private static final long serialVersionUID = 3L;
073 
074     /**
075      * Constant for zero evolution durations.
076      */
077     public static final EvolutionDurations ZERO = new EvolutionDurations(
078         Duration.ZERO,
079         Duration.ZERO,
080         Duration.ZERO,
081         Duration.ZERO,
082         Duration.ZERO,
083         Duration.ZERO,
084         Duration.ZERO
085     );
086 
087     /**
088      * Returns a copy of this duration with the specified duration added.
089      <p>
090      * This instance is immutable and unaffected by this method call.
091      *
092      @param other the duration to add
093      @return a {@code EvolutionDurations} based on this duration with the
094      *         specified duration added
095      @throws NullPointerException if the {@code other} duration is {@code null}
096      @throws ArithmeticException if numeric overflow occurs
097      */
098     public EvolutionDurations plus(final EvolutionDurations other) {
099         requireNonNull(other);
100         return new EvolutionDurations(
101             offspringSelectionDuration.plus(other.offspringSelectionDuration),
102             survivorsSelectionDuration.plus(other.survivorsSelectionDuration),
103             offspringAlterDuration.plus(other.offspringAlterDuration),
104             offspringFilterDuration.plus(other.offspringFilterDuration),
105             survivorFilterDuration.plus(other.survivorFilterDuration),
106             evaluationDuration.plus(other.evaluationDuration),
107             evolveDuration.plus(other.evolveDuration)
108         );
109     }
110 
111     EvolutionDurations plusEvaluation(final Duration duration) {
112         return new EvolutionDurations(
113             offspringSelectionDuration,
114             survivorsSelectionDuration,
115             offspringAlterDuration,
116             offspringFilterDuration,
117             survivorFilterDuration,
118             evaluationDuration.plus(duration),
119             evolveDuration
120         );
121     }
122 
123     EvolutionDurations plusEvolve(final Duration duration) {
124         return new EvolutionDurations(
125             offspringSelectionDuration,
126             survivorsSelectionDuration,
127             offspringAlterDuration,
128             offspringFilterDuration,
129             survivorFilterDuration,
130             evaluationDuration,
131             evolveDuration.plus(duration)
132         );
133     }
134 
135     /**
136      * Compares two durations objects. Only the {@link #evolveDuration()}
137      * property is taken into account for the comparison.
138      *
139      @param other the other durations object this object is compared with
140      @return an integer smaller/equal/greater than zero if the
141      *         {@link #evolveDuration()} property of {@code this} object is
142      *         smaller/equal/greater than the corresponding property of the
143      *         {@code other} project.
144      */
145     @Override
146     public int compareTo(final EvolutionDurations other) {
147         return evolveDuration.compareTo(other.evolveDuration);
148     }
149 
150     /* *************************************************************************
151      *  Java object serialization
152      * ************************************************************************/
153 
154     void write(final ObjectOutput outthrows IOException {
155         writeDuration(offspringSelectionDuration, out);
156         writeDuration(survivorsSelectionDuration, out);
157         writeDuration(offspringAlterDuration, out);
158         writeDuration(offspringFilterDuration, out);
159         writeDuration(survivorFilterDuration, out);
160         writeDuration(evaluationDuration, out);
161         writeDuration(evolveDuration, out);
162     }
163 
164     private static void writeDuration(final Duration duration, final DataOutput out)
165         throws IOException
166     {
167         writeLong(duration.getSeconds(), out);
168         writeInt(duration.getNano(), out);
169     }
170 
171     static EvolutionDurations read(final ObjectInput inthrows IOException {
172         return new EvolutionDurations(
173             readDuration(in),
174             readDuration(in),
175             readDuration(in),
176             readDuration(in),
177             readDuration(in),
178             readDuration(in),
179             readDuration(in)
180         );
181     }
182 
183     private static Duration readDuration(final DataInput inthrows IOException {
184         final long seconds = readLong(in);
185         final int nanos = readInt(in);
186         return Duration.ofSeconds(seconds, nanos);
187     }
188 
189 }