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

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

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

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
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.net.URL;
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.perfs.Context;
import cdc.perfs.Environment;
import cdc.perfs.EnvironmentKind;
import cdc.perfs.Measure;
import cdc.perfs.MeasureStatus;
import cdc.perfs.api.MeasureLevel;
import cdc.perfs.api.RuntimeProbe;
import cdc.perfs.api.Source;
import cdc.perfs.runtime.RuntimeEnvironment;
import cdc.perfs.snapshot.SnapshotContext;
import cdc.perfs.snapshot.SnapshotEnvironment;
import cdc.perfs.snapshot.SnapshotMeasure;
import cdc.util.bin.BinaryIO;
import cdc.util.compress.CompressionUtil;
import cdc.util.compress.Compressor;

/**
 * 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 { protected static final EnvironmentKind[] ENVIRONMENT_KIND_VALUES = EnvironmentKind.values(); protected static final MeasureLevel[] MEASURE_LEVEL_VALUES = MeasureLevel.values(); protected static final MeasureStatus[] MEASURE_STATUS_VALUES = MeasureStatus.values(); protected static final int VERSION_1 = 1; private PerfsBin() { } protected static boolean isValidVersion(int number) { return number == VERSION_1; } /** * Environment binary serialization. * * @author Damien Carbonne * */ public static 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<>(); public Writer() { // Nothing to do } public void save(Environment environment, String filename, Compressor compressor) throws IOException { final RuntimeProbe probe = RuntimeEnvironment.getInstance().createProbe(SOURCE, MeasureLevel.INFO); probe.start("save(" + filename + ", " + compressor + ")"); try (final FileOutputStream fos = new FileOutputStream(filename); final BufferedOutputStream bos = new BufferedOutputStream(CompressionUtil.adapt(fos, compressor)); final DataOutputStream out = new DataOutputStream(bos)) { writeEnvironment(environment, out); out.flush(); } catch (final IOException e) { LOGGER.trace("Error saving:" + filename, e); throw e; } finally { probe.stop(); } } private static String protect(String s) { return s == null ? "" : s; } private void writeEnvironment(Environment environment, DataOutput out) throws IOException { out.writeInt(VERSION_1); 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); } out.writeInt(environment.getContexts().size()); for (final Context context : environment.getContexts()) { writeContext(context, out); } } private void writeSource(Source source, DataOutput out) throws IOException { 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, DataOutput out) 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), out); } } private void writeMeasure(Measure measure, DataOutput out) throws IOException { 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, out); child = child.getNextSibling(); } } } /** * Environment binary deserialization. * * @author Damien Carbonne * */ public static 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<>(); public SnapshotEnvironment load(String filename, Compressor compressor) throws IOException { final RuntimeProbe probe = RuntimeEnvironment.getInstance().createProbe(SOURCE, MeasureLevel.INFO); probe.start("load(" + filename + ", " + compressor + ")"); try (final FileInputStream fis = new FileInputStream(filename); final BufferedInputStream bis = new BufferedInputStream(CompressionUtil.adapt(fis, compressor)); final DataInputStream in = new DataInputStream(bis)) { return readEnvironment(in); } catch (final IOException e) { LOGGER.trace("Error loading:" + filename, e); throw e; } finally { probe.stop(); } } public SnapshotEnvironment load(File file, Compressor compressor) throws IOException { final RuntimeProbe probe = RuntimeEnvironment.getInstance().createProbe(SOURCE, MeasureLevel.INFO); probe.start("load(" + file + ", " + compressor + ")"); try (final FileInputStream fis = new FileInputStream(file); final BufferedInputStream bis = new BufferedInputStream(CompressionUtil.adapt(fis, compressor)); final DataInputStream in = new DataInputStream(bis)) { return readEnvironment(in); } catch (final IOException e) { LOGGER.trace("Error loading:" + file, e); throw e; } finally { probe.stop(); } } public SnapshotEnvironment load(URL url, Compressor compressor) throws IOException { final RuntimeProbe probe = RuntimeEnvironment.getInstance().createProbe(SOURCE, MeasureLevel.INFO); probe.start("load(" + url + ", " + compressor + ")"); try (final InputStream is = url.openStream(); final BufferedInputStream bis = new BufferedInputStream(CompressionUtil.adapt(is, compressor)); final DataInputStream in = new DataInputStream(bis)) { return readEnvironment(in); } catch (final IOException e) { LOGGER.trace("Error loading:" + url, e); throw e; } finally { probe.stop(); } } private SnapshotEnvironment readEnvironment(DataInput in) throws IOException { final int 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, in); readContexts(environment, in); return environment; } private void readSources(SnapshotEnvironment environment, DataInput in) throws IOException { final int count = in.readInt(); for (int index = 0; index < count; index++) { readSource(environment, in); } } private void readContexts(SnapshotEnvironment environment, DataInput in) throws IOException { final int count = in.readInt(); for (int index = 0; index < count; index++) { readContext(environment, in); } } private void readSource(SnapshotEnvironment environment, DataInput in) throws IOException { final short id = in.readShort(); final String name = in.readUTF(); final MeasureLevel maxLevel = BinaryIO.readByteAsEnum(MEASURE_LEVEL_VALUES, in); final Source source = environment.getSource(name); source.setMaxLevel(maxLevel); sources.put(id, source); } private void readContext(SnapshotEnvironment environment, DataInput in) 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, in); } } private SnapshotMeasure readMeasure(SnapshotContext context, SnapshotMeasure parent, int parentDepth, SnapshotMeasure previous, DataInput in) 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, in); } return measure; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy