001    /*
002     * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package de.kumpe.hadooptimizer.impl;
017    
018    import java.io.PrintWriter;
019    import java.util.Collection;
020    
021    import de.kumpe.hadooptimizer.EvaluationResult;
022    import de.kumpe.hadooptimizer.impl.ReportingHalterWrapper.Reporter;
023    
024    /**
025     * A {@link Reporter} implementation which writes the evaluation-results to a
026     * simple text-file of the following format:
027     * <p>
028     * A comment in the first line describing the file's format and one line per
029     * {@link EvaluationResult} in with the following colums:
030     * <ol>
031     * <li>the cycle number
032     * <li>the result number
033     * <li>the evaluation
034     * <li>the individual formatted by
035     * {@link LoggingReporter#formatIndividual(StringBuilder, Object)}
036     * </ol>
037     * <p>
038     * With an <code>double[]</code> individual the result may look like this:
039     * 
040     * <pre>
041     * #cycle result evaluation individual
042     * 0 0 20000.0 [100.0, 100.0]
043     * 1 0 19260.53116542464 [98.73071889720983, 97.38596735781995]
044     * 1 1 19468.191322019986 [99.22362530562448, 98.05102529016519]
045     * 1 2 19532.212300408937 [97.62563047159728, 99.91503437205381]
046     * 1 3 19567.90766494946 [99.72890299878424, 98.03323251603692]
047     * 2 0 18794.398942170505 [96.3683774664037, 97.34133324282375]
048     * 2 1 18913.606724906247 [98.47298455693839, 95.88758715386727]
049     * 2 2 19009.274361645486 [97.58557565219022, 97.25069301017946]
050     * 2 3 19068.25006183995 [96.79725135084752, 98.36164874253139]
051     * </pre>
052     * 
053     * @param <I>
054     *            the individuals' type
055     * 
056     * @author <a href="http://kumpe.de/christian/java">Christian Kumpe</a>
057     */
058    public class TextFileReporter<I> implements Reporter<I> {
059            private static final long serialVersionUID = 1L;
060    
061            private final transient PrintWriter out;
062            private long cycle;
063            private long lastCycleStart;
064    
065            public TextFileReporter(final PrintWriter out) {
066                    if (null == out) {
067                            throw new NullPointerException("out may not be null");
068                    }
069                    this.out = out;
070                    out.println("# cycle result duration[ns] evaluation individual...");
071            }
072    
073            @Override
074            public void report(final Collection<EvaluationResult<I>> evaluationResults) {
075                    if (null == out) {
076                            return;
077                    }
078                    final long now = System.nanoTime();
079                    final long duration = 0 < lastCycleStart ? now - lastCycleStart : -1;
080                    lastCycleStart = now;
081    
082                    int result = 0;
083                    for (final EvaluationResult<I> evaluationResult : evaluationResults) {
084                            final StringBuilder buffer = new StringBuilder();
085                            buffer.append(cycle);
086                            buffer.append(' ');
087                            buffer.append(result);
088                            buffer.append(' ');
089                            buffer.append(duration);
090                            buffer.append(' ');
091                            buffer.append(evaluationResult.getEvaluation());
092                            buffer.append(' ');
093                            LoggingReporter.formatIndividual(buffer,
094                                            evaluationResult.getIndividual());
095                            out.println(buffer.toString());
096                            result++;
097                    }
098                    cycle++;
099            }
100    
101            @Override
102            public String toString() {
103                    return "TextFileReporter []";
104            }
105    }