/* * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab * * This file is part of Simonstrator.KOM. * * Simonstrator.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 . * */ package de.tud.kom.p2psim.impl.vehicular.caching; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import de.tudarmstadt.maki.simonstrator.api.Host; import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException; 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.transport.ConnectivityListener; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.VehicleInformationComponent; 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.replacement.CacheReplacementStrategy; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.AvailableInformationAttributes; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.JamInformation; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.information.PointInformation; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge; import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute; public class DefaultCachingComponent implements CachingComponent, ConnectivityListener { private Map, List> _cache = new HashMap<>(); private Map _lastColorValues = new HashMap<>(); private Host _host; private CacheInvalidationStrategy _invalidationStrategy; private CacheReplacementStrategy _replacementStrategy; private CacheDecisionStrategy _decisionStrategy; private int _minObservations = 0; private double[] informationRatios = new double[] {1, 0.75, 0.5, 0.25, 0}; public DefaultCachingComponent(Host pHost, CacheInvalidationStrategy pInvalidationStrategy, CacheReplacementStrategy pReplacementStrategy, CacheDecisionStrategy pDecisionStrategy) { _host = pHost; if (_host != null) { NetInterface wifi = _host.getNetworkComponent().getByName(NetInterfaceName.WIFI); if (wifi != null) { wifi.addConnectivityListener(this); } else { NetInterface cellular = _host.getNetworkComponent().getByName(NetInterfaceName.MOBILE); cellular.addConnectivityListener(this); } } _invalidationStrategy = pInvalidationStrategy; _replacementStrategy = pReplacementStrategy; _decisionStrategy = pDecisionStrategy; } @Override public List getDecidedCacheEntries( Class pCacheEntryClass) { List cacheEntries = getCacheEntries(pCacheEntryClass); if (cacheEntries == null) { return null; } Map, List>> similarCacheEntries = new HashMap<>(); for (T t : cacheEntries) { Object position = getEdgeOrPosition(t); if (!similarCacheEntries.containsKey(position)) { similarCacheEntries.put(position, new HashMap<>()); } if (!similarCacheEntries.get(position).containsKey(t.getValue().getClass())) { similarCacheEntries.get(position).put(t.getValue().getClass(), new ArrayList()); } similarCacheEntries.get(position).get(t.getValue().getClass()).add(t); } List decidedInformation = new ArrayList<>(); for (Map, List> similarEdges : similarCacheEntries .values()) { for (List similarInformation : similarEdges.values()) { if (similarInformation.size() >= _minObservations) { PointInformation correctInformation = _decisionStrategy .decideOnCorrectInformation(similarInformation); decidedInformation.add((T) correctInformation); } } } return decidedInformation; } public void setMinObservations(int pMinObservations) { this._minObservations = pMinObservations; } @Override public List getCacheEntries( Class pCacheEntryClass) { if (_cache.containsKey(pCacheEntryClass)) { List cacheEntries = _cache .get(pCacheEntryClass); List results = new ArrayList<>(); for (int i = 0; i < cacheEntries.size(); i++) { PointInformation object = cacheEntries.get(i); if (_invalidationStrategy.checkInformation(object)) { cacheEntries.remove(i--); continue; } results.add((T) object); } return results; } return null; } @Override public boolean containsEntry(T pCacheEntry) { if (_cache.containsKey(pCacheEntry)) { List cacheEntries = _cache.get(pCacheEntry); return cacheEntries.contains(pCacheEntry); } return false; } @Override public void storeCacheEntry(T pCacheEntry) { if (!_cache.containsKey(pCacheEntry.getClass())) { _cache.put(pCacheEntry.getClass(), new ArrayList<>()); } List entries = _cache.get(pCacheEntry.getClass()); entries.add(pCacheEntry); } @Override public void initialize() { _cache.clear(); } @Override public void shutdown() { } @Override public Host getHost() { return _host; } @Override public void wentOnline(Host pHost, NetInterface pNetInterface) { _cache.clear(); } @Override public void wentOffline(Host pHost, NetInterface pNetInterface) { } @Override public void clear() { _cache.clear(); } public Object getEdgeOrPosition(PointInformation information) { if (information.hasAttribute(AvailableInformationAttributes.EDGE)) { return information .getAttribute(AvailableInformationAttributes.EDGE); } else { return information.getLocation(); } } public CacheDecisionStrategy getDecisionStrategy() { return _decisionStrategy; } @Override public String getNodeDescription() { return " " + getHost().getId(); } @Override public int getNodeColorDimensions() { return 2; } @Override public String[] getNodeColorDimensionDescriptions() { return new String[] {"Route Information", "Number of jam information"}; } @Override public String[] getNodeColorDescriptions(int pDimension) { if (pDimension == 0) { String[] labels = new String[informationRatios.length]; for (int i = 0; i < informationRatios.length; i++) { labels[i] = informationRatios[i] * 100 + "%"; } return labels; } else if (pDimension == 1) { String[] numbers = new String[10]; for (int i = 0; i < numbers.length; i++) { numbers[i] = String.valueOf(i); } return numbers; } return new String[0]; } @Override public int getNodeColor(int pDimension) { if (pDimension == 0) { List decidedCacheEntries = getDecidedCacheEntries(JamInformation.class); try { VehicleInformationComponent vehicleInformationComponent = getHost().getComponent(VehicleInformationComponent.class); if (vehicleInformationComponent.isValid()) { RoadNetworkRoute currentRoute = vehicleInformationComponent.getCurrentRoute(); if (currentRoute != null) { int count = 0; int active = 0; for (RoadNetworkEdge edge : currentRoute.getRoute()) { if (edge.isActive()) { if (decidedCacheEntries != null) { for (JamInformation jamInformation : decidedCacheEntries) { if (jamInformation.getEdge().equals(edge) && jamInformation.getValue()) { count++; break; } } } active++; } } if (active != 0) { double ratio = count / ((double) active); for (int i = 0; i < informationRatios.length; i++) { if (informationRatios[i] <= ratio) { _lastColorValues.put(pDimension, i); break; } } } else { _lastColorValues.put(pDimension, 0); } } } } catch (ComponentNotAvailableException e) { } if (_lastColorValues.containsKey(pDimension)) { return _lastColorValues.get(pDimension); } return 0; } if (pDimension == 1) { List decidedCacheEntries = getDecidedCacheEntries(JamInformation.class); if (decidedCacheEntries != null) { _lastColorValues.put(pDimension, decidedCacheEntries.size()); } if (_lastColorValues.containsKey(pDimension)) { return Math.min(9, _lastColorValues.get(pDimension)); } return 0; } return 0; } @Override public boolean isActive() { return getHost().getNetworkComponent().getByName(NetInterfaceName.MOBILE).isUp() || getHost().getNetworkComponent().getByName(NetInterfaceName.WIFI).isUp(); } }