at.spardat.xma.mdl.util.TransAtomTable Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* 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
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: TransAtomTable.java 2089 2007-11-28 13:56:13Z s3460 $
package at.spardat.xma.mdl.util;
import java.io.IOException;
import java.util.ArrayList;
import at.spardat.xma.mdl.*;
import at.spardat.xma.mdl.Atom;
import at.spardat.xma.mdl.Transactional;
import at.spardat.xma.serializer.XmaInput;
import at.spardat.xma.serializer.XmaOutput;
/**
* Manages a two dimensional arrays of Atom objects. Each row is
* uniquely identified by a String-key. No two rows may have the same key.
* Besides accessing rows by a zero-based row index, rows may be accessed
* using the key.
*
* Rows are specified using arrays of Atoms. Whereever a Atom array is provided
* as method parameter (e.g., adding a row), a copy of the array is stored internally. So
* the caller may freely reuse the array.
*
* This class relies on the fact that class Atom is immutable. Making
* Atom non immutable would break this class.
*
* Columns are specified with zero-based column indexes. The number of columns
* a table has is specified at construction time.
*
* A TransAtomTable supports transactional behaviour, so its changes
* made since the last syncpoint (construction, commit, rollback) may be undone.
* To support this, the syncpoint state is saved if modifications are done.
* The modifications themselves are also kept in a list up to a point where
* the size of the changes approaches the size of the table. In this case,
* changes are discarded which effects serialization.
*
* Serialization is supported (methods externalize and internalize).
* The caller may choose to externalize deltas or the complete state. This
* class internally decides up to which point changes are tracked based on heuristics
* (actually if the cumulated serialized size of changes approaches the serialized
* size of the complete state). Thus the caller merely may express its wish that changes
* should be externalized.
*
* @author YSD, 13.04.2003 09:26:44
*/
public class TransAtomTable implements Transactional, Synchronization, Descriptive {
/**
* Constructor.
*
* @param numCols number of columns in this table.
*/
public TransAtomTable (int numCols) {
numCols_ = numCols;
}
/**
* @see at.spardat.xma.mdl.Transactional#changed()
*/
public boolean changed() {
return saved_ != null;
}
/**
* @see at.spardat.xma.mdl.Transactional#rollback()
*/
public void rollback() {
if (changed()) {
data_ = saved_;
streamedTableSize_ = streamedSize();
changes_ = null;
streamedChangesSize_ = 0;
saved_ = null;
}
}
/**
* @see at.spardat.xma.mdl.Transactional#commit()
*/
public void commit() {
if (changed()) {
saved_ = null;
changes_ = null;
streamedChangesSize_ = 0;
}
}
/**
* Returns the number of rows in this
*/
public int size () {
return data_.size();
}
/**
* Returns an Atom by providing row and column indexes.
*
* @param rowIndex the index of the row
* @param colIndex the index of the column
* @return the retrieved Atom
* @exception ArrayIndexOutOfBoundsException if a provided index is invalid
*/
public Atom get (int rowIndex, int colIndex) {
Atom [] row = (Atom[]) data_.getValue(rowIndex);
return row[colIndex];
}
/**
* Returns an Atom by providing a row key and a column index.
*
* @param key the key of the row
* @param colIndex the index of the columns
* @return the retrieved Atom or null if this table has no row
* with the provided key.
* @exception ArrayIndexOutOfBoundsException if colIndex is invalid.
*/
public Atom get (String key, int colIndex) {
Atom [] row = (Atom[]) data_.getValue(key);
return row[colIndex];
}
/**
* Returns a copy of the Atom array for a particular key or null,
* if this has no row with the provided key.
*
* @param key of the wanted row
* @return null, if key not found, copied Atom [] otherwise.
*/
public Atom [] getAtoms (String key) {
Atom [] atoms = (Atom[]) data_.getValue(key);
if (atoms == null) return null;
Atom [] copy = new Atom[atoms.length];
System.arraycopy(atoms, 0, copy, 0, atoms.length);
return copy;
}
/**
* Returns the index of the row whose key equals the one provided.
*
* This is a time consuming operation of O(n).
*
* @param key the key of the entry whose row is wanted.
* @return the index of the found entry or -1 if the key is not
* in the table.
*/
public int indexOf (String key) {
return data_.indexOf(key);
}
/**
* Returns the key at a provided row index.
*
* @exception ArrayIndexOutOfBoundsException if index out of range.
*/
public String getKey (int rowIndex) {
return data_.getKey(rowIndex);
}
/**
* Adds a row to this at a provided index.
*
* @param rowIndex the index at which the row should be added. Must
* lie in the range [0, size()].
* @param key the key of the newly inserted row
* @param atoms an array of Atoms.
* @return true if added, false if this already contains a row with the
* provided key and the row was not added.
* @exception IllegalArgumentException if rowIndex out of range
* or the length of atoms is unequal to the number
* of columns provided at construction time.
*/
public boolean add (int rowIndex, String key, Atom [] atoms) {
if (data_.containsKey(key)) return false;
if (atoms.length != numCols_) throw new IllegalArgumentException();
if (rowIndex < 0 || rowIndex > data_.size()) throw new IllegalArgumentException();
return handle (new AddRowChangeEvent (key, rowIndex, atoms));
}
/**
* Adds a row at the end of this.
*
* @param key the key of the newly inserted row
* @param atoms an array of Atoms.
* @return true if added, false if this already contains a row with the
* provided key
* @exception IllegalArgumentException if the length of atoms
* is unequal to the number
* of columns provided at construction time.
*/
public boolean add (String key, Atom [] atoms) {
return add (size(), key, atoms);
}
/**
* Removes a row for a given key from this. This operation is of O(n).
*
* @param key the key whose row should be removed
* @return true if this has contained a row with the given key, false
* otherwise
*/
public boolean remove (String key) {
int index = data_.indexOf(key);
if (index == -1) return false;
remove (index);
return true;
}
/**
* Removes a row for at a given index from this. This operation is of O(n).
*
* @param index the index of the row that should be removed.
* @exception ArrayIndexOutOfBoundsException if index out of range
*/
public void remove (int index) {
if (index < 0 || index >= size()) throw new ArrayIndexOutOfBoundsException();
if (!handle (new RemoveRowChangeEvent(index))) throw new InternalError();
}
/**
* Replaces a row at a given index.
*
* @param index the index at which the row is to be replaced.
* @param row the new row
* @exception ArrayIndexOutOfBoundsException if index is out of bounds.
* @exception IllegalArgumentException if the length of atoms is unequal to the number
* of columns provided at construction time.
*
*/
public void replace (int index, Atom[] row) {
if (index < 0 || index >= size()) throw new ArrayIndexOutOfBoundsException();
if (row == null || row.length != numCols_) throw new IllegalArgumentException();
if (!handle (new ReplaceRowChangeEvent(index, row))) throw new InternalError();
}
/**
* Replaces a particular cell in the table.
*
* @param rowIndex the row index at which the new cell is to be replaced
* @param colIndex the column index of the cell
* @param cell the new Atom
* @exception ArrayIndexOutOfBoundsException if rowIndex or colIndex
* are out of bounds.
*/
public void replace (int rowIndex, int colIndex, Atom cell) {
if (rowIndex < 0 || rowIndex >= size()) throw new ArrayIndexOutOfBoundsException();
if (colIndex < 0 || colIndex >= numCols_) throw new ArrayIndexOutOfBoundsException();
if (!handle (new ReplaceAtomChangeEvent(rowIndex, colIndex, cell))) throw new InternalError();
}
/**
* Returns true if this table contains a row with the provided key.
*/
public boolean containsKey (String key) {
return data_.containsKey(key);
}
/**
* Removes all rows from this.
*/
public void clear () {
if (!handle (new ClearEvent())) throw new InternalError();
}
/**
* Externalizing this either serializes the actual state of this or the accumulated
* changes. The default behaviour is to serialize the changes if changes are beeing
* tracked. This behaviour may be overwritten by
* ignoreDeltas. If true, changes are never written.
*
* @param xo the serialization destination
* @param ignoreDeltas if true, the actual state of this (all rows) is written
* and deltas are ignored.
* @throws IOException on serialization errors
*/
public void externalize (XmaOutput xo, boolean ignoreDeltas) throws IOException {
if (changes_ != null && !ignoreDeltas) {
// output a byte indicating that changes are following
xo.writeBoolean ("deltas", true);
// output the changes
externalizeChanges (changes_, xo);
} else {
// output a byte indicating that no changes are following
xo.writeBoolean ("deltas", false);
// output all rows of the table
externalizeRows (data_, xo);
}
}
/**
* Updates the state of this with information of the given XmaInput. Before
* doing this, the changes in this are committed (i.e., history is discarded).
* Then, if in contains changes, they are read and applied to the
* preexisting state. Otherwise, all rows are replaced with the rows
* from in.
*
* In either case, the state after calling internalize is !changed().
*
* @param in the XmaInput.
* @throws IOException on serialization errors
* @throws ClassNotFoundException on serialization errors
*/
public void internalize (XmaInput in) throws IOException, ClassNotFoundException {
commit();
boolean deltas = in.readBoolean();
if (deltas) {
// set of changes
ArrayList changes = internalizeChanges(in);
for (int i=0; iev has been executed
*/
private boolean handle (TableChangeEvent ev) {
// make a copy of data_ if not copied yet
boolean firstModification = false; // first modification since last syncpoint?
if (saved_ == null) {
saved_ = (KeyedList) data_.clone();
firstModification = true;
}
// execute the event
boolean success = ev.execute();
if (!success && firstModification) {
saved_ = null;
}
if (!success) return false;
// if this has been the first modification, decide if changes should be tracked
if (firstModification) {
if (streamedTableSize_ > 50) {
// start change tracking if there are at least 50 bytes in the table (heuristics)
changes_ = new ArrayList();
streamedChangesSize_ = 0;
}
}
// if change tracking is on (changes_ != null), add the change to the list of changes
if (changes_ != null) {
changes_.add(ev);
streamedChangesSize_ += ev.streamedSize();
// decide if change tracking should be stopped because the cumulated size of
// the changes reaches some fraction of the cumulated size of the table.
if (streamedChangesSize_ > streamedTableSize_ * MAX_STREAMED_CHANGES_RATIO) {
// drop change list
changes_ = null;
streamedChangesSize_ = 0;
}
}
return success;
}
/**
* Returns the length of a byte array resulting from streaming an Atom[]
*
* @param arr the array whose streamed size is requested.
*/
private static int streamedSizeOfAtomArray (Atom [] arr) {
int length = 0;
for (int i=arr.length-1; i>=0; i--) {
length += Atom.streamedSize(arr[i]);
}
return length;
}
/**
* Returns an estimator on how much bytes a provided row consumes when
* serialized.
*
* @param key the key of the row
* @param arr the Atom array of the row
* @return number of bytes to serialize the provided row
*/
private static int streamedSizeOfRow (String key, Atom [] arr) {
return 2 + key.length() + streamedSizeOfAtomArray(arr);
}
/**
* Returns the cumulated streamed size over all rows in this table.
*/
private int streamedSize () {
int streamedSize = 0;
for (int i=data_.size()-1; i>=0; i--) {
streamedSize += streamedSizeOfRow (data_.getKey(i), (Atom[])data_.getValue(i));
}
return streamedSize;
}
/**
* Copies an Atom array and returns the copy.
*
* @param atomsIn the array to copy
* @return the copy
*/
private static Atom [] copyAtoms (Atom [] atomsIn) {
Atom [] atoms = new Atom[atomsIn.length];
System.arraycopy(atomsIn, 0, atoms, 0, atomsIn.length);
return atoms;
}
/**
* Externalizes an Atom array
*
* @param atoms the array to externalize
* @param xo the XMA wrapper around ObjectOutput
* @throws IOException on serialization errors
*/
private void externalizeAtoms (Atom[] atoms, XmaOutput xo) throws IOException {
xo.writeShort("numAtoms", atoms.length);
for (int i=0; iXmaInput.
*
* @param xi the input stream
* @return newly created ArrayList with newly created TableChangeEvents. Returned
* ArrayList is never null.
* @throws IOException on serialization errors
* @throws ClassNotFoundException on serialization errors
*/
private ArrayList internalizeChanges (XmaInput xi) throws IOException, ClassNotFoundException {
// read the number of changes
int numChanges = xi.readInt();
ArrayList changes = new ArrayList(numChanges);
for (int i=0; irows to the serialization destination xo.
*
* @param rows KeyedList which holds the rows to write.
* @param xo the output destination
* @throws IOException on serialization errors
*/
private void externalizeRows (KeyedList rows, XmaOutput o) throws IOException {
int numRows = rows.size();
// write size
o.writeInt("numRows", numRows);
// the rows themselves
for (int i=0; idata_ is streamed.
*/
private int streamedTableSize_;
/**
* Indicates if streamedTableSize_ should be updated on every change event.
*/
private boolean updateStreamedSize_ = true;
/**
* Holds a saved copy of data_ if changed() is true.
*/
private KeyedList saved_;
/**
* Keeps track of changes (TableChangeEvents) applied to this since the last
* synchronization point (construction, commit, rollback). If there has
* been no change yet (saved_ == null), then changes_ also is null.
* If saved_ != null, changes_ may either be null or not. If changes_ == null,
* the change list has been dropped because is has grown to large
* in relation to data_. If changes_ != 0, changes must be stored in this
* instance variable until the cumulated streamed size of the changes exceeds
* some fraction of the streamed size of data_. Thereafter it may be dropped.
*/
private ArrayList changes_;
/**
* The cumulated streamed size of all changes in changes_.
*/
private int streamedChangesSize_;
/**
* When the cumulated streamed size of the changes exceeds the cumulated
* streamed size of the table multiplied with this fraction, the
* change list is dropped because serializing the complete table
* requires not much more space than serializing the deltas and it's of
* no use to further track deltas (which would consume memory).
*/
private static final double MAX_STREAMED_CHANGES_RATIO = 0.7;
private static final byte T_ADDROW_EVT = 0;
private static final byte T_REMOVEROW_EVT = 1;
private static final byte T_REPLACEATOM_EVT = 2;
private static final byte T_REPLACEROW_EVT = 3;
private static final byte T_CLEAR_EVT = 4;
/**
* Factory method for events used when internalizing events from a stream
*
* @param type one of the T_* codes defined above
* @return newly contructed TableChangeEvent; internalize must be called
* later on the returned instance.
*/
private TableChangeEvent createEvent (byte type) {
switch (type) {
case T_ADDROW_EVT: return new AddRowChangeEvent();
case T_REMOVEROW_EVT: return new RemoveRowChangeEvent();
case T_REPLACEATOM_EVT: return new ReplaceAtomChangeEvent();
case T_REPLACEROW_EVT: return new ReplaceRowChangeEvent();
case T_CLEAR_EVT: return new ClearEvent();
default: return null;
}
}
/**
* Base class for change events on TransAtomTables. The execute methods of the subclasses
* may only modify the instance variable data_ and must not perform
* any error checking on the provided arguments. Furthermore, the instance
* streamedTableSize_, which holds an estimator of the byte size of the table,
* must be kept up to date if updateStreamedSize_ is true.
*
* @author YSD, 13.04.2003 22:35:59
*/
public abstract class TableChangeEvent implements Descriptive {
/**
* Executes this change event and modifies the table. This condition holds for all events
* subclassed from this: There is no need to perform error checking on arguments
* because this is done by the caller of execute.
*
* @return true if modification has been done, false otherwise. If false is returned,
* this should be considered as severe programming error.
*/
public abstract boolean execute ();
/**
* Returns a type indicator used in serialization
*/
public abstract byte getType ();
/**
* Returns the number of bytes this event requires when streamed to a byte array
*/
public abstract int streamedSize ();
/**
* Reads the instance variables from an input stream
*/
public abstract void internalize (XmaInput in) throws IOException, ClassNotFoundException;
/**
* Writes the state to an output stream
*/
public abstract void externalize (XmaOutput out) throws IOException;
/**
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
n.appShortClass(this).app(": ");
n.app("streamedSize", streamedSize());
}
}
/**
* Adds a row to the table
*
* @author YSD, 13.04.2003 22:29:54
*/
public final class AddRowChangeEvent extends TableChangeEvent {
/**
* May only be used to call internalize thereafter.
*/
public AddRowChangeEvent () {
}
/**
* Constructor
*/
public AddRowChangeEvent (String key, int index, Atom [] atoms) {
key_ = key;
index_ = index;
atoms_ = copyAtoms (atoms);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#execute()
*/
public boolean execute() {
if (updateStreamedSize_) streamedTableSize_ += streamedSizeOfRow(key_, atoms_);
return data_.add(index_, key_, atoms_);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#getType()
*/
public byte getType() {
return T_ADDROW_EVT;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#streamedSize()
*/
public int streamedSize() {
return 1 + // type
2 + key_.length() + // key_
4 + //index
streamedSizeOfAtomArray(atoms_);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#externalize(at.spardat.xma.serializer.XmaOutput)
*/
public void externalize(XmaOutput out) throws IOException {
out.writeString("key", key_);
out.writeInt("index", index_);
externalizeAtoms(atoms_, out);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize(XmaInput in) throws IOException, ClassNotFoundException {
key_ = in.readString();
index_ = in.readInt();
atoms_ = internalizeAtoms(in);
}
/**
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
super.describe(n); n.comma();
n.app("index", index_).comma();
n.app("key", key_).comma();
n.app("atoms: "); describeAtomArray(n, atoms_);
}
private String key_;
private int index_;
private Atom [] atoms_;
}
/**
* Removes a row at a given index from this. This is of time consuming O(n).
*
* @author YSD, 14.04.2003 09:43:51
*/
public final class RemoveRowChangeEvent extends TableChangeEvent {
/**
* May only be used to call internalize thereafter.
*/
public RemoveRowChangeEvent () {
}
/**
* Constructor
*
* @param index the index of the row to delete
*/
public RemoveRowChangeEvent (int index) {
index_ = index;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#execute()
*/
public boolean execute() {
if (updateStreamedSize_) {
String key = data_.getKey(index_);
Atom [] row = (Atom[]) data_.getValue(index_);
streamedTableSize_ -= streamedSizeOfRow(key, row);
}
data_.remove(index_);
return true;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#getType()
*/
public byte getType() {
return T_REMOVEROW_EVT;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#streamedSize()
*/
public int streamedSize() {
return 1 + // type
4; //index
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#externalize(at.spardat.xma.serializer.XmaOutput)
*/
public void externalize(XmaOutput out) throws IOException {
out.writeInt("index", index_);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize(XmaInput in) throws IOException, ClassNotFoundException {
index_ = in.readInt();
}
/**
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
super.describe(n); n.comma();
n.app("index", index_);
}
private int index_;
}
/**
* Replaces a row at a given index with a new row.
*
* @author YSD, 14.04.2003 09:59:31
*/
public final class ReplaceRowChangeEvent extends TableChangeEvent {
/**
* May only be used to call internalize thereafter.
*/
public ReplaceRowChangeEvent () {
}
/**
* Constructor
*/
public ReplaceRowChangeEvent (int index, Atom [] row) {
index_ = index;
newRow_ = copyAtoms(row);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#execute()
*/
public boolean execute() {
String key = data_.getKey(index_);
if (updateStreamedSize_) {
streamedTableSize_ -= streamedSizeOfAtomArray((Atom[]) data_.getValue(index_));
streamedTableSize_ += streamedSizeOfAtomArray(newRow_);
}
data_.replace(key, newRow_);
return true;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#getType()
*/
public byte getType() {
return T_REPLACEROW_EVT;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#streamedSize()
*/
public int streamedSize() {
return 1 + // type
4 + //index
streamedSizeOfAtomArray(newRow_);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#externalize(at.spardat.xma.serializer.XmaOutput)
*/
public void externalize(XmaOutput out) throws IOException {
out.writeInt("index", index_);
externalizeAtoms(newRow_, out);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize(XmaInput in) throws IOException, ClassNotFoundException {
index_ = in.readInt();
newRow_ = internalizeAtoms(in);
}
/**
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
super.describe(n); n.comma();
n.app("index", index_).comma();
n.app("newRow: "); describeAtomArray(n, newRow_);
}
private int index_;
private Atom [] newRow_;
}
/**
* Replaces an Atom (table cell) in the table.
*
* @author YSD, 14.04.2003 09:59:31
*/
public final class ReplaceAtomChangeEvent extends TableChangeEvent {
/**
* May only be used to call internalize thereafter.
*/
public ReplaceAtomChangeEvent () {
}
/**
* Constructor
*
* @param rowIndex the index of the row
* @param colIndex the index of the column
* @param atom the new Atom
*/
public ReplaceAtomChangeEvent (int rowIndex, int colIndex, Atom atom) {
rowIndex_ = rowIndex;
colIndex_ = colIndex;
atom_ = atom;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#execute()
*/
public boolean execute() {
Atom [] oldRow = (Atom[]) data_.getValue(rowIndex_);
Atom [] newRow = copyAtoms(oldRow);
newRow[colIndex_] = atom_;
if (updateStreamedSize_) {
streamedTableSize_ -= streamedSizeOfAtomArray(oldRow);
streamedTableSize_ += streamedSizeOfAtomArray(newRow);
}
data_.replace(data_.getKey(rowIndex_), newRow);
return true;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#getType()
*/
public byte getType() {
return T_REPLACEATOM_EVT;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#streamedSize()
*/
public int streamedSize() {
return 1 + // type
4 + // rowIndex
4 + // ColIndex
Atom.streamedSize(atom_);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#externalize(at.spardat.xma.serializer.XmaOutput)
*/
public void externalize(XmaOutput out) throws IOException {
out.writeInt("rowIdx", rowIndex_);
out.writeInt("colIdx", colIndex_);
Atom.externalize(atom_, out);
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize(XmaInput in) throws IOException, ClassNotFoundException {
rowIndex_ = in.readInt();
colIndex_ = in.readInt();
atom_ = Atom.internalize(in);
}
/**
* Returns the row index of the row where the change is applied
*/
public int getRowIndex() {
return rowIndex_;
}
/**
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
super.describe(n); n.comma();
n.app("rowIdx", rowIndex_).comma();
n.app("colIdx", colIndex_).comma();
n.app("atom", atom_);
}
private int rowIndex_;
private int colIndex_;
private Atom atom_;
}
/**
* Clears the table
*
* @author YSD, 14.04.2003 11:27:21
*/
public final class ClearEvent extends TableChangeEvent {
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#execute()
*/
public boolean execute() {
data_.clear();
if (updateStreamedSize_) streamedTableSize_ = 0;
return true;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#getType()
*/
public byte getType() {
return T_CLEAR_EVT;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#streamedSize()
*/
public int streamedSize() {
return 1;
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#externalize(at.spardat.xma.serializer.XmaOutput)
*/
public void externalize(XmaOutput out) throws IOException {
// empty since there is no data this event consists of
}
/**
* @see at.spardat.xma.mdl.util.TransAtomTable.TableChangeEvent#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize(XmaInput in) throws IOException, ClassNotFoundException {
// empty since there is no data this event consists of
}
}
}