com.persistit.encoding.ValueCoder Maven / Gradle / Ivy
Show all versions of akiban-persistit Show documentation
/**
* Copyright © 2005-2012 Akiban Technologies, Inc. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* This program may also be available under different license terms.
* For more information, see www.akiban.com or contact [email protected].
*
* Contributors:
* Akiban Technologies, Inc.
*/
package com.persistit.encoding;
import com.persistit.Value;
import com.persistit.exception.ConversionException;
/**
*
* Interface for specialized encoding and decoding of Object
s of
* arbitrary type in a {@link Value}. Persistit contains built-in logic to
* encode objects of certain classes. For other classes, if there is no
* registered ValueCoder
, Persistit uses standard object
* serialization to generate a byte array that represents the state of that
* object in the database.
*
*
* By implementing and registering a ValueCoder
with the current
* {@link CoderManager} you can override this default encoding. Typically the
* customized encoding of an object will be much shorter than that produced by
* serialization because the customized encoding classes by their Persistit
* class handles (see {@link com.persistit.ClassIndex}) rather than their names.
* In addition, standard serialization serializes the entire graph of other
* objects that may be directly or indirectly referred to by the object being
* made persistent. This behavior may result in storing much more data than is
* required, and more importantly, may result in incorrect semantics. A
* customized ValueEncoder
can handle persistence of fields that
* refer to other objects in a manner that is semantically appropriate for the
* specific object. Note that if a class has a ValueCoder
, it can
* be stored in Persistit even if it does not implement
* java.io.Serializable
.
*
*
* A ValueCoder
implements methods to convert an object of some
* class to an array of bytes and back again. Typically the implementation of a
* ValueCoder
will simply invoke the Value
's
* put
methods to write the fields into the Value
. For
* example, the following code defines a class, and a ValueCoder
to
* store and retrieve it.
*
*
*
*
* class MyClass {
* int id;
* int anotherInt;
* String someString;
* MyClass anotherMyClass;
* }
*
* class MyClassValueCoder implements ValueCoder {
* public void put(Value value, Object object, CoderContext context) {
* MyClass mc = (MyClass) object;
* value.put(mc.id);
* value.put(mc.anotherInt);
* value.put(mc.someString);
* value.put(mc.anotherMyClass == null ? -1 : mc.anotherMyClass.id);
* }
*
* public Object get(Value value, Class clazz, CoderContext context) {
* MyClass mc = new MyClass();
* mc.id = value.getInt();
* mc.anotherInt = value.getInt();
* mc.someString = value.getString();
* mc.anotherMyClass = lookupMyClass(value.getInt());
* return mc;
* }
* }
*
*
*
*
* The application should register this ValueCoder
before
* attempting to invoke {@link Value#put(Object)} on an object of class
* MyClass
or to retrieve an object value using {@link Value#get()}
* that will resolve to a MyClass
. Generally this means that
* applications should register all ValueCoder
s and
* KeyCoder
s during application startup, immediately after invoking
* {@link com.persistit.Persistit#initialize}. For example:
*
*
* ...
* try
* {
* Persistit.initialize();
* CoderManager cm = Persistit.getInstance().getCoderManager();
* cm.registerValueCoder(new MyClassValueCoder());
* cm.registerValueCoder(new MyClassValueCoder2());
* ...
* cm.registerKeyCoder(new MyClassKeyCoder());
* ...
* }
* catch (PersistitException e)
* {
* ...
* }
*
*
*
*
*
* @version 1.0
*/
public interface ValueCoder {
/**
*
* Encodes the supplied Object
into the supplied
* Value
. This method will be called only if this
* ValueCoder
has been registered with the current
* {@link CoderManager} to encode objects having the class of the supplied
* object.
*
*
* Upon completion of this method, the backing byte array of the
* Value
and its size should be updated to reflect the
* serialized object. Use the methods {@link Value#getEncodedBytes},
* {@link Value#getEncodedSize} and {@link Value#setEncodedSize} to
* manipulate the byte array directly. More commonly, the implementation of
* this method will simply call the appropriate put
methods to
* write the interior field values into the Value
object.
*
*
* @param value
* The Value
to which the interior data of the
* supplied Object
should be encoded
* @param object
* The object value to encode. This parameter will never be
* null
because Persistit encodes nulls with a
* built-in encoding.
* @param context
* An arbitrary object that can optionally be supplied by the
* application to convey an application-specific context for the
* operation. (See {@link CoderContext}.) The default value is
* null
.
*/
public void put(Value value, Object object, CoderContext context) throws ConversionException;
/**
*
* Creates an instance of the supplied class, populates its state by
* decoding the supplied Value
, and returns it. This method
* will be called only if this ValueCoder
has been registered
* with the current {@link CoderManager} to encode objects having supplied
* Class
value. Persistit will never call this method to decode
* a value that was null
when written because null values are
* handled by built-in encoding logic.
*
*
* @param value
* The Value
from which interior fields of the
* object are to be retrieved
* @param clazz
* The class of the object to be returned.
* @param context
* An arbitrary object that can optionally be supplied by the
* application to convey an application-specific context for the
* operation. (See {@link CoderContext}.) The default value is
* null
.
* @return An Object
having the same class as the suppled
* clazz
parameter.
* @throws ConversionException
*/
public Object get(Value value, Class> clazz, CoderContext context) throws ConversionException;
}