All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.perfs.core.io.PerfsBin Maven / Gradle / Ivy

There is a newer version: 0.52.0
Show newest version
package cdc.perfs.core.io;

import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import cdc.io.compress.CompressionUtils;
import cdc.io.compress.Compressor;
import cdc.io.utils.BinaryIO;
import cdc.io.utils.IOUtils;
import cdc.perfs.api.MeasureLevel;
import cdc.perfs.api.RuntimeProbe;
import cdc.perfs.api.Source;
import cdc.perfs.api.SourceLevel;
import cdc.perfs.core.Context;
import cdc.perfs.core.Environment;
import cdc.perfs.core.EnvironmentKind;
import cdc.perfs.core.Measure;
import cdc.perfs.core.MeasureStatus;
import cdc.perfs.core.runtime.RuntimeEnvironment;
import cdc.perfs.core.snapshot.SnapshotContext;
import cdc.perfs.core.snapshot.SnapshotEnvironment;
import cdc.perfs.core.snapshot.SnapshotMeasure;
import cdc.util.events.ProgressController;
import cdc.util.events.ProgressSupplier;

/**
 * Binary serialization / deserialization of environments.
 * 

* Binary format is: *

Stream = {
 *    Version          : int (1)
 *    Environment_Kind : byte
 *    Reference_Date   : long
 *    Reference_Nanos  : long
 *    Elapsed_Nanos    : long
 *    Sources {
 *       Count   : int
 *       [Count] : Source
 *    }
 *    Contexts {
 *       Count   : int
 *       [Count] : Context
 *    }
 * }
 *
 * Source = {
 *    Id        : short
 *    Name      : String
 *    Max_Level : byte
 * }
 *
 * Context = {
 *    Id       : int
 *    Name     : String
 *    Is_Alive : boolean
 *    Count    : int
 *    [Count]  : Measure
 * }
 *
 * Measure = {
 *    Source_Id            : short
 *    Status               : byte
 *    Level                : byte
 *    Details              : String
 *    Absolute_Begin_Nanos : long
 *    Absolute_End_Nanos   : long
 *    Children_Count       : int
 *    [Children_Count]     : Measure
 * }
* * @author Damien Carbonne * */ public final class PerfsBin { private static final int SIZE = 1024 * 128; private static final EnvironmentKind[] ENVIRONMENT_KIND_VALUES = EnvironmentKind.values(); private static final SourceLevel[] SOURCE_LEVEL_VALUES = SourceLevel.values(); private static final MeasureLevel[] MEASURE_LEVEL_VALUES = MeasureLevel.values(); private static final MeasureStatus[] MEASURE_STATUS_VALUES = MeasureStatus.values(); private static final int VERSION_1 = 1; private static final int VERSION_2 = 2; private PerfsBin() { } static boolean isValidVersion(int number) { return number == VERSION_1 || number == VERSION_2; } /** * Environment binary serialization. * * @author Damien Carbonne * */ public static final class Writer { private static final Logger LOGGER = LogManager.getLogger(Writer.class); private static final Source SOURCE = RuntimeEnvironment.getInstance().getSource(Writer.class); private final Map sources = new HashMap<>(); private final ProgressSupplier progressSupplier; private final DataOutputStream out; private Writer(DataOutputStream out, ProgressController controller) { this.progressSupplier = new ProgressSupplier(controller); this.out = out; } public static void save(Environment environment, OutputStream os, String systemId, Compressor compressor, ProgressController controller) throws IOException { final RuntimeProbe probe = RuntimeEnvironment.getInstance().createProbe(SOURCE, MeasureLevel.INFO); probe.start("save(" + systemId + ", " + compressor + ")"); try (final DataOutputStream out = new DataOutputStream(CompressionUtils.adapt(IOUtils.toBuffered(os, SIZE), compressor))) { final Writer writer = new Writer(out, controller); writer.writeEnvironment(environment); } catch (final IOException e) { LOGGER.trace(() -> "Error saving: " + systemId, e); throw e; } finally { probe.stop(); } } public static void save(Environment environment, File file, Compressor compressor, ProgressController controller) throws IOException { save(environment, new FileOutputStream(file), file.getPath(), compressor, controller); } public static void save(Environment environment, String filename, Compressor compressor, ProgressController controller) throws IOException { save(environment, new File(filename), compressor, controller); } public static void save(Environment environment, URL url, Compressor compressor, ProgressController controller) throws IOException { final URLConnection connection = url.openConnection(); connection.setDoOutput(true); save(environment, connection.getOutputStream(), url.toExternalForm(), compressor, controller); } private static String protect(String s) { return s == null ? "" : s; } private void writeEnvironment(Environment environment) throws IOException { progressSupplier.setTotal((long) environment.getSources().size() + environment.getMeasuresCount()); progressSupplier.setValue(0L); out.writeInt(VERSION_2); BinaryIO.writeEnumAsByte(environment.getKind(), out); out.writeLong(Date.from(environment.getReferenceInstant()).getTime()); out.writeLong(environment.getReferenceNanos()); out.writeLong(environment.getElapsedNanos()); out.writeInt(environment.getSources().size()); for (final Source source : environment.getSources()) { writeSource(source); } out.writeInt(environment.getContexts().size()); for (final Context context : environment.getContexts()) { writeContext(context); } out.flush(); } private void writeSource(Source source) throws IOException { progressSupplier.checkCancelled(); progressSupplier.incrementValue(); final short id = (short) (sources.size() + 1); sources.put(source, id); out.writeShort(id); out.writeUTF(source.getName()); BinaryIO.writeEnumAsByte(source.getMaxLevel(), out); } private void writeContext(Context context) throws IOException { out.writeInt(context.getId()); out.writeUTF(protect(context.getName())); out.writeBoolean(context.isAlive()); out.writeInt(context.getRootMeasuresCount()); for (int index = 0; index < context.getRootMeasuresCount(); index++) { writeMeasure(context.getRootMeasure(index)); } } private void writeMeasure(Measure measure) throws IOException { progressSupplier.checkCancelled(); progressSupplier.incrementValue(); out.writeShort(sources.get(measure.getSource())); BinaryIO.writeEnumAsByte(measure.getStatus(), out); BinaryIO.writeEnumAsByte(measure.getLevel(), out); out.writeUTF(protect(measure.getDetails())); out.writeLong(measure.getAbsoluteBeginNanos()); out.writeLong(measure.getAbsoluteEndNanos()); out.writeInt(measure.getChildrenCount()); Measure child = measure.getFirstChild(); while (child != null) { writeMeasure(child); child = child.getNextSibling(); } } } /** * Environment binary deserialization. * * @author Damien Carbonne * */ public static final class Reader { private static final Logger LOGGER = LogManager.getLogger(Reader.class); private static final Source SOURCE = RuntimeEnvironment.getInstance().getSource(Reader.class); private final Map sources = new HashMap<>(); private int version = -1; private final DataInput in; private Reader(DataInput in) { this.in = in; } public static SnapshotEnvironment load(InputStream in, String systemId, Compressor compressor) throws IOException { final RuntimeProbe probe = RuntimeEnvironment.getInstance().createProbe(SOURCE, MeasureLevel.INFO); probe.start("load(" + systemId + ", " + compressor + ")"); try (final DataInputStream din = new DataInputStream((CompressionUtils.adapt(IOUtils.toBuffered(in, SIZE), compressor)))) { final Reader reader = new Reader(din); return reader.readEnvironment(); } catch (final IOException e) { LOGGER.trace(() -> "Error loading: " + systemId, e); throw e; } finally { probe.stop(); } } public static SnapshotEnvironment load(File file, Compressor compressor) throws IOException { return load(new FileInputStream(file), file.getPath(), compressor); } public static SnapshotEnvironment load(String filename, Compressor compressor) throws IOException { return load(new File(filename), compressor); } public static SnapshotEnvironment load(URL url, Compressor compressor) throws IOException { return load(url.openStream(), url.toExternalForm(), compressor); } private SnapshotEnvironment readEnvironment() throws IOException { this.version = in.readInt(); if (!isValidVersion(version)) { throw new IOException("Invalid version (" + version + ")"); } BinaryIO.readByteAsEnum(ENVIRONMENT_KIND_VALUES, in); final Date refDate = new Date(in.readLong()); final long refNanos = in.readLong(); final long elapsedNanos = in.readLong(); final SnapshotEnvironment environment = new SnapshotEnvironment(refNanos, refDate.toInstant(), elapsedNanos); readSources(environment); readContexts(environment); return environment; } private void readSources(SnapshotEnvironment environment) throws IOException { final int count = in.readInt(); for (int index = 0; index < count; index++) { readSource(environment); } } private void readContexts(SnapshotEnvironment environment) throws IOException { final int count = in.readInt(); for (int index = 0; index < count; index++) { readContext(environment); } } private void readSource(SnapshotEnvironment environment) throws IOException { final short id = in.readShort(); final String name = in.readUTF(); final SourceLevel maxLevel; if (version == VERSION_1) { final SourceLevel tmp = BinaryIO.readByteAsEnum(SOURCE_LEVEL_VALUES, in); maxLevel = SourceLevel.values()[tmp.ordinal() + 1]; } else { maxLevel = BinaryIO.readByteAsEnum(SOURCE_LEVEL_VALUES, in); } final Source source = environment.getSource(name); source.setMaxLevel(maxLevel); sources.put(id, source); } private void readContext(SnapshotEnvironment environment) throws IOException { final int id = in.readInt(); final String name = in.readUTF(); final boolean alive = in.readBoolean(); final SnapshotContext context = environment.createContext(id, name, alive); final int count = in.readInt(); SnapshotMeasure previous = null; for (int index = 0; index < count; index++) { previous = readMeasure(context, null, 0, previous); } } private SnapshotMeasure readMeasure(SnapshotContext context, SnapshotMeasure parent, int parentDepth, SnapshotMeasure previous) throws IOException { final short sourceId = in.readShort(); final MeasureStatus status = BinaryIO.readByteAsEnum(MEASURE_STATUS_VALUES, in); final MeasureLevel level = BinaryIO.readByteAsEnum(MEASURE_LEVEL_VALUES, in); final String details = in.readUTF(); final long begin = in.readLong(); final long end = in.readLong(); final SnapshotMeasure measure = context.createMeasure(parent, parentDepth, previous, sources.get(sourceId), details, begin, end, status, level); final int count = in.readInt(); SnapshotMeasure prev = null; for (int index = 0; index < count; index++) { prev = readMeasure(context, measure, parentDepth + 1, prev); } return measure; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy