package ch.epfl.data.squall.components.signal_components; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map.Entry; public class Histogram { private HashMap<Integer, Integer> _statsMap; private HashSet<Integer> _frequentSet; private int _windowCountThreshold; private int _frequentThreshold; private int _currentWindowSize=0; /* * windowCountThreshold needs to be much more than frequentThreshold */ public Histogram(int windowCountThreshold, int frequentThreshold) { _statsMap = new HashMap<Integer, Integer>(); _windowCountThreshold = windowCountThreshold; _frequentThreshold = frequentThreshold; _frequentSet= new HashSet<Integer>(); } //returns null if no change or the updated frequencies public HashSet<Integer> update(HashMap<Integer, Integer> stats){ for (Entry<Integer, Integer> element : stats.entrySet()) { int key=element.getKey(); int value= element.getValue(); Integer localValue= _statsMap.get(key); _currentWindowSize+=value; int updateValue=0; if(localValue!=null) updateValue=value+localValue; else updateValue=value; _statsMap.put(key, updateValue); } //Check if reached the WindowThreshold if(_currentWindowSize>_windowCountThreshold){ HashSet<Integer> newSet = getNewFrequentSet(); if(isChanged(_frequentSet, newSet)){ _frequentSet=newSet; clear(); return _frequentSet; } clear(); return null; } return null; } private void clear(){ _statsMap.clear(); _currentWindowSize=0; } private boolean isChanged(HashSet<Integer> h1, HashSet<Integer> h2) { if ( h1.size() != h2.size() ) { return true; } HashSet<Integer> clone = new HashSet<Integer>(h2); Iterator<Integer> it = h1.iterator(); while (it.hasNext() ){ int A = it.next(); if (clone.contains(A)){ clone.remove(A); } else { return true; } } return false; } private HashSet<Integer> getNewFrequentSet(){ HashSet<Integer> newSet = new HashSet<>(); for (Entry<Integer, Integer> entry: _statsMap.entrySet()) { int value = entry.getValue(); if(value < _frequentThreshold) continue; int key= entry.getKey(); newSet.add(key); } return newSet; } }