com.neeve.sto
Class StoFieldContainer

java.lang.Object
  extended by com.neeve.sto.StoFieldContainer
All Implemented Interfaces:
Cloneable

public class StoFieldContainer
extends Object
implements Cloneable

An ordered container of STO fields.

Threading:
STO field containers are not safe for concurrent access by multiple threads.

An STO field container supports the ability to lay out STO fields in a container in an ordered manner. The container preserves the order in which the fields are laid out as well as maintains a map of fields keyed by field name for those fields that have non-null names. Operations supported by the container include field append (append(com.neeve.sto.StoField)), field iteration (first(),next()), getting field by position (get(int)) and getting field by name (get(String)).

A field container can be backed by a buffer. A container's backing buffer is used to hold the serialized for of the container i.e. the serialized form of each of the fields in the container. To associate a backing buffer with a container, the user can either directly associate the container with a buffer (setBackingBuffer(com.neeve.sto.StoField)) or associate a buffer manager (setBackingBufferManager(com.neeve.sto.IStoBufferManager)) with the container. The difference between the two is the, in the latter case, the container will use the buffer manager to resize the backing buffer in case the buffer is too small to accomodate the serialized container. In the former case (backing the container directly with a buffer), an exception is thrown whenever the container encounters that its backing buffer is too small for its contents. Setting a buffer manager will automatically set the backing buffer if not already set. Also, the backing buffer and/or the buffer manager can be associated/disassociated from a container at any time during the life of the container i.e. before or after fields are added to the container and before or after field values have been assigned.

The container marks the its first variable length field as the 'late sync boundary' (or null if all fields are fixed length). Fields before a container's late sync boundary are synced to the container's backing buffer in real time i.e. reading and writing of field values are performed directly from the container's backing buffer. Fields at or after the late sync boundary are serialized to the backing buffer only during sync i.e. when sync(com.neeve.sto.StoField) is invoked i.e. sync(com.neeve.sto.StoField) is the container's serialization method (throws exception if the container is not associated with a backing buffer)

Field container's can be re-instantiated from its serialized form using the create(ByteBuffer) method.

Typical usage of a container is as follows:

// create field container
StoFieldContainer container1 = StoFieldContainer.create();

// set backing buffer
container1.setBackingBufferManager(StoBufferManager.create());
OR
container1.setBackingBuffer(ByteBuffer.allocate(1024));

// the choice above depends on whether the user wants dynamic
// resizing of the backing buffer or not

// Append fields to the container.
//
// Note: The backing buffer can be set after appending fields too.
StoIntField field1 = StoIntField.create(null); // fixed, no name
StoStringField field2 = StoStringField.create("field2"); // variable, with name
.
.
.

// Set fields values
field1.setValue(42);
field2.setValue("yooohaaah!");
.
.
.

// Sync the container to the backing buffer.
container1.sync();


// Deserialize the buffer into a new container.
final StoFieldContainer container2 = StoFieldContainer.create(container1.getBackingBuffer());
.
.
.
// Iterate through the fields
System.out.println("Field 1 (int) = " + ((StoIntField)container2.first()).getValue());
System.out.println("Field 2 (string) = " + ((StoStringField)container2.next()).getValue());

// or, we can access fields by name
System.out.println("Field 2 (string) = " + ((StoStringField)container2.get("field2")).getValue());

// or, we can access fields by position (1 based)
System.out.println("Field 1 (int) = " + ((StoIntField)container2.get(1)).getValue());
.
.
.


Method Summary
 StoFieldContainer append(StoField field)
          Append a field to a container.
 StoFieldContainer changeBackingBuffer(ByteBuffer buffer)
          Change a container's backing buffer.
 StoFieldContainer clearBackingBuffer()
          Clear a container's backing buffer.
 StoFieldContainer clearBackingBufferManager()
          Clear a container's backing buffer manager.
 Object clone()
          Clone an STO field container.
 boolean contentsEquals(StoFieldContainer other)
          Get if a container object is equal to another object.
 int count()
          Get the number of fields in a field container
static StoFieldContainer create()
          Create an empty STO field container.
static StoFieldContainer create(ByteBuffer buffer)
          Create an STO field container from its serialized form.
static StoFieldContainer create(ByteBuffer buffer, boolean attach)
          Create an STO field container from its serialized form.
 StoField first()
          Get the first field in a field container.
 StoField get(int pos)
          Get a field by position (one based).
 StoField get(String name)
          Get a field by name.
 ByteBuffer getBackingBuffer()
          Get a container's backing buffer.
 IStoBufferManager getBackingBufferManager()
          Get a container's backing buffer manager.
static int getFieldOffset(ByteBuffer buffer, int pos)
          Get the offset of a field in a serialized container.
 StoField getLateSyncBoundary()
          Get a container's late sync boundary field.
 int getLateSyncBoundaryMark()
          Get a container's late sync boundary mark.
 int getSerializedLength()
          Get the serialized length of a container
 short getTypeFactoryId()
          Get the container's factory.
 short getTypeId()
          Get the type id of a container within its factory.
 boolean isVariableLength()
          Get whether a container is a fixed or variable length container.
 StoField next()
          Get next field in a field container.
 void reset()
          Reset the contents of a field container.
 StoFieldContainer setBackingBuffer(ByteBuffer buffer)
          Set a container's backing buffer.
 StoFieldContainer setBackingBuffer(ByteBuffer buffer, boolean suppressClear)
          Set a container's backing buffer.
 StoFieldContainer setBackingBufferManager(IStoBufferManager bufferManager)
          Set a container's backing buffer manager.
 StoFieldContainer sync()
          Sync a container's late sync fields to the container's backing buffer.
 StoFieldContainer sync(ByteBuffer buffer, int offset)
          Sync a container's fields to a buffer.
 String toString()
          Get a string representation of a field container.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Method Detail

getTypeFactoryId

public short getTypeFactoryId()
Get the container's factory.

This method pertains to user compound types. User compund types are classes that extend an STO field container using the field container as the container for the field contents. Each user compound type is uniquely associated with a type factory and is uniquely identified within the factory by a type id. This method returns the system wide unique id of a compound type's factory.

This method returns 0 by default. This signifies that the container is behaves as a standalon container and not as a base class for a user compound type. The compound type class should override this method and return its factory id.


getTypeId

public short getTypeId()
Get the type id of a container within its factory.

This method pertains to user compound types. See getTypeFactoryId() for more information on user compound types.

This method is only pertinent if getTypeFactoryId() returns a positive value.


create

public static StoFieldContainer create()
Create an empty STO field container.


create

public static StoFieldContainer create(ByteBuffer buffer,
                                       boolean attach)
Create an STO field container from its serialized form.

Parameters:
buffer - The buffer containing the serialized container.
attach - Indicates if the supplied buffer is to be kept attached to the container post deserialization. If kept attached, then the container can optimize performance by leaving field contents in the buffer and only deserialize from the buffer on demand.

create

public static StoFieldContainer create(ByteBuffer buffer)
Create an STO field container from its serialized form.

This method invokes the following:
create(buffer, true)

Note: This method will attach the supplied buffer to the container post deserialization. Therefore, the user should consider the buffer to be owned by the container post return from this call.


getFieldOffset

public static int getFieldOffset(ByteBuffer buffer,
                                 int pos)
Get the offset of a field in a serialized container.

Parameters:
buffer - The buffer containing the serialized container.
pos - The field's position in the container i.e. the argument supplied to get(int) to retrieve the field.
Returns:
Returns the absolute offset in the supplied buffer where the serialied body of a field starts. The returned offset can be supplied directly to the fields static get(ByteBuffer, int) method to get the field's value. A return value of -1 indicates that the specified position is invalid i.e. it is less than 0 or greater than the number of fields in the (serialized) container.

setBackingBufferManager

public final StoFieldContainer setBackingBufferManager(IStoBufferManager bufferManager)
Set a container's backing buffer manager.

Parameters:
bufferManager - The new buffer manager.

This method sets the supplied buffer manager as the container's backing buffer manager. If the container is not already attached to a backing buffer, this method allocates a new buffer using the new buffer manager and invokes setBackingBuffer(com.neeve.sto.StoField) to set it as the container's backing buffer.


getBackingBufferManager

public final IStoBufferManager getBackingBufferManager()
Get a container's backing buffer manager.

