/**
* Replication Benchmarker
* https://github.com/score-team/replication-benchmarker/
* Copyright (C) 2013 LORIA / Inria / SCORE Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package crdt.set;
import crdt.CRDT;
import crdt.CRDTMessage;
import java.util.*;
import crdt.PreconditionException;
import jbenchmarker.core.LocalOperation;
/**
*
* @author score
*/
public abstract class CRDTSet<T> extends CRDT<Set<T>> {
public CRDTSet() {
}
public CRDTSet(int replicaNumber) {
super(replicaNumber);
}
@Override
public abstract CRDTSet<T> create();
abstract protected CRDTMessage innerAdd(T t) throws PreconditionException;
abstract protected CRDTMessage innerRemove(T t) throws PreconditionException;
abstract public boolean contains (T t);
@Override
final public CRDTMessage applyLocal(LocalOperation op) throws PreconditionException {
SetOperation<T> s = (SetOperation<T>) op;
CRDTMessage msg;
if (s.getType() == SetOperation.OpType.add) {
msg = add(s.getContent());
}else{
msg = remove(s.getContent());
}
return msg;
}
/**
* Adds an element to the set
* @param t the element
* @return a message
* @throws PreconditionException if elment is already in lookup (or other crdt specific condition)
*/
final public CRDTMessage add(T t) throws PreconditionException {
if (lookup().contains(t)) {
throw new PreconditionException("Add : the element " + t + " already exists in the set");
}
CRDTMessage msg;
msg = innerAdd(t);
notifyAdd(t);
return msg;
}
/**
* Removes an element to the set
* @param t the element
* @return a message
* @throws PreconditionException if elment is already in lookup (or other crdt specific condition)
*/
final public CRDTMessage remove(T t) throws PreconditionException {
if (!lookup().contains(t)) {
throw new PreconditionException("Remove : the element " + t + " does not exist in the set");
}
CRDTMessage msg;
msg = innerRemove(t);
notifyDel(t);
return msg;
}
/**
* Notifies the observers that an element is added.
* Should be called when lookup is changed by applyRemote.
* @param t the element added
*/
protected void notifyAdd(T t) {
this.setChanged();
this.notifyObservers(new SetOperation<T>(SetOperation.OpType.add, t));
}
/**
* Notifies the observers that an element is remove.
* Should be called when lookup is changed by applyRemote.
* @param t the element removed
*/
protected void notifyDel(T t) {
this.setChanged();
this.notifyObservers(new SetOperation<T>(SetOperation.OpType.del, t));
}
public String view(){
return this.lookup().toString();
}
}