package edu.usc.enl.dynamicmeasurement.algorithms.tasks.hhh.flow.singleswitch; import edu.usc.enl.dynamicmeasurement.model.WildcardPattern; import java.util.*; /** * Created with IntelliJ IDEA. * User: masoud * Date: 8/19/13 * Time: 6:34 PM <br/> * For finding the precision of Hierarchical Heavy Hitters. * This class finds the probability of a HHH to be false or true and sums that up over all HHHs */ public class FalseHHHFinder { /** * For checking the descendant HHHs, using the threshold may be overkilling, * If true, lets refining accuracy using average weight of HHHs we think are true HHHs */ private final boolean refine; private List<WildcardPattern> lastFalseHHHs; private final int wildcardNum; public FalseHHHFinder(boolean refine, int wildcardNum) { this.refine = refine; this.wildcardNum = wildcardNum; } public boolean isRefine() { return refine; } public List<WildcardPattern> getLastFalseHHHs() { return lastFalseHHHs; } public double findFalseHHHs2(Collection<WildcardPattern> reportedHHH, Collection<WildcardPattern> monitors, double threshold) { TreeMap<WildcardPattern, Boolean> bottomUpTrueHHHs = new TreeMap<>(WildcardPattern.WILDCARDNUM_COMPARATOR); for (WildcardPattern wildcardPattern : reportedHHH) { bottomUpTrueHHHs.put(wildcardPattern, Boolean.FALSE); } double accuracy = 0; double sum = 0; List<WildcardPattern> falseHHHs = new LinkedList<>(); for (Map.Entry<WildcardPattern, Boolean> entry : bottomUpTrueHHHs.entrySet()) { WildcardPattern hhh = entry.getKey(); boolean isExact = hhh.getWildcardNum() == wildcardNum; //find if there is any descendent hhh that is false //if (checkDescendantHHHs(falseHHHs, hhh)) { if (!isExact && checkForDescendantHHHs(falseHHHs, hhh, threshold, reportedHHH, monitors)) { falseHHHs.add(hhh); continue; } // now check monitors, if it is exact or there is a monitor under me it is OK boolean isTrue = isExact || hasDescendantMonitors(monitors, hhh); if (isTrue) { sum += hhh.getWeight(); accuracy++; } else { // This is not an exact HHH but a fringe one without any descendant HHH or monitor. // It can only be a hope to be a true HHH if it sweight is <2*threshold if (hhh.getWeight() < 2 * threshold) { accuracy += 0.5; } falseHHHs.add(hhh); } } if (refine) { // Using the average weight of HHHs, check again the descendant HHHs double averageEasyTrueHHHWeight = sum / (reportedHHH.size() - falseHHHs.size()); for (Iterator<WildcardPattern> iterator = falseHHHs.iterator(); iterator.hasNext(); ) { WildcardPattern falseHHH = iterator.next(); if (!checkForDescendantHHHs(falseHHHs, falseHHH, averageEasyTrueHHHWeight, reportedHHH, monitors)) { iterator.remove(); } } } lastFalseHHHs = falseHHHs; return accuracy; } public Map<WildcardPattern, Double> findFalseHHHs(Collection<WildcardPattern> reportedHHH, Collection<WildcardPattern> monitors, double threshold) { TreeMap<WildcardPattern, Double> bottomUpHHHsReport = new TreeMap<>(WildcardPattern.WILDCARDNUM_COMPARATOR); for (WildcardPattern wildcardPattern : reportedHHH) { bottomUpHHHsReport.put(wildcardPattern, 0d); } double trueHHHSum = 0; List<WildcardPattern> falseHHHs = new LinkedList<>(); for (Map.Entry<WildcardPattern, Double> entry : bottomUpHHHsReport.entrySet()) { WildcardPattern hhh = entry.getKey(); if (hhh.getWildcardNum() == wildcardNum) { //exact hhhs are always true entry.setValue(1d); trueHHHSum += hhh.getWeight(); } else { //find if there is any descendent hhh that is false //find descendant monitors if (!hasDescendantMonitors(monitors, hhh)) { falseHHHs.add(hhh); if (hhh.getWeight() < 2 * threshold) { entry.setValue(0.5); } } else { //check descendant HHHs if (checkForDescendantHHHs(falseHHHs, hhh, threshold, bottomUpHHHsReport.keySet(), monitors)) { entry.setValue(1d); trueHHHSum += hhh.getWeight(); } else { falseHHHs.add(hhh); } } } } if (refine) { double averageEasyTrueHHHWeight = trueHHHSum / (reportedHHH.size() - falseHHHs.size()); for (Iterator<WildcardPattern> iterator = falseHHHs.iterator(); iterator.hasNext(); ) { WildcardPattern falseHHH = iterator.next(); if (checkForDescendantHHHs(falseHHHs, falseHHH, averageEasyTrueHHHWeight, bottomUpHHHsReport.keySet(), monitors)) { iterator.remove(); bottomUpHHHsReport.put(falseHHH, 1d); } } } lastFalseHHHs = falseHHHs; return bottomUpHHHsReport; } protected boolean hasDescendantMonitors(Collection<WildcardPattern> monitors, WildcardPattern hhh) { boolean hasDescendantMonitor = false; for (WildcardPattern monitor : monitors) { if (hhh.match(monitor) && !hhh.equals(monitor)) { hasDescendantMonitor = true; break; } } return hasDescendantMonitor; } protected boolean checkForDescendantHHHs(List<WildcardPattern> falseHHHs, WildcardPattern hhh, double threshold, Collection<WildcardPattern> bottomUPHHHs, Collection<WildcardPattern> monitors) { List<WildcardPattern> descendantFalseHHHs = new ArrayList<>(); for (WildcardPattern falseHHH : falseHHHs) { if (hhh.match(falseHHH)) { if (falseHHH.getWeight() >= 2 * threshold) { return false; } else { //there is still hope that even if the descendant hhh is false, I am true descendantFalseHHHs.add(falseHHH); } } } if (descendantFalseHHHs.size() <= 0) { return true; } if (descendantFalseHHHs.size() > 0) { //check if descendentHHHs become smaller down to threshold, the hhh will still remain hhh Collection<WildcardPattern> directMonitors = getDirectMonitors(hhh, bottomUPHHHs, monitors); //Reduce the size of descendant false hhhs to weight-threshold, //as the real descendant hhh will take at least that much and the remaining will be gathered here for (WildcardPattern descendantFalseHHH : descendantFalseHHHs) { directMonitors.add(new WildcardPattern(descendantFalseHHH.getData(), descendantFalseHHH.getWildcardNum(), descendantFalseHHH.getWeight() - threshold)); } //now check and see if hhh is still an HHH based on monitors // the HHH is at least grandparent of descendant false hhhs so if //any of its children weight become>threshold, it is no longer an hhh try { WildcardPattern leftChild = hhh.clone().goDown(false); double rightSum = 0; double leftSum = 0; for (WildcardPattern newMonitor : directMonitors) { if (leftChild.match(newMonitor)) { leftSum += newMonitor.getWeight(); } else { rightSum += newMonitor.getWeight(); } } return leftSum < threshold && rightSum < threshold; } catch (WildcardPattern.InvalidWildCardValue invalidWildCardValue) { invalidWildCardValue.printStackTrace(); } } return false; } private Collection<WildcardPattern> getDirectMonitors(WildcardPattern hhh, Collection<WildcardPattern> bottomUpHHHs, Collection<WildcardPattern> monitors) { List<WildcardPattern> directMonitors = new LinkedList<>(monitors); for (Iterator<WildcardPattern> iterator = directMonitors.iterator(); iterator.hasNext(); ) { WildcardPattern newMonitor = iterator.next(); if (!hhh.match(newMonitor)) { iterator.remove(); } } for (WildcardPattern bHHH : bottomUpHHHs) { if (bHHH.getWildcardNum() >= hhh.getWildcardNum()) { //equal condition here also breaks hhh itself break; } if (hhh.match(bHHH)) { for (Iterator<WildcardPattern> iterator = directMonitors.iterator(); iterator.hasNext(); ) { WildcardPattern monitor = iterator.next(); if (bHHH.match(monitor)) { iterator.remove(); } } } } return directMonitors; } }