Commit 049d6ed1 authored by Tobias Meuser's avatar Tobias Meuser Committed by Jose Ignacio Monreal Bailey
Browse files

Added cache based decision

parent ba977666
...@@ -30,8 +30,10 @@ import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface; ...@@ -30,8 +30,10 @@ import de.tudarmstadt.maki.simonstrator.api.component.network.NetInterface;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName; import de.tudarmstadt.maki.simonstrator.api.component.network.NetworkComponent.NetInterfaceName;
import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener; import de.tudarmstadt.maki.simonstrator.api.component.transport.ConnectivityListener;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.CachingComponent; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.CachingComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.invalidation.CacheInvalidationStrategy; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.invalidation.CacheInvalidationStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.replacement.CacheReplacementStrategy; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.replacement.CacheReplacementStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
public class DefaultCachingComponent implements CachingComponent, ConnectivityListener { public class DefaultCachingComponent implements CachingComponent, ConnectivityListener {
...@@ -40,14 +42,50 @@ public class DefaultCachingComponent implements CachingComponent, ConnectivityLi ...@@ -40,14 +42,50 @@ public class DefaultCachingComponent implements CachingComponent, ConnectivityLi
private CacheInvalidationStrategy _invalidationStrategy; private CacheInvalidationStrategy _invalidationStrategy;
private CacheReplacementStrategy _replacementStrategy; private CacheReplacementStrategy _replacementStrategy;
private CacheDecisionStrategy _decisionStrategy;
public DefaultCachingComponent(Host pHost, CacheInvalidationStrategy pInvalidationStrategy, CacheReplacementStrategy pReplacementStrategy) { public DefaultCachingComponent(Host pHost, CacheInvalidationStrategy pInvalidationStrategy, CacheReplacementStrategy pReplacementStrategy, CacheDecisionStrategy pDecisionStrategy) {
_host = pHost; _host = pHost;
if (_host != null) {
_host.getNetworkComponent().getByName(NetInterfaceName.WIFI).addConnectivityListener(this); _host.getNetworkComponent().getByName(NetInterfaceName.WIFI).addConnectivityListener(this);
}
_invalidationStrategy = pInvalidationStrategy; _invalidationStrategy = pInvalidationStrategy;
_replacementStrategy = pReplacementStrategy; _replacementStrategy = pReplacementStrategy;
_decisionStrategy = pDecisionStrategy;
}
@Override
public <T extends PointInformation> List<T> getDecidedCacheEntries(Class<T> pCacheEntryClass) {
List<T> cacheEntries = getCacheEntries(pCacheEntryClass);
if (cacheEntries == null) {
return null;
}
Map<Object, List<PointInformation>> similarCacheEntries = new HashMap<>();
for (T t : cacheEntries) {
Object position = getEdgeOrPosition(t);
if (!similarCacheEntries.containsKey(position)) {
similarCacheEntries.put(position, new ArrayList<>());
}
similarCacheEntries.get(position).add(t);
}
List<T> decidedInformation = new ArrayList<>();
for (List<PointInformation> similarEntries : similarCacheEntries.values()) {
PointInformation correctInformation = _decisionStrategy.decideOnCorrectInformation(similarEntries);
if (correctInformation == null) {
System.out.println();
}
decidedInformation.add((T) correctInformation);
}
return decidedInformation;
} }
@Override @Override
...@@ -85,17 +123,7 @@ public class DefaultCachingComponent implements CachingComponent, ConnectivityLi ...@@ -85,17 +123,7 @@ public class DefaultCachingComponent implements CachingComponent, ConnectivityLi
_cache.put(pCacheEntry.getClass(), new ArrayList<>()); _cache.put(pCacheEntry.getClass(), new ArrayList<>());
} }
List<PointInformation> entries = _cache.get(pCacheEntry.getClass()); List<PointInformation> entries = _cache.get(pCacheEntry.getClass());
int index;
if ((index = entries.indexOf(pCacheEntry)) != -1) {
if (_replacementStrategy.replaceInformation(entries.get(index), pCacheEntry)) {
entries.remove(index);
entries.add(pCacheEntry); entries.add(pCacheEntry);
} else {
// Nothing to do
}
} else {
entries.add(pCacheEntry);
}
} }
@Override @Override
...@@ -127,4 +155,12 @@ public class DefaultCachingComponent implements CachingComponent, ConnectivityLi ...@@ -127,4 +155,12 @@ public class DefaultCachingComponent implements CachingComponent, ConnectivityLi
_cache.clear(); _cache.clear();
} }
public Object getEdgeOrPosition(PointInformation information) {
if (information.hasAttribute(AvailableInformationAttributes.EDGE)) {
return information.getAttribute(AvailableInformationAttributes.EDGE);
} else {
return information.getLocation();
}
}
} }
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
public enum CacheDecisionStrategyType {
DEFAULT(NewestCacheDecisionStrategy.class), NEWEST(NewestCacheDecisionStrategy.class), TTL(TTLbasedCacheDecisionStrategy.class), MAJORITY(MajorityVotingCacheDecisionStrategy.class);
private final Class<? extends CacheDecisionStrategy> decisionStrategy;
private final Map<String, String> params = new HashMap<>();
private CacheDecisionStrategyType(final Class<? extends CacheDecisionStrategy> decisionStrategy) {
this.decisionStrategy = decisionStrategy;
}
public CacheDecisionStrategy getDecisionStrategy() {
try {
try {
Constructor<? extends CacheDecisionStrategy> constructor = decisionStrategy.getConstructor(Map.class);
return constructor.newInstance(params);
} catch (NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
return decisionStrategy.newInstance();
}
} catch (InstantiationException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
public void addAttribute(String pKey, String pValue) {
params.put(pKey, pValue);
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
public class MajorityVotingCacheDecisionStrategy implements CacheDecisionStrategy {
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
List<T> pSimilarPointInformation) {
Map<Object, Integer> voting = new HashMap<>();
for (T t : pSimilarPointInformation) {
if (!voting.containsKey(t.getValue())) {
voting.put(t.getValue(), 0);
}
voting.put(t.getValue(), voting.get(t.getValue()) + 1);
}
Entry<Object, Integer> maxEntry = null;
for (Entry<Object, Integer> entry : voting.entrySet()) {
if (maxEntry == null) {
maxEntry = entry;
}
if (maxEntry.getValue() < entry.getValue()) {
maxEntry = entry;
}
}
long maxTimestamp = 0;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = t.getDetectionDate();
if (t.getValue().equals(maxEntry.getValue()) && timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
return maxFitting;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.List;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
public class NewestCacheDecisionStrategy implements CacheDecisionStrategy {
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
List<T> pSimilarPointInformation) {
long newestDetectionTime = 0;
T chosenInformation = null;
for (T t : pSimilarPointInformation) {
if (t.getDetectionDate() > newestDetectionTime) {
newestDetectionTime = t.getDetectionDate();
chosenInformation = t;
}
}
return chosenInformation;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM 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
* any later version.
*
* PeerfactSim.KOM 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 PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.vehicular.caching.decision;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.caching.decision.CacheDecisionStrategy;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation;
public class TTLbasedCacheDecisionStrategy implements CacheDecisionStrategy {
private static final long SCALING = Time.SECOND;
private long ttl = 300 * Time.SECOND / SCALING;
private double accuracy = 1;
private double costWrongKeep = 1;
private double costWrongChange = 1;
public TTLbasedCacheDecisionStrategy(Map<String, String> pParams) {
for (Entry<String, String> param : pParams.entrySet()) {
switch (param.getKey()) {
case "ACCURACY":
accuracy = Double.valueOf(param.getValue());
break;
default:
break;
}
}
}
@Override
public <T extends PointInformation> T decideOnCorrectInformation(
List<T> pSimilarPointInformation) {
if (pSimilarPointInformation.size() == 1) {
return pSimilarPointInformation.get(0);
} else if (pSimilarPointInformation.size() == 0) {
return null;
}
long minTimestamp = Long.MAX_VALUE;
long maxTimestamp = 0;
Object value = pSimilarPointInformation.get(0).getValue();
boolean differentValue = false;
for (T t : pSimilarPointInformation) {
if (!t.hasAttribute(AvailableInformationAttributes.TTL)) {
throw new AssertionError("Unable to perform TTL-based majority voting witout TTL");
}
long timestamp = t.getDetectionDate();
if (timestamp < minTimestamp) {
minTimestamp = timestamp;
}
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
}
if (!value.equals(t.getValue())) {
differentValue = true;
}
}
if (differentValue) {
long difference = maxTimestamp - minTimestamp;
if (difference == 0) {
return pSimilarPointInformation.get(pSimilarPointInformation.size() - 1);
}
double rate = difference / ((double) (pSimilarPointInformation.size() - 1) * SCALING);
rate = Math.min(rate, ttl / 10);
double b = determineB(rate, 1 - accuracy, ttl, costWrongKeep, costWrongChange);
Map<Object, Double> weight = new HashMap<>();
for (T t : pSimilarPointInformation) {
double impact = calculateImpact(1 - accuracy, ttl, t.getDetectionDate() / SCALING, b, maxTimestamp / SCALING);
double sumImpact = 0;
if (weight.containsKey(t.getValue())) {
sumImpact = weight.get(t.getValue());
}
sumImpact += impact;
weight.put(t.getValue(), sumImpact);
}
double maxWeight = 0;
Object maxValue = null;
for (Object key : weight.keySet()) {
if (weight.get(key) > maxWeight) {
maxWeight = weight.get(key);
maxValue = key;
}
}
maxTimestamp = 0;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = t.getDetectionDate();
if (t.getValue().equals(maxValue) && timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
return maxFitting;
} else {
maxTimestamp = 0;
T maxFitting = null;
for (T t : pSimilarPointInformation) {
long timestamp = (long) t.getAttribute(AvailableInformationAttributes.TTL);
if (timestamp > maxTimestamp) {
maxTimestamp = timestamp;
maxFitting = t;
}
}
return maxFitting;
}
}
public double calculateImpact(double errorProbability, long ttl, long time, double b, long maxTimestamp) {
long currentTime = Time.getCurrentTime() / SCALING;
long age = currentTime - time;
if (errorProbability == 0) {
if (time == maxTimestamp) {
return 1;
} else {
return 0;
}
} else if (errorProbability == 1) {
return 1;
} else if (errorProbability == 0.5) {
return (errorProbability - 1) / ttl * age + errorProbability;
}
return (1 - errorProbability) * (Math.exp(b * age) - Math.exp(b * ttl)) / (1 - Math.exp(b * ttl));
}
public double getChangeProbability(long ttl) {
return 1 - Math.pow(0.5, 1 / (double) ttl);
}
public int getOptimalMessageAmountForSwitch(double changeProbability, double errorProbability, double costSlow, double costFast) {
return (int) Math.round(Math.log(-changeProbability / Math.log(errorProbability) * costSlow / costFast) / Math.log(errorProbability));
}
public double determineB(double rate, double errorProbability, long ttl, double costSlow, double costFast) {
return determineB(rate, errorProbability, ttl, costSlow, costFast, 1);
}
public double determineB(double rate, double errorProbability, long ttl, double costSlow, double costFast, int reversed) {
if (errorProbability == 0 || errorProbability == 1 || errorProbability == 0.5) {
return Double.NaN;
}
double b;
double p_c = getChangeProbability((long) (ttl / rate));
int optimalAmount = getOptimalMessageAmountForSwitch(p_c, errorProbability, costSlow, costFast);
boolean first = true;
double leftSide;
double rightSide;
double step = 0.5;
if (errorProbability < 0.5) {
b = -1 * reversed;
} else {
b = 1 * reversed;
}
do {
leftSide = calculateWeightingForOldState(optimalAmount, rate, errorProbability, ttl, b);
rightSide = calculateWeightingForNewState(optimalAmount, rate, errorProbability, ttl, b);
if (Double.isNaN(leftSide) || Double.isNaN(rightSide)) {
if (reversed != -1) {
return determineB(rate, errorProbability, ttl, costSlow, costFast, -1);
} else {
return Double.NaN;
}
}
leftSide = Math.round(leftSide * 100000);
rightSide = Math.round(rightSide * 100000);
if (leftSide > rightSide) {
if (b < 0) {
b -= step;
if (!first) {
step *= 0.5;
}
} else {
b -= step;
step *= 0.5;
first = false;
}
} else if (leftSide < rightSide) {
if (b > 0) {
b += step;
if (!first) {
step *= 0.5;
}
} else {
b += step;
step *= 0.5;
first = false;
}
} else {
break;
}
} while (true);
return b;
}
public double calculateWeightingForOldState(int optimalMessageAmount, double rate, double errorProbability, long ttl, double b) {
double impact = 0;
for (int a = optimalMessageAmount + 1; a < Math.max(Math.floor(ttl / rate), optimalMessageAmount + 2); a++) {
impact += calculateImpact(errorProbability, ttl, Time.getCurrentTime() / SCALING - (long)Math.floor(a * rate), b, 0);
}
return impact;
}
public double calculateWeightingForNewState(int optimalMessageAmount, double rate, double errorProbability, long ttl, double b) {
double impact = 0;
for (int a = 0; a <= optimalMessageAmount; a++) {
impact += calculateImpact(errorProbability, ttl, Time.getCurrentTime() / SCALING - (long)Math.floor(a * rate), b, 0);
}
return impact;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment