Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cdc.perfs.core.io.PerfsBin Maven / Gradle / Ivy
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;
}
}
}