/**
* 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.tree.wordtree;
import collect.HashTree;
import collect.Tree;
import collect.UnorderedNode;
import crdt.CRDTMessage;
import crdt.Factory;
import crdt.PreconditionException;
import crdt.set.CRDTSet;
import crdt.tree.CRDTUnorderedTree;
import java.util.*;
/**
*
* @author urso
*
*
*/
public class WordTree<T> extends CRDTUnorderedTree<T>{
CRDTSet words;
WordPolicy<T> wcp;
public WordTree(Factory<CRDTSet<List<T>>> setFactory, Factory<WordPolicy<T>> wcp) {
this.wcp = wcp.create();
this.words = setFactory.create();
this.words.addObserver(this.wcp);
}
@Override
public CRDTMessage add(UnorderedNode<T> father, T element) throws PreconditionException {
if (!wcp.lookup().contains(father))
throw new PreconditionException("Adding node " + element + " with father not in the tree");
if (father.getChild(element) != null)
throw new PreconditionException("Adding node " + element + " already present under father");
CRDTMessage msg = null;
for (List<T> wf : wcp.addMapping(father)) {
List<T> w = new Word(wf, element);
CRDTMessage add = words.add(w);
msg = msg == null ? add : msg.concat(add);
}
return msg;
}
@Override
public CRDTMessage remove(UnorderedNode<T> subtree) throws PreconditionException {
if (wcp.lookup().getRoot() == subtree)
throw new PreconditionException("Removing root");
if (!wcp.lookup().contains(subtree))
throw new PreconditionException("Removing node " + subtree + " not in the tree");
CRDTMessage msg = null;
for (List<T> w : wcp.toBeRemoved(subtree)) {
CRDTMessage del = words.remove(w);
msg = msg == null ? del : msg.concat(del);
}
return msg;
}
@Override
public void applyOneRemote(CRDTMessage op) {
words.applyRemote(op);
}
@Override
public Tree<T> lookup() {
return wcp.lookup();
}
@Override
public UnorderedNode<T> getRoot() {
return (UnorderedNode<T>) wcp.lookup().getRoot();
}
@Override
public WordTree<T> create() {
return new WordTree<T>(words, wcp);
}
@Override
public void setReplicaNumber(int replicaNumber) {
super.setReplicaNumber(replicaNumber);
words.setReplicaNumber(replicaNumber);
}
@Override
public String toString() {
return "WordTree<" + words.getClass() + ',' + wcp.getClass() + ">{" + this.getReplicaNumber() + '}';
}
@Override
public synchronized void addObserver(Observer obsrvr) {
super.addObserver(obsrvr);
((HashTree<T>) wcp.lookup()).addObserver(obsrvr);
}
}