Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes the option to zip or not the binary serialisation format #356

Merged
merged 2 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
/*******************************************************************************************************
*
* CompositeGamaMessage.java, in gama.extension.network, is part of the source code of the
* GAMA modeling and simulation platform (v.2024-06).
* CompositeGamaMessage.java, in gama.extension.network, is part of the source code of the GAMA modeling and simulation
* platform (v.2024-06).
*
* (c) 2007-2024 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, ESPACE-DEV, CTU)
*
* Visit https://github.com/gama-platform/gama for license information and contacts.
*
*
********************************************************************************************************/
package gama.extension.network.common;

import gama.core.common.interfaces.ISerialisationConstants;
import gama.core.messaging.GamaMessage;
import gama.core.runtime.IScope;
import gama.extension.serialize.binary.BinarySerialisation;
Expand All @@ -33,8 +32,7 @@ public class CompositeGamaMessage extends GamaMessage {
*/
public CompositeGamaMessage(final IScope scope, final GamaMessage message) {
super(scope, message.getSender(), message.getReceivers(), message.getContents(scope));
this.contents = BinarySerialisation.saveToString(scope, message.getContents(scope),
ISerialisationConstants.BINARY_FORMAT, true);
this.contents = BinarySerialisation.saveToString(scope, message.getContents(scope));
// this.contents = StreamConverter.convertNetworkObjectToStream(scope, message.getContents(scope));
this.emissionTimeStamp = message.getEmissionTimestamp();
this.setUnread(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*******************************************************************************************************
*
* Connector.java, in gama.extension.network, is part of the source code of the
* GAMA modeling and simulation platform (v.2024-06).
* Connector.java, in gama.extension.network, is part of the source code of the GAMA modeling and simulation platform
* (v.2024-06).
*
* (c) 2007-2024 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, ESPACE-DEV, CTU)
*
* Visit https://github.com/gama-platform/gama for license information and contacts.
*
*
********************************************************************************************************/
package gama.extension.network.common;

Expand All @@ -17,7 +17,6 @@
import java.util.List;
import java.util.Map;

import gama.core.common.interfaces.ISerialisationConstants;
import gama.core.messaging.GamaMessage;
import gama.core.metamodel.agent.IAgent;
import gama.core.runtime.IScope;
Expand Down Expand Up @@ -189,11 +188,9 @@ public void send(final IAgent sender, final String receiver, final GamaMessage c
if (cmsg.getSender() instanceof IAgent) {
cmsg.setSender(sender.getAttribute(INetworkSkill.NET_AGENT_NAME));
}
final NetworkMessage msg = MessageFactory
.buildNetworkMessage((String) sender.getAttribute(INetworkSkill.NET_AGENT_NAME), receiver,
BinarySerialisation.saveToString(sender.getScope(), cmsg,
ISerialisationConstants.BINARY_FORMAT,
true) /* StreamConverter.convertObjectToStream(sender.getScope(), cmsg) */);
final NetworkMessage msg =
MessageFactory.buildNetworkMessage((String) sender.getAttribute(INetworkSkill.NET_AGENT_NAME),
receiver, BinarySerialisation.saveToString(sender.getScope(), cmsg));
this.sendMessage(sender, receiver, MessageFactory.packMessage(msg));
} else {
this.sendMessage(sender, receiver, content.getContents(sender.getScope()).toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import "Base Model.gaml"
experiment "1. Save Simulation" type: gui parent: Base {


string format <- "binary";
string file_path <- "../includes/saved_simulation.simulation";

text "Run the simulation until cycle 5, when it will be saved in a file and quit" font: font("Helvetica", 14, #bold);
parameter "File path" var: file_path ;

reflex store when: cycle = 5 {
save simulation to: file_path format: format;
save simulation to: file_path ;
do die;
}

Expand Down Expand Up @@ -48,7 +47,7 @@ experiment "3. Restore Simulation" type: gui parent: Base{
parameter "File to read" var: input <- file("../includes/saved_simulation.simulation");

// We "restore" the simulation from the file. As it happens each time the simulation reaches 10 cycles, it loops forever between 5 and 10 cycles.
reflex when: cycle=10 {
reflex when: simulation.cycle=10 {
restore simulation from: input;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,27 @@
********************************************************************************************************/
package gama.extension.serialize.binary;

import static gama.core.common.util.FileUtils.constructAbsoluteFilePath;
import static java.nio.file.Files.readAllBytes;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.WRITE;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

import org.nustaq.serialization.FSTConfiguration;

import gama.core.common.interfaces.ISerialisationConstants;
import gama.core.common.util.FileUtils;
import gama.core.kernel.simulation.SimulationAgent;
import gama.core.metamodel.agent.IAgent;
import gama.core.metamodel.agent.SerialisedAgent;
import gama.core.runtime.GAMA;
import gama.core.runtime.IScope;
import gama.core.runtime.exceptions.GamaRuntimeException;
import gama.core.util.ByteArrayZipper;

/**
* The Class BinarySerialisationReader.
Expand All @@ -36,6 +40,8 @@
*/
public class BinarySerialisation implements ISerialisationConstants {

private static FSTConfiguration FST = FSTConfiguration.createDefaultConfiguration();

/** The processor. */
private static BinarySerialiser PROCESSOR = new BinarySerialiser();

Expand All @@ -52,24 +58,12 @@ public class BinarySerialisation implements ISerialisationConstants {
*/
public static Object createFromFile(final IScope scope, final String path) {
try {
byte[] all = Files.readAllBytes(Path.of(FileUtils.constructAbsoluteFilePath(scope, path, true)));
return createFromBytes(scope, all);
return createFromBytes(scope, readAllBytes(Path.of(constructAbsoluteFilePath(scope, path, true))));
} catch (IOException e) {
throw GamaRuntimeException.create(e, scope);
}
}

/**
* Checks if is serialisation header.
*
* @param b
* the b
* @return true, if is serialisation header
*/
private static boolean isSerialisationHeader(final byte b) {
return b == GAMA_OBJECT_IDENTIFIER || b == GAMA_AGENT_IDENTIFIER;
}

/**
* Creates the from string.
*
Expand All @@ -84,8 +78,7 @@ private static boolean isSerialisationHeader(final byte b) {
public static Object createFromString(final IScope scope, final String string) {
if (string == null || string.isBlank()) return null;
try {
byte[] all = string.getBytes(ISerialisationConstants.STRING_BYTE_ARRAY_CHARSET);
return createFromBytes(scope, all);
return createFromBytes(scope, string.getBytes(STRING_BYTE_ARRAY_CHARSET));
} catch (Throwable e) {
e.printStackTrace();
try {
Expand All @@ -108,13 +101,7 @@ public static Object createFromString(final IScope scope, final String string) {
* @date 31 oct. 2023
*/
public static Object createFromBytes(final IScope scope, final byte[] bytes) {
byte type = bytes[0];
if (!isSerialisationHeader(type)) throw GamaRuntimeException.error("Not a GAMA serialisation record", scope);
boolean zip = bytes[1] == COMPRESSED;
byte[] some = removeIdentifiers(bytes);
if (zip) { some = ByteArrayZipper.unzip(some); }
return type == GAMA_OBJECT_IDENTIFIER ? PROCESSOR.createObjectFromBytes(scope, some)
: PROCESSOR.createAgentFromBytes(scope, some);
return PROCESSOR.createObjectFromBytes(scope, bytes);
}

/**
Expand All @@ -127,8 +114,7 @@ public static Object createFromBytes(final IScope scope, final byte[] bytes) {
*/
public static void restoreFromFile(final IAgent agent, final String path) {
try {
byte[] all = Files.readAllBytes(Path.of(path));
if (isSerialisationHeader(all[0])) { restoreFromBytes(agent, all); }
restoreFromBytes(agent, Files.readAllBytes(Path.of(path)));
} catch (IOException e) {
throw GamaRuntimeException.create(e, agent.getScope());
}
Expand All @@ -146,11 +132,8 @@ public static void restoreFromFile(final IAgent agent, final String path) {
*/
public static void restoreFromString(final IAgent agent, final String string) {
try {
byte[] all = string.getBytes(ISerialisationConstants.STRING_BYTE_ARRAY_CHARSET);
restoreFromBytes(agent, all);
restoreFromBytes(agent, string.getBytes(STRING_BYTE_ARRAY_CHARSET));
} catch (Throwable e) {
// e.printStackTrace();
// The string is maybe a path ?
try {
restoreFromFile(agent, string);
} catch (Throwable ex) {
Expand All @@ -172,11 +155,7 @@ public static void restoreFromString(final IAgent agent, final String string) {
* @date 8 août 2023
*/
public static void restoreFromBytes(final IAgent sim, final byte[] bytes) throws IOException {
if (bytes[0] != GAMA_AGENT_IDENTIFIER) throw new IOException("Not an agent serialisation record");
boolean zip = bytes[1] == COMPRESSED;
byte[] some = removeIdentifiers(bytes);
if (zip) { some = ByteArrayZipper.unzip(some); }
PROCESSOR.restoreAgentFromBytes(sim, some);
PROCESSOR.restoreAgentFromBytes(sim, bytes);
}

/**
Expand All @@ -197,14 +176,13 @@ public static void restoreFromBytes(final IAgent sim, final byte[] bytes) throws
* whether to include the "history" of the agent in the serialisation. Only applicables to simulations
* @date 31 oct. 2023
*/
public static final void saveToFile(final IScope scope, final Object o, final String path, final String format,
final boolean zip, final boolean includingHistory) {
try (OutputStream os = Files.newOutputStream(new File(path).toPath(), StandardOpenOption.APPEND,
StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
public static final void saveToFile(final IScope scope, final Object o, final String path,
final boolean includingHistory) {
try (OutputStream os = Files.newOutputStream(new File(path).toPath(), CREATE, WRITE, TRUNCATE_EXISTING)) {
if (o instanceof SimulationAgent sim) {
sim.setAttribute(SerialisedAgent.SERIALISE_HISTORY, includingHistory);
}
os.write(saveToBytes(scope, o, zip));
os.write(saveToBytes(scope, o));
if (o instanceof SimulationAgent sim) { sim.setAttribute(SerialisedAgent.SERIALISE_HISTORY, false); }
} catch (IOException e) {
throw GamaRuntimeException.create(e, scope);
Expand All @@ -218,9 +196,8 @@ public static final void saveToFile(final IScope scope, final Object o, final St
* @return
* @date 8 août 2023
*/
public static final String saveToString(final IScope scope, final Object sim, final String format,
final boolean zip) {
return new String(saveToBytes(scope, sim, zip), STRING_BYTE_ARRAY_CHARSET);
public static final String saveToString(final IScope scope, final Object sim) {
return new String(saveToBytes(scope, sim), STRING_BYTE_ARRAY_CHARSET);
}

/**
Expand All @@ -232,46 +209,8 @@ public static final String saveToString(final IScope scope, final Object sim, fi
* @return the string
* @date 21 août 2023
*/
public static final byte[] saveToBytes(final IScope scope, final Object object, final boolean zip) {
byte[] toSave = object instanceof IAgent a ? PROCESSOR.saveAgentToBytes(scope, a)
: PROCESSOR.saveObjectToBytes(scope, object);
if (zip) { toSave = ByteArrayZipper.zip(toSave); }
return addIdentifiers(toSave, object instanceof IAgent ? GAMA_AGENT_IDENTIFIER : GAMA_OBJECT_IDENTIFIER,
zip ? COMPRESSED : UNCOMPRESSED);
}

/**
* Adds the byte.
*
* @param array
* the array
* @param identifier
* the identifier
* @param zip
* the zip
* @return the byte[]
*/
private static byte[] addIdentifiers(final byte[] array, final byte identifier, final byte zip) {
if (array == null) return new byte[] { identifier, zip };
ByteBuffer buffer = ByteBuffer.allocate(array.length + 2);
buffer.put(identifier);
buffer.put(zip);
buffer.put(array);
return buffer.array();
}

/**
* Removes the identifiers.
*
* @param array
* the tableau
* @return the byte[]
*/
public static byte[] removeIdentifiers(final byte[] array) {
if (array == null || array.length < 2) return new byte[0];
byte[] newArray = new byte[array.length - 2];
System.arraycopy(array, 2, newArray, 0, newArray.length);
return newArray;
public static final byte[] saveToBytes(final IScope scope, final Object object) {
return PROCESSOR.saveObjectToBytes(scope, object);
}

/**
Expand All @@ -285,8 +224,8 @@ public static byte[] removeIdentifiers(final byte[] array) {
* @return the byte[]
* @date 29 déc. 2023
*/
public static final byte[] saveToBytes(final Object object, final boolean zip) {
return saveToBytes(GAMA.getRuntimeScope(), object, zip);
public static final byte[] saveToBytes(final Object object) {
return saveToBytes(GAMA.getRuntimeScope(), object);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,6 @@ public void restoreAgentFromBytes(final IAgent sim, final byte[] input) {
}
}

/**
* Save simulation to bytes.
*
* @author Alexis Drogoul ([email protected])
* @param sim
* the sim
* @return the byte[]
* @date 8 août 2023
*/
public byte[] saveAgentToBytes(final IScope newScope, final IAgent sim) {
return saveObjectToBytes(newScope, SerialisedAgent.of(sim, true));
}

/**
* Save object to bytes.
*
Expand All @@ -125,7 +112,7 @@ public byte[] saveAgentToBytes(final IScope newScope, final IAgent sim) {
*/
public byte[] saveObjectToBytes(final IScope newScope, final Object obj) {
inAgent = false;
return fst.asByteArray(obj);
return fst.asByteArray(obj instanceof IAgent a ? SerialisedAgent.of(a, true) : obj);
}

/**
Expand All @@ -140,32 +127,11 @@ public byte[] saveObjectToBytes(final IScope newScope, final Object obj) {
* @date 29 sept. 2023
*/
public Object createObjectFromBytes(final IScope newScope, final byte[] input) {
try {
scope = newScope;
return fst.asObject(input);
} catch (Exception e) {
throw GamaRuntimeException.create(e, scope);
} finally {
scope = null;
}

}

/**
* Creates the agent from bytes.
*
* @param newScope
* the new scope
* @param input
* the input
* @return the i agent
*/
public IAgent createAgentFromBytes(final IScope newScope, final byte[] input) {
try {
scope = newScope;
Object o = fst.asObject(input);
if (o instanceof SerialisedAgent sa) return sa.recreateIn(scope);
return null;
return o;
} catch (Exception e) {
throw GamaRuntimeException.create(e, scope);
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import gama.core.util.ByteArrayZipper;
import gama.dev.DEBUG;
import gama.extension.serialize.binary.SimulationHistory.SimulationHistoryNode;

Expand All @@ -36,7 +35,7 @@ static record SimulationHistoryNode(byte[] bytes, long cycle) {}
final ExecutorService executor = Executors.newCachedThreadPool();

public void push(final byte[] state, final int cycle) {
executor.execute(() -> { push(new SimulationHistoryNode(ByteArrayZipper.zip(state), cycle)); });
executor.execute(() -> { push(new SimulationHistoryNode(state, cycle)); });
}

}
Loading