Commit 586fad4e authored by Lubomir Bulej's avatar Lubomir Bulej

ShadowString, ShadowThread: make constructors package private.

ShadowString, ShadowThread: add constructors for un-initialized shadows.
StringInfoHandler, ThreadInfoHandler: let ShadowObjectTable handle the registration, keep only IO in the handler code.
ShadowObjectTable: drop the debug parameter from the register() method, use logging instead.
ShadowObjectTable: use special constructors when creating un-initialized shadows of special objects.
ShadowClassTable: avoid using the debug parameter when calling the register() static method.
parent 9e74e34d
......@@ -6,34 +6,32 @@ import java.io.IOException;
import ch.usi.dag.dislreserver.DiSLREServerException;
import ch.usi.dag.dislreserver.reqdispatch.RequestHandler;
import ch.usi.dag.dislreserver.shadow.NetReferenceHelper;
import ch.usi.dag.dislreserver.shadow.ShadowClass;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
import ch.usi.dag.dislreserver.shadow.ShadowString;
public class StringInfoHandler implements RequestHandler {
public final class StringInfoHandler implements RequestHandler {
public void handle (DataInputStream is, DataOutputStream os, boolean debug)
throws DiSLREServerException {
@Override
public void handle (
final DataInputStream is, final DataOutputStream os,
final boolean debug
) throws DiSLREServerException {
try {
long net_ref = is.readLong ();
String str = is.readUTF ();
ShadowClass klass = ShadowClassTable.get (NetReferenceHelper.get_class_id (net_ref));
ShadowString sString = new ShadowString (net_ref, str, klass);
ShadowObjectTable.register (sString, debug);
} catch (IOException e) {
final long netReference = is.readLong ();
final String value = is.readUTF ();
ShadowObjectTable.registerShadowString (netReference, value);
} catch (final IOException e) {
throw new DiSLREServerException (e);
}
}
@Override
public void exit () {
// do nothing
}
}
......@@ -6,40 +6,35 @@ import java.io.IOException;
import ch.usi.dag.dislreserver.DiSLREServerException;
import ch.usi.dag.dislreserver.reqdispatch.RequestHandler;
import ch.usi.dag.dislreserver.shadow.NetReferenceHelper;
import ch.usi.dag.dislreserver.shadow.ShadowClass;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
import ch.usi.dag.dislreserver.shadow.ShadowThread;
public class ThreadInfoHandler implements RequestHandler {
public void handle (DataInputStream is, DataOutputStream os, boolean debug)
throws DiSLREServerException {
@Override
public void handle (
final DataInputStream is, final DataOutputStream os,
final boolean debug
) throws DiSLREServerException {
try {
long net_ref = is.readLong ();
String name = is.readUTF ();
boolean isDaemon = is.readBoolean ();
final long netReference = is.readLong ();
final String name = is.readUTF ();
final boolean isDaemon = is.readBoolean ();
ShadowClass klass = ShadowClassTable.get (
NetReferenceHelper.get_class_id (net_ref)
ShadowObjectTable.registerShadowThread (
netReference, name, isDaemon
);
ShadowThread sThread = new ShadowThread (
net_ref, name, isDaemon, klass
);
ShadowObjectTable.register (sThread, debug);
} catch (IOException e) {
} catch (final IOException e) {
throw new DiSLREServerException (e);
}
}
@Override
public void exit () {
// do nothing
}
}
......@@ -102,7 +102,7 @@ public class ShadowClassTable {
final ShadowClass exist = shadowClasses.putIfAbsent (classID, klass);
if (exist == null) {
ShadowObjectTable.register (klass, debug);
ShadowObjectTable.register (klass);
} else if (!exist.equals (klass)) {
throw new DiSLREServerFatalException ("Duplicated class ID");
......
......@@ -5,10 +5,16 @@ import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import ch.usi.dag.dislreserver.DiSLREServerFatalException;
import ch.usi.dag.dislreserver.util.Logging;
import ch.usi.dag.util.logging.Logger;
public class ShadowObjectTable {
private static final Logger __log = Logging.getPackageInstance ();
//
private static final int INITIAL_TABLE_SIZE = 10_000_000;
private static ConcurrentHashMap <Long, ShadowObject>
......@@ -16,18 +22,21 @@ public class ShadowObjectTable {
//
public static void register (final ShadowObject newObj, final boolean debug) {
public static void register (final ShadowObject newObj) {
if (newObj == null) {
throw new DiSLREServerFatalException ("Attempting to register a null as a shadow object");
__log.warn ("attempting to register a null shadow object");
return;
}
//
final long objID = newObj.getId ();
final ShadowObject exist = shadowObjects.putIfAbsent (objID, newObj);
if (exist != null) {
if (newObj.getId () == exist.getId ()) {
if (debug) {
System.out.println ("Re-register a shadow object.");
if (__log.traceIsLoggable ()) {
__log.trace ("re-registering shadow object %x", objID);
}
if (newObj.equals (exist)) {
......@@ -98,10 +107,10 @@ public class ShadowObjectTable {
ShadowObject tmp = null;
if ("java.lang.String".equals (klass.getName ())) {
tmp = new ShadowString (net_ref, null, klass);
tmp = new ShadowString (net_ref, klass);
} else if (isAssignableFromThread (klass)) {
tmp = new ShadowThread (net_ref, null, false, klass);
tmp = new ShadowThread (net_ref, klass);
} else {
tmp = new ShadowObject (net_ref, klass);
......@@ -137,4 +146,33 @@ public class ShadowObjectTable {
}
};
}
// TODO LB: Make this interface per-shadow-world instead of static.
public static void registerShadowThread (
final long netReference, final String name, final boolean isDaemon
) {
final int shadowClassId = NetReferenceHelper.get_class_id (netReference);
final ShadowClass shadowClass = ShadowClassTable.get (shadowClassId);
final ShadowThread shadowThread = new ShadowThread (
netReference, shadowClass, name, isDaemon
);
register (shadowThread);
}
public static void registerShadowString (
final long netReference, final String value
) {
final int shadowClassId = NetReferenceHelper.get_class_id (netReference);
final ShadowClass shadowClass = ShadowClassTable.get (shadowClassId);
final ShadowString shadowString = new ShadowString (
netReference, shadowClass, value
);
register (shadowString);
}
}
package ch.usi.dag.dislreserver.shadow;
import java.util.Formatter;
import java.util.concurrent.atomic.AtomicReference;
// TODO ShadowString should better handle if String data are not send
// over network - throw a runtime exception ??
public class ShadowString extends ShadowObject {
public final class ShadowString extends ShadowObject {
private String __value;
private final AtomicReference <String> __value;
//
ShadowString (
final long netReference, final ShadowClass shadowClass
) {
this (netReference, shadowClass, null);
}
public ShadowString (
final long netReference, final String value, final ShadowClass klass
ShadowString (
final long netReference, final ShadowClass shadowClass,
final String value
) {
super (netReference, klass);
__value = value;
super (netReference, shadowClass);
__value = new AtomicReference <> (value);
}
//
// TODO warn user that it will return null when the ShadowString is not yet sent.
@Override
public String toString () {
return __value;
return __value.get ();
}
void setValue (final String value) {
__value = value;
__value.updateAndGet (v -> value);
}
//
@Override
public boolean equals (final Object obj) {
......
......@@ -4,20 +4,29 @@ import java.util.Formattable;
import java.util.Formatter;
// TODO ShadowTrhead should better handle if String data are not send
// over network - throw a runtime exception ??
public class ShadowThread extends ShadowObject implements Formattable {
// TODO Make it clear that extra data have not yet been sent over the network.
//
// Consider returning an Optional (if we can distinguish that the data has
// not been set) or keep the data in a separate info class that can be swapped
// atomically.
//
public final class ShadowThread extends ShadowObject implements Formattable {
private String __name;
private boolean __isDaemon;
//
ShadowThread (final long netReference, final ShadowClass shadowClass) {
super (netReference, shadowClass);
}
public ShadowThread (
final long netReference, final String name,
final boolean isDaemon, final ShadowClass klass
ShadowThread (
final long netReference, final ShadowClass shadowClass,
final String name, final boolean isDaemon
) {
super (netReference, klass);
super (netReference, shadowClass);
__name = name;
__isDaemon = isDaemon;
......@@ -36,20 +45,22 @@ public class ShadowThread extends ShadowObject implements Formattable {
}
public void setName (final String name) {
void setName (final String name) {
__name = name;
}
public void setDaemon (final boolean isDaemon) {
void setDaemon (final boolean isDaemon) {
__isDaemon = isDaemon;
}
//
@Override
public boolean equals (final Object object) {
//
// TODO LB: Why do we need to check thread name or other fields?
// Comparing the (unique) net reference should be enough.
//
if (super.equals (object)) {
if (object instanceof ShadowThread) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment