package water;
/**
* Auto-serializer interface using a delegator pattern (the faster option is
* to byte-code gen directly in all Iced classes, but this requires all Iced
* classes go through a ClassLoader).
* <p>
* Freezable is a marker interface, and {@link Iced} is the companion marker
* class. Marked classes have 2-byte integer type associated with them, and
* an auto-genned delegate class created to actually do serialization.
* Serialization is extremely dense (includes various compressions), and
* typically memory-bandwidth bound to generate. Note that the first object implementing Freezable
* is the start of the serialization, serialization for parent objects is not going to be generated and user needs to provide
* custom serialization if that is the case.
* <p>
* H2O uses Iced classes as the primary means of moving Java Objects around
* the cluster.
* <p>
* Default serialization behavior can be override by user by implementing his own serialization methods. (NOTE:All custom serialization methods must be declared as either final or static!)
*
* If given Freezable class contains custom serialization method, it uses it instead of the default autogenerated one (i.e. no auto-serialization happens for this class!),
* however, all Freezable parents are still going to be serialized automatically.
*
* The serialization behavior for a given freezable class F can be described in following steps (here shown on serialization into bytes, other methods are analogical):
* H2O will generate F$Icer extends ((parent of F)$Icer if freezable, water.Icer otherwise).
*
* F$Icer.write( F f, Autobuffer ab) {
super.write(f,ab);
* // if F has custom serialization defined:
* return f.write_impl(ab) (or return F.write_impl(f,ab), depending on the flavor of implemented custom serialization);
* // otherwise auto serialize all non-static non-transient memebers of F and return ab
* }
*
* The default serialization behavior can be overriden for given class by implementing one of or all of following custom serialization methods:
*
* 1) override serialization into AutoBuffer provide either
*
* public final AutoBuffer write_impl(Autobuffer ab);
* or
* public static AutoBuffer write_impl(Autobuffer ab, T t);
*
* 2) to override deserialization from AutoBuffer provide either
*
* public final T read_impl(Autobuffer ab);
* or
* public static T read_impl(Autobuffer ab, T t);
*
* 3) to override serialization into JSON provide either
*
* public final AutoBuffer writeJSON_impl(Autobuffer ab);
* or
* public static AutoBuffer writeJSON_impl(Autobuffer ab, T t);
*
* 4) to override deserialization from JSON provide either*
*
* public final T readJSON_impl(Autobuffer ab);
* or
* public static T readJSON_impl(Autobuffer ab, T t);
*
* 5) override serialization into array of bytes:
* useful for Freezable directly supported by byte array (e.g. for memory efficiency reason), @see Chunk
*
* provide @Override T byte [] asBytes()
*
* 6) override de-serialization from array of bytes containing exactly the bytes containing the freezable and nothing more:
* useful for Freezable directly supported by byte array (e.g. for memory efficiency reason), @see Chunk
*
* provide @Override T reloadFromBytes(byte [] ary)
*
* </p>
* */
public interface Freezable<T extends Freezable> extends Cloneable {
/** Standard "write thyself into the AutoBuffer" call, using the fast Iced
* protocol. Real work is in the delegate {@link Icer} classes.
* @param ab <code>AutoBuffer</code> to write this object to.
* @return Returns the original {@link AutoBuffer} for flow-coding. */
AutoBuffer write(AutoBuffer ab);
/** Standard "read thyself from the AutoBuffer" call, using the fast Iced protocol. Real work
* is in the delegate {@link Icer} classes.
* @param ab <code>AutoBuffer</code> to read this object from.
* @return Returns a new instance of object reconstructed from AutoBuffer. */
T read(AutoBuffer ab);
/** Standard "write thyself into the AutoBuffer" call, using JSON. Real work
* is in the delegate {@link Icer} classes.
* @param ab <code>AutoBuffer</code> to write this object to.
* @return Returns the original {@link AutoBuffer} for flow-coding. */
AutoBuffer writeJSON(AutoBuffer ab);
/** Standard "read thyself from the AutoBuffer" call, using JSON. Real work
* is in the delegate {@link Icer} classes.
* @param ab <code>AutoBuffer</code> to read this object from.
* @return Returns an instance of object reconstructed from JSON data. */
T readJSON(AutoBuffer ab);
/** Returns a small dense integer, which is cluster-wide unique per-class.
* Useful as an array index.
* @return Small integer, unique per-type */
int frozenType();
/** Return serialized version of self as a byte array.
* Useful for Freezables directly supported by byte array (@see Chunk)
* In most cases, just use the Autobuffer version.
* @return serialized bytes */
byte [] asBytes();
/**
* Replace yourself with deserialized version from the given bytes.
* Useful for Freezables directly supported by byte array (@see Chunk).
* In most cases, just use the Autobuffer version.
* @param ary byte array containing exactly (i.e. nothing else) the serialized version of the Freezable
* @return this freshly reloaded from the given bytes.
* */
T reloadFromBytes(byte [] ary);
/** Make clone public, but without the annoying exception.
* @return Returns this object cloned. */
public T clone();
}