package se.sics.gvod.ls.interas;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import se.sics.asdistances.ASDistances;
import se.sics.asdistances.PrefixHandler;
import se.sics.gvod.common.VodDescriptor;
/**
*
* @author Niklas Wahlén <nwahlen@kth.se>
*/
public class InterAsComparator implements Comparator<VodDescriptor> {
private VodDescriptor referenceNode;
private ASDistances distances;
private Map<Integer, Integer> penalties;
public InterAsComparator(VodDescriptor referenceNode) {
this.referenceNode = referenceNode;
this.distances = ASDistances.getInstance();
penalties = new HashMap<Integer, Integer>();
}
@Override
public int compare(VodDescriptor d1, VodDescriptor d2) {
String ipr = referenceNode.getVodAddress().getIp().getHostAddress();
String ip1 = d1.getVodAddress().getIp().getHostAddress();
String ip2 = d2.getVodAddress().getIp().getHostAddress();
byte distanceTo1 = distances.getDistance(ipr, ip1);
byte distanceTo2 = distances.getDistance(ipr, ip2);
int penalty1 = this.getPenalty(d1.getVodAddress().getId());
int penalty2 = this.getPenalty(d2.getVodAddress().getId());
if (penalty1 < penalty2) {
return 1;
} else if (penalty1 > penalty2) {
return -1;
} else if (distanceTo1 < distanceTo2) {
return 1;
} else if (distanceTo1 > distanceTo2) {
return -1;
} else {
int sharedPrefixLength1 = PrefixHandler.sharedPrefix(ipr, ip1);
int sharedPrefixLength2 = PrefixHandler.sharedPrefix(ipr, ip2);
if (sharedPrefixLength1 > sharedPrefixLength2) {
return 1;
} else if (sharedPrefixLength1 < sharedPrefixLength2) {
return -1;
} else {
return 0;
}
}
}
public void punish(int id) {
Integer currentPenalty = penalties.get(id);
if (currentPenalty == null || currentPenalty < 51) {
penalties.put(id, 100);
} else { /*
* If the map previously contained a mapping for the key, the old
* value is replaced by the specified value.
*/
penalties.put(id, currentPenalty * 2);
}
}
public int getPenalty(int id) {
Integer penalty = penalties.get(id);
return penalty == null ? 0 : penalty;
}
public void decreasePenalties() {
Set<Integer> ids = penalties.keySet();
for (Integer id : ids) {
Integer currentPenalty = penalties.get(id);
if (currentPenalty != null) {
penalties.put(id, currentPenalty - 1);
}
}
}
}