package org.simantics.db.common;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import org.simantics.databoard.Bindings;
import org.simantics.databoard.binding.Binding;
-import org.simantics.databoard.serialization.SerializationException;
import org.simantics.databoard.serialization.Serializer;
import org.simantics.db.Metadata;
import org.simantics.db.Session;
import org.simantics.db.WriteGraph;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.Bytes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class CommandMetadata implements Metadata {
+import gnu.trove.list.array.TByteArrayList;
+
+public final class CommandMetadata implements Metadata {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CommandMetadata.class);
public static final boolean DEBUG = false;
public static final String RESET_COMMAND = "// RESET";
-
+
private static final Binding BINDING =
Bindings.getBindingUnchecked(CommandMetadata.class);
private static final Serializer SERIALIZER =
Bindings.getSerializerUnchecked(BINDING);
-
+
public List<Command> commands;
-
- public static class Command {
+
+ public static final class Command {
public long modelId;
public String command;
-
- public Command() {
+
+ public Command() {
}
-
+
public Command(long modelId, String command) {
super();
this.modelId = modelId;
this.command = command;
}
}
-
+
public CommandMetadata() {
}
@Override
public byte[] serialise(Session session) {
try {
- return SERIALIZER.serialize(this);
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException(e);
+ TByteArrayList commandsSerialized = new TByteArrayList(4096);
+ byte[] bytes = new byte[8];
+
+ int commandsSize = commands.size();
+ Bytes.writeLE(bytes, 0, commandsSize);
+ commandsSerialized.add(bytes, 0, 4);
+
+ for (Command command : commands) {
+ Bytes.writeLE8(bytes, 0, command.modelId);
+ commandsSerialized.add(bytes);
+ byte[] commandBytes = command.command.getBytes(StandardCharsets.UTF_8);
+ Bytes.writeLE(bytes, 0, commandBytes.length);
+ commandsSerialized.add(bytes, 0, 4);
+ commandsSerialized.add(commandBytes);
+ }
+ return commandsSerialized.toArray();
+ } catch (Exception ee) {
+ // Ok, backwards compatibility required
+ // This is rather slow operation hence the new implementation above
+ try {
+ return SERIALIZER.serialize(this);
+ } catch (IOException e) {
+ LOGGER.error("Could not serialize", e);
+ LOGGER.error("Original exception for new serialisation", ee);
+ throw new RuntimeException(e);
+ }
}
}
-
+
public static CommandMetadata deserialise(Session session, byte[] input) {
if(input == null) {
CommandMetadata metadata = new CommandMetadata();
return metadata;
}
try {
- return (CommandMetadata)SERIALIZER.deserialize(input);
- } catch (SerializationException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ int byteIndex = 0;
+ int commandsSize = Bytes.readLE4(input, byteIndex);
+ byteIndex += 4;
+
+ List<Command> commands = new ArrayList<>(commandsSize);
+ for (int i = 0; i < commandsSize; i++) {
+ long modelId = Bytes.readLE8(input, byteIndex);
+ byteIndex += 8;
+ int commandsLength = Bytes.readLE4(input, byteIndex);
+ byteIndex += 4;
+
+ String command = new String(input, byteIndex, commandsLength);
+ byteIndex += commandsLength;
+ Command comm = new Command(modelId, command);
+ commands.add(comm);
+ }
+ CommandMetadata metadata = new CommandMetadata();
+ metadata.commands = commands;
+ return metadata;
+ } catch (Exception ee) {
+ // Ok, backwards compatibility required
+ // This is rather slow operation hence the new implementation above
+ try {
+ return (CommandMetadata)SERIALIZER.deserialize(input);
+ } catch (Exception e) {
+ LOGGER.error("Could not deserialise", e);
+ LOGGER.error("Original exception for new deserialisation", ee);
+ }
+ return null;
}
- return null;
}
public CommandMetadata add(Command command) {