package myLinda;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import linda.LindaArgs;
import linda.LindaType;
public class TupleSpaceTree {
Map<String, TupleSpaceTree> mymap = new HashMap<String, TupleSpaceTree>();
Set<TupleSpaceTree> gapSet = new HashSet<TupleSpaceTree>();
private TupleSpaceTree parent = null;
private LindaArgs value;
private int counter;
public TupleSpaceTree(TupleSpaceTree parent) {
this.parent = parent;
}
public TupleSpaceTree update_values(LindaArgs args) {
LindaType arg = args.remove(0);
String key = arg.getRawValue();
if (!mymap.containsKey(key)) {
mymap.put(key, new TupleSpaceTree(this));
}
if (args.isEmpty()) {
return mymap.get(key);
} else {
return mymap.get(key).update_values(args);
}
}
public TupleSpaceTree find(LindaArgs pattern) {
return findAux(pattern, this, 0);
}
public TupleSpaceTree findAux(LindaArgs pattern, TupleSpaceTree currentNode, int pos) {
if (currentNode.counter == 0) {
// There are no tuples beneath.
return null;
}
if (pattern.size() <= pos) {
// We found leaf.
return currentNode;
}
LindaType lindaType = pattern.get(pos);
String key = lindaType.getRawValue();
if (key == null) {
int size = currentNode.gapSet.size();
if (size != 0) {
for(TupleSpaceTree node : currentNode.gapSet) {
currentNode = findAux(pattern, node, pos + 1);
if (currentNode != null) {
return currentNode;
}
}
} else {
throw new RuntimeException("Set shouldn't be wmpty on > 0 counter.");
}
} else if (currentNode.mymap.containsKey(key)) {
return findAux(pattern, currentNode.mymap.get(key), pos + 1);
}
return null;
}
public void setValue(LindaArgs args) {
value = args;
}
public List<LindaType> getValue() {
return value;
}
public void increment() {
counter++;
if (parent != null){
parent.gapSet.add(this);
parent.increment();
}
}
public void decrement() {
counter--;
if (parent != null){
if (counter == 0) {
parent.gapSet.remove(this);
}
parent.decrement();
}
}
}