com.google.caliper.runner.OutputFileDumper.java Source code

Java tutorial

Introduction

Here is the source code for com.google.caliper.runner.OutputFileDumper.java

Source

/*
 * Copyright (C) 2011 Google Inc.
 *
 * 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 com.google.caliper.runner;

import static java.util.logging.Level.SEVERE;

import com.google.caliper.api.ResultProcessor;
import com.google.caliper.config.CaliperConfig;
import com.google.caliper.config.InvalidConfigurationException;
import com.google.caliper.config.ResultProcessorConfig;
import com.google.caliper.model.Run;
import com.google.caliper.model.Trial;
import com.google.caliper.options.CaliperDirectory;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.stream.JsonWriter;

import org.joda.time.format.ISODateTimeFormat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.logging.Logger;

import javax.inject.Inject;

/**
 * {@link ResultProcessor} that dumps the output data to a file in JSON format. By default, the
 * output will be dumped to a file called
 * {@code ~/.caliper/results/[benchmark classname].[timestamp].json}; if it exists and is a file,
 * the file will be overwritten.  The location can be overridden as either a file or a directory
 * using either the {@code file} or {@code dir} options respectively.
 */
final class OutputFileDumper implements ResultProcessor {
    private static final Logger logger = Logger.getLogger(OutputFileDumper.class.getName());

    private final Run run;
    private final Gson gson;
    private final File resultFile;
    private final File workFile;

    private Optional<JsonWriter> writer = Optional.absent();

    @Inject
    OutputFileDumper(Run run, BenchmarkClass benchmarkClass, Gson gson, CaliperConfig caliperConfig,
            @CaliperDirectory File caliperDirectory) throws InvalidConfigurationException {
        this.run = run;
        ResultProcessorConfig config = caliperConfig.getResultProcessorConfig(OutputFileDumper.class);
        if (config.options().containsKey("file")) {
            this.resultFile = new File(config.options().get("file"));
            logger.finer("found an output file in the configuration");
        } else if (config.options().containsKey("dir")) {
            File dir = new File(config.options().get("dir"));
            if (dir.isFile()) {
                throw new InvalidConfigurationException("specified a directory, but it's a file");
            }
            this.resultFile = new File(dir, createFileName(benchmarkClass.name()));
            logger.finer("found an output directory in the configuration");
        } else {
            this.resultFile = new File(new File(caliperDirectory, "results"),
                    createFileName(benchmarkClass.name()));
            logger.fine("found no configuration");
        }
        logger.fine(String.format("using %s for results", resultFile));
        this.gson = gson;
        this.workFile = new File(resultFile.getPath() + ".tmp");
    }

    private String createFileName(String benchmarkName) {
        return String.format("%s.%s.json", benchmarkName, createTimestamp());
    }

    private String createTimestamp() {
        return ISODateTimeFormat.dateTimeNoMillis().print(run.startTime());
    }

    @Override
    public void processTrial(Trial trial) {
        if (!writer.isPresent()) {
            try {
                Files.createParentDirs(workFile);
                JsonWriter writer = new JsonWriter(
                        new OutputStreamWriter(new FileOutputStream(workFile), Charsets.UTF_8));
                writer.setIndent("  "); // always pretty print
                writer.beginArray();
                this.writer = Optional.of(writer);
            } catch (IOException e) {
                logger.log(SEVERE,
                        String.format("An error occured writing trial %s. Results in %s will be incomplete.",
                                trial.id(), resultFile),
                        e);
            }
        }
        if (writer.isPresent()) {
            gson.toJson(trial, Trial.class, writer.get());
        }
    }

    @Override
    public void close() throws IOException {
        if (writer.isPresent()) {
            writer.get().endArray().close();
        }
        if (workFile.exists()) {
            Files.move(workFile, resultFile);
        }
    }
}