Isolator.java
package org.microspace.table;
import java.math.BigInteger;
import org.microspace.exception.IllegalOperationException;
import org.microspace.specific.CurrentTimeProvider;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.Getter;
import org.microspace.table.column.IndexedMap;
import org.microspace.table.column.IndexedSet;
/**
* A front map that can be used as a transaction map.
* @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
*/
public class Isolator<T> extends SimpleUnsafeTable<T> {
public enum State {
CREATED, LOCKED
}
State state;
protected final IndexedMap<Object, BigInteger> backUpdateCount;
protected final IndexedSet<Object> updates;
public Isolator(Class<T> clazz, CurrentTimeProvider currentTimeProvider) {
super(clazz, currentTimeProvider);
Accessor<T> getters = getAccessor();
backUpdateCount = new IndexedMap<Object, BigInteger> (getters.getPrimaryKeyGetSetPair().getIndexType());
updates = new IndexedSet<Object> (getters.getPrimaryKeyGetSetPair().getIndexType());
state = State.CREATED;
}
public Isolator(Accessor<T> accessor, CurrentTimeProvider currentTimeProvider) {
super(accessor, currentTimeProvider);
Accessor<T> getters = getAccessor();
backUpdateCount = new IndexedMap<Object, BigInteger> (getters.getPrimaryKeyGetSetPair().getIndexType());
updates = new IndexedSet<Object> (getters.getPrimaryKeyGetSetPair().getIndexType());
state = State.CREATED;
}
public IndexedSet<Object> keySet () {
return entries.keySet ();
}
public void setFirstEntry (Entry<T> container) {
Getter<T> keyGetter = getAccessor().getPrimaryKeyGetSetPair();
Object key = keyGetter.get (container.getSpaceEntry());
if (entries.get(key) != null) {
throw new IllegalArgumentException ("Map already has the key.");
}
if (backUpdateCount.put (key, container.getUpdateCount()) != null) {
throw new IllegalArgumentException ("Removed container is already copied.");
}
if (getState() == State.LOCKED){
throw new IllegalOperationException("Map is locked.");
}
if (container.isRemoved()) {
@SuppressWarnings("unused")
T t = readById(container.getPrimaryKey());
updates.add (keyGetter.get(container.getSpaceEntry()));
}
super.setFirstEntry(container);
}
public BigInteger getBackUpdateCount (Object o) {
return backUpdateCount.get(o);
}
public IndexedSet<Object> getUpdatedKeys () {
return updates;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
/**
* Removes are marke only.
*/
@Override
protected void remove (Entry<T> container) {
remove (container, true);
}
@Override
public void setEntry (Entry<T> container) {
if (getState() == State.LOCKED){
throw new IllegalOperationException("Map is locked.");
}
// Load up the entry if it exists.
@SuppressWarnings("unused")
T t = readById(container.getPrimaryKey());
Getter<T> keyGetter = getAccessor().getPrimaryKeyGetSetPair();
updates.add (keyGetter.get(container.getSpaceEntry()));
if (container.isRemoved()) {
remove (container);
} else {
move (container);
}
}
public void clear () {
if (getState() == State.LOCKED){
throw new IllegalOperationException ("Map is locked.");
}
backUpdateCount.clear ();
updates.clear();
super.clear();
}
}