Returns:
Returns the container's backing buffer manager. A value of null indicates that the container does not have a buffer manager installed.

clearBackingBufferManager

public final StoFieldContainer clearBackingBufferManager()
Clear a container's backing buffer manager.

Invoking this method is equivalent to invoking setBackingBufferManager(null) .


setBackingBuffer

public final StoFieldContainer setBackingBuffer(ByteBuffer buffer,
                                                boolean suppressClear)
                                         throws EStoInsufficientSpaceException
Set a container's backing buffer.

Parameters:
buffer - The container's new backing buffer. A value of null just clears the existing backing buffer (if any). The act of clearing a backing buffer preserves field contents by sync'ing field contents from the buffer being cleared to field private member variables.
suppressClear - Specifies that the method should suppress clearing of any existing backing buffer before setting the new backing buffer. The user should use this option with caution since the suppression of buffer clearing may cause field values stored directly in the buffer to be lost when the new buffer is installed.
Throws:
EStoInsufficientSpaceException - Thrown if no buffer manager has been installed on the container and the supplied buffer capacity is less that the cumulative serialized length of all fields before but excluding the late sync boundary fields.

This method sets a container's backing buffer. Unless suppressed via the suppressClear parameter, tThis method first clears the existing backing buffer if any (the act of clearing a backing buffer preserves existing field contents by syncing the field contents from the buffer being cleared to field member variables). If the supplied buffer is non-null, the method then sets the supplied buffer as the container's backing buffer and sync's the existing fields upto but excluding the late sync boundary field to the new buffer.

Note: The preferred mechanism to set a container's backing buffer is to install a buffer manager via setBackingBufferManager(com.neeve.sto.IStoBufferManager). The setBackingBufferManager(com.neeve.sto.IStoBufferManager) method will implicitly call this method if no backing buffer is attached to the container at the time the method is invoked. Installing a buffer manager enables the container to dynamically reallocate backing buffers as and when fields are appended to the container. Using this method to set a container's backing buffer without installing a buffer manager does not allow dynamic growth of backing buffers.


setBackingBuffer

public final StoFieldContainer setBackingBuffer(ByteBuffer buffer)
                                         throws EStoInsufficientSpaceException
Set a container's backing buffer.

This method invokes setBackingBuffer(buffer, false)

Throws:
EStoInsufficientSpaceException
See Also:
setBackingBuffer(ByteBuffer, boolean)

changeBackingBuffer

public final StoFieldContainer changeBackingBuffer(ByteBuffer buffer)
                                            throws EStoFieldCorruptException
Change a container's backing buffer.

Parameters:
buffer - The buffer to set.
Throws:
EStoFieldCorruptException - Thrown in case the field layout in the buffer is not identical to that in the container.

This method replaces any existing buffer backing a container with a new buffer containing a serialized set of fields identical to what is in the container. The field values before the replacement are discarded and refreshed with values serialized in the backing buffer. The method retains the supplied buffer as the container's backing buffer.

This method is the opposite of setBackingBuffer(ByteBuffer) in that this method treats the contents of the buffer to be more valid than the in-memory values held by the fields. setBackingBuffer(ByteBuffer) treats the contents of the fields in-memory values to be more valid and overwrites the contents of the set backing buffer.


getBackingBuffer

public final ByteBuffer getBackingBuffer()
Get a container's backing buffer.

Returns:
Returns a container's currently set backing buffer.

clearBackingBuffer

public final StoFieldContainer clearBackingBuffer()
Clear a container's backing buffer.

Invoking this method is equivalent to invoking setBackingBuffer(null) .


append

public final StoFieldContainer append(StoField field)
                               throws EStoFieldAlreadyPresentException
Append a field to a container.

Throws:
EStoInsufficientSpaceException - Thrown in case a buffer manager is not installed on the container and there is not enough space in the container's current backing buffer to accommodate the new field. This exception does not mean that the field has not been accepted by the container. It only means that the existing backing buffer, if any, is not large enough to hold the serialized container. The insufficient backing buffer is cleared from the container before the exception is thrown.

This method appends a field to a field container. The fields backing buffer is dynamically grown to accomodate the new field only if the container is attached to a backing buffer too small to hold the additional field and a buffer manager is installed at the time this method is invoked. If the field being appended is the first variable length field in the container, it is marked as the late sync boundary field. If field is at or beyond the container's late sync boundary, then the field is not sync'd to the container's backing buffer (if one is set at the time this method is invoked) i.e. the field is sync'd to the container's backing buffer if and only if the late sync boundary field is not set at the time this field is appended and this field is not set as the late sync boundary field.

EStoFieldAlreadyPresentException

get

public final StoField get(String name)
Get a field by name.

Returns:
The named field or null in case no field of supplied name exists.

get

public final StoField get(int pos)
Get a field by position (one based).

Returns:
The field at requested position or null in case no field at the requested position exists.

getLateSyncBoundary

public final StoField getLateSyncBoundary()
Get a container's late sync boundary field.

Returns:
This method returns the container's late sync boundary field. A null return value indicates that all of the container's fields are sync'd in real time to the container's backing buffer.

A container's late sync boundary field is the first field whose contents are not backed in real time by the container's backing buffer. Changes to fields at or beyond the late sync boundary are reflected in field private member variables an only sync'd to the container's backing buffer on sync(com.neeve.sto.StoField).


getLateSyncBoundaryMark

public final int getLateSyncBoundaryMark()
Get a container's late sync boundary mark.

Returns:
Returns the container's late sync boundary mark. A value of 0 indicates that either the container's backing buffer has not been set or is the first field in the container. If the late sync boundary is null, then the return value from this method marks the end of the container serialized in the backing buffer.

A container's late sync boundary mark is the position in the container's backing buffer that marks the end of the last serialized field before the late sync boundary field.


isVariableLength

public final boolean isVariableLength()
Get whether a container is a fixed or variable length container.

This method returns true if and only if atleast one of the fields contained by the container is a variable length field.


first

public final StoField first()
Get the first field in a field container.

Returns:
The first field or null in case the list is empty

This method resets the field container's field iterator and returns the first field in the container. To iterator through the container's field list, the user should first invoke this method and then invoke next() repreatedly until it returns null (indicating end of field list).


next

public final StoField next()
Get next field in a field container.

Returns:
The next field or null in case the end of the field list has been reached.

count

public final int count()
Get the number of fields in a field container


getSerializedLength

public final int getSerializedLength()
Get the serialized length of a container


reset

public final void reset()
Reset the contents of a field container.

This method resets the contents of a field container. Upon return from this method, the contents of the container are the same as a freshly created container with its fields reset but left intact. If the container is backed by a buffer, then the field contents in the buffer are also reset.


sync

public final StoFieldContainer sync()
                             throws EStoInsufficientSpaceException
Sync a container's late sync fields to the container's backing buffer.

Throws:
EStoInsufficientSpaceException - Thrown if a buffer manager has not been installed on the container and the current backing buffer does not have enough space to serialize all fields in the container. This method does not clear the backing buffer from the container if this exception is thrown.

This method syncs all container fields at or after the late sync boundary field to the container's backing buffer. The backing buffer is dynamically grown to accomodate the fields if a buffer manager is installed on the container.


sync

public final StoFieldContainer sync(ByteBuffer buffer,
                                    int offset)
                             throws EStoInsufficientSpaceException
Sync a container's fields to a buffer.

Throws:
IllegalStateException - Thrown if the container is attached to a backing buffer.
EStoInsufficientSpaceException - Thrown if the specified buffer does not have enough space to serialize all fields in the container.

This method syncs all container fields the specified buffer. An exception is thrown if there is not enough space in the buffer to accomodate the serialized container.

Upon return from this method, the buffer position mark is position to the end of the serialized container i.e. buffer.position()-offset is the serialized length of the container.


contentsEquals

public final boolean contentsEquals(StoFieldContainer other)
Get if a container object is equal to another object.

This method returns true if and only if the object being compared against is also a field container, contains the same number of fields and the fields in both containers are identical.


clone

public Object clone()
Clone an STO field container.

This method clones the contents of a field container. The cloned object has the same number, type and value of fields as the original object. However, the cloned object is not backed by a buffer or buffer manager.

Overrides:
clone in class Object

toString

public String toString()
Get a string representation of a field container.

Overrides:
toString in class Object


Copyright © 2015 Neeve Research, LLC. All Rights Reserved.