Permalink
Browse files

Issue 72: Corrected the data logging and decoding

  • Loading branch information...
rhauch committed Mar 5, 2016
1 parent 94b3ebd commit 9b81275213c6bfb3fdac7df82fcb672baabd1f11
@@ -24,9 +24,10 @@
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.Map;
import java.util.StringJoiner;
import org.strongback.tools.utils.FileUtils;
import org.strongback.tools.utils.Parser;
@@ -180,33 +181,41 @@ public static final void main(String[] args) {
}
}
private static String readString(DataInputStream in) throws EOFException, IOException{
int len = in.readInt();
byte[] value = new byte[len];
in.read(value);
return new String(value,StandardCharsets.UTF_8);
}
/* Actually converts the log */
private static final void decode(DataInputStream in, BufferedWriter writer)
throws BadFileFormatException, EOFException, IOException {
// Verify Header
printer.print(Strings.CHECK_LOG, Printer.Verbosity.VERBOSE);
byte[] header = new byte[3];
in.read(header);
if(!Arrays.equals(header, "log".getBytes())) throw new BadFileFormatException();
String header = readString(in);
printer.print("Found header = " + header, Printer.Verbosity.VERBOSE);
if(!"data-record".equals(header)) throw new BadFileFormatException();
printer.print(Strings.SUCCESS, Printer.Verbosity.VERBOSE);
// Get the number of elements
int numElements = in.read();
// Get the number of channels
int numElements = in.readInt();
printer.print(Strings.ELEMENT_COUNT + numElements, Printer.Verbosity.VERBOSE);
// Get the size of each element
// Get the size of each channel sample
int[] elementSizes = new int[numElements];
for(int i = 0; i< elementSizes.length; i++) {
elementSizes[i] = in.read();
elementSizes[i] = in.readInt();
printer.print("read channel " + i + " size = " + elementSizes[i], Printer.Verbosity.VERBOSE);
}
// Write the name of each element
// Read and write the name of each channel
StringJoiner joiner = new StringJoiner(",");
for(int i = 0; i< numElements; i++) {
int nameSize = in.read();
byte[] b = new byte[nameSize];
in.read(b);
writer.write(new String(b) + ", ");
joiner.add(readString(in));
}
writer.write(joiner.toString());
printer.print("channel names = " + joiner, Printer.Verbosity.VERBOSE);
writer.newLine();
printer.print(Strings.READING_LOG, Printer.Verbosity.VERBOSE);
@@ -218,11 +227,16 @@ private static final void decode(DataInputStream in, BufferedWriter writer)
printer.print(Strings.READ_LINE + lineCount, Printer.Verbosity.VERBOSE);
in.reset();
for(int i = 0; i < numElements; i++) {
if (i!=0) writer.write(",");
if(elementSizes[i]==4){
writer.write(in.readInt() + ", ");
int value = in.readInt();
writer.write(Integer.toString(value));
} else if(elementSizes[i]==2) {
short value = in.readShort();
writer.write(Short.toString(value));
} else {
throw new IOException("Unexpected size of data: " + elementSizes[i]);
}
else if(elementSizes[i]==2)
writer.write(in.readShort() + ", ");
}
writer.newLine();
lineCount++;
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
@@ -33,6 +34,7 @@
private MappedFileDataWriter writer;
private long recordLength;
private final long fileSize;
private final int channelCount;
public FileDataWriter(Iterable<DataRecorderChannel> channels, Supplier<String> filenameGenerator, int writesPerSecond,
int runningTimeInSeconds) {
@@ -47,6 +49,10 @@ public FileDataWriter(Iterable<DataRecorderChannel> channels, Supplier<String> f
recordLength += (Short.BYTES * suppliers.size());
fileSize = numWrites * recordLength + 1024; // add extra room for header and miscellaneous
AtomicInteger count = new AtomicInteger();
channels.forEach(ch->count.incrementAndGet());
channelCount = count.get() + 1; // adding the time sequence
openIfNeeded();
}
@@ -57,16 +63,16 @@ protected void openIfNeeded() {
} catch (IOException e) {
throw new RuntimeException(e);
}
suppliers.clear();
// Write the header
writer.write("data-record");
// Write the number of elements
writer.write(suppliers.size() + 1);
// Write the size of each element (Infrastructure for variable length element)
writer.write(Integer.BYTES);
writer.write(channelCount);
// Write the size of each channel as an integer
writer.write(Integer.BYTES); // size of the time channel
channels.forEach(channel -> {
IntSupplier supplier = channel.getSupplier();
assert supplier != null;
@@ -101,6 +107,7 @@ public void close() {
writer.close();
} finally {
writer = null;
suppliers.clear();
}
}
@@ -22,6 +22,7 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.LongConsumer;
import java.util.function.Supplier;
@@ -358,6 +359,52 @@ public Configurator reportExcessiveExecutionPeriods(LongConsumer handler) {
return this;
}
/**
* When the supplied condition is {@code true}, call the supplied function with this Configurator.
* @param condition the condition that determines whether the supplied function should be called; may not be null
* @param configure the function that will perform additional configuration
* @return this configurator so that methods can be chained together; never null
*/
public Configurator when( boolean condition, Runnable configure ) {
return when(()->condition,configure);
}
/**
* When the supplied condition is {@code true}, call the supplied function with this Configurator.
* @param condition the function that determines whether the supplied function should be called; may not be null
* @param configure the function that will perform additional configuration
* @return this configurator so that methods can be chained together; never null
*/
public Configurator when( BooleanSupplier condition, Runnable configure ) {
if ( condition != null && configure != null && condition.getAsBoolean() ) {
configure.run();
}
return this;
}
/**
* When the supplied condition is {@code true}, call the supplied function with this Configurator.
* @param condition the condition that determines whether the supplied function should be called; may not be null
* @param configure the function that will perform additional configuration
* @return this configurator so that methods can be chained together; never null
*/
public Configurator when( boolean condition, Consumer<Configurator> configure ) {
return when(()->condition,configure);
}
/**
* When the supplied condition is {@code true}, call the supplied function with this Configurator.
* @param condition the function that determines whether the supplied function should be called; may not be null
* @param configure the function that will perform additional configuration
* @return this configurator so that methods can be chained together; never null
*/
public Configurator when( BooleanSupplier condition, Consumer<Configurator> configure ) {
if ( condition != null && configure != null && condition.getAsBoolean() ) {
configure.accept(this);
}
return this;
}
/**
* Complete the Strongback configuration and initialize Strongback so that it can be used.
*/

0 comments on commit 9b81275

Please sign in to comment.