package uk.ac.imperial.lsds.seep.gc14.operator; import static uk.ac.imperial.lsds.seep.gc14.util.StaticSensorNetworkStructure.maxIndexHouseholds; import static uk.ac.imperial.lsds.seep.gc14.util.StaticSensorNetworkStructure.maxIndexPlugs; import static uk.ac.imperial.lsds.seep.gc14.util.StaticSensorNetworkStructure.numberHouses; import static uk.ac.imperial.lsds.seep.gc14.util.StaticSensorNetworkStructure.numberPlugs; import java.util.HashMap; import java.util.List; import java.util.Map; import uk.ac.imperial.lsds.seep.comm.serialization.DataTuple; import uk.ac.imperial.lsds.seep.gc14.util.SkipList; import uk.ac.imperial.lsds.seep.gc14.util.StaticSensorNetworkStructure; import uk.ac.imperial.lsds.seep.operator.StatelessOperator; public class Q2OutliersPart2 implements StatelessOperator { private static final long serialVersionUID = 1L; static final int windowOneHourInSec = 3600; static final int windowOneDayInSec = 86400; //memory fixed Map<Integer, Float> currentMedianOneHourPerPlug = new HashMap<Integer, Float>(); Map<Integer, Float> currentMedianOneDayPerPlug = new HashMap<Integer, Float>(); //memory variable SkipList valuesSortedByValueOneHour = null; SkipList valuesSortedByValueOneDay = null; float currentGlobalMedianOneHour = -1; float currentGlobalMedianOneDay = -1; //memory fixed Map<Integer, List<Integer>> housePlugs = new HashMap<Integer, List<Integer>>(); Map<Integer, Integer> plugHouses = new HashMap<Integer, Integer>(); //memory fixed Map<Integer, Float> shareOfOutlierPlugsOneHourPerHouse = new HashMap<Integer, Float>(); Map<Integer, Float> shareOfOutlierPlugsOneDayPerHouse = new HashMap<Integer, Float>(); //time control stuff int c = 0; int sec = 0; long init = System.currentTimeMillis(); int aggrRemove = 0; int aggrInsert = 0; @Override public void setUp() { //initialise lists here as transient methods become null after serialisation valuesSortedByValueOneHour = new SkipList(); valuesSortedByValueOneDay = new SkipList(); for (int i = 0; i < numberPlugs; i++) { currentMedianOneHourPerPlug.put(i, -1f); currentMedianOneDayPerPlug.put(i, -1f); } for (int i = 0; i < numberHouses; i++) { shareOfOutlierPlugsOneHourPerHouse.put(i,0f); shareOfOutlierPlugsOneDayPerHouse.put(i,0f); } housePlugs = StaticSensorNetworkStructure.getInstance().getHousePlugs(numberHouses, maxIndexHouseholds, maxIndexPlugs); plugHouses = StaticSensorNetworkStructure.getInstance().getPlugHouses(numberHouses, maxIndexHouseholds, maxIndexPlugs); } int lat_sampler = 0; @Override public void processData(DataTuple data) { c++; // System.out.println("Data: "+data); int timestamp = data.getInt("timestamp"); int ppointer = data.getInt("ppointer"); int window = data.getInt("window"); float plugMedian = data.getFloat("plugMedian"); float insertedValue = data.getFloat("value"); int[] removedValues = data.getIntArray("removedValues"); /* * Distinguish windows */ if (window == windowOneHourInSec) { // insert new values if (insertedValue != -1) { aggrInsert++; valuesSortedByValueOneHour.add(insertedValue); } /* * NOTE: cannot use removeAll since this would remove * ALL INSTANCES of the respective values */ // int sizeBeforeRemoval = valuesSortedByValueOneHour.size(); // int sizeOfElementsToRemove = removedValues.length; // boolean in = false; for (float toRemove : removedValues){ // in = true; aggrRemove++; valuesSortedByValueOneHour.remove(toRemove); } // if(in){ // if(sizeBeforeRemoval-sizeOfElementsToRemove != valuesSortedByValueOneHour.size()){ // System.out.println((valuesSortedByValueOneHour.size()-(sizeBeforeRemoval-sizeOfElementsToRemove))+" noremoved"); // } // } // new global median float newCurrentGlobalMedianOneHour = valuesSortedByValueOneHour.getMedian(); int onlyOneHouseToCheck = -1; if (newCurrentGlobalMedianOneHour == currentGlobalMedianOneHour) onlyOneHouseToCheck = plugHouses.get(ppointer); currentGlobalMedianOneHour = newCurrentGlobalMedianOneHour; lat_sampler++; long currentTime = System.currentTimeMillis(); if(lat_sampler > 2000){ long incomingInstTs = data.getPayload().instrumentation_ts; long latency = (currentTime - incomingInstTs); System.out.println("! "+latency); lat_sampler = 0; } /* * If global did not change and local did not change there is * nothing to do and we return */ if (onlyOneHouseToCheck != -1) { if (plugMedian == currentMedianOneHourPerPlug.get(ppointer)) return; } // store plug median currentMedianOneHourPerPlug.put(ppointer, plugMedian); if (onlyOneHouseToCheck != -1) checkHouseOneHour(data, timestamp, onlyOneHouseToCheck); else { // for each house for (int house : housePlugs.keySet()) checkHouseOneHour(data, timestamp, house); } } else { // insert new values if (insertedValue != -1) valuesSortedByValueOneDay.add(insertedValue); /* * NOTE: cannot use removeAll since this would remove * ALL INSTANCES of the respective values */ for (float toRemove : removedValues) valuesSortedByValueOneDay.remove(toRemove); // new global median float newCurrentGlobalMedianOneDay = valuesSortedByValueOneDay.getMedian(); int onlyOneHouseToCheck = -1; if (newCurrentGlobalMedianOneDay == currentGlobalMedianOneDay) onlyOneHouseToCheck = plugHouses.get(ppointer); currentGlobalMedianOneDay = newCurrentGlobalMedianOneDay; /* * If global did not change and local did not change there is * nothing to do and we return */ if (onlyOneHouseToCheck != -1) { if (plugMedian == currentMedianOneDayPerPlug.get(ppointer)) return; } // store plug median currentMedianOneDayPerPlug.put(ppointer, plugMedian); if (onlyOneHouseToCheck != -1) checkHouseOneDay(data, timestamp, onlyOneHouseToCheck); else { // for each house for (int house : housePlugs.keySet()) checkHouseOneDay(data, timestamp, house); } } if((System.currentTimeMillis() - init) > 1000){ System.out.println("Q22 "+c+" "); System.out.println("aggrRemove size: "+aggrRemove); System.out.println("aggrInsert size: "+aggrInsert); aggrRemove = 0; aggrInsert = 0; System.out.println("valuesSortedByValueOneHour: "+valuesSortedByValueOneHour.size()); c = 0; sec++; init = System.currentTimeMillis(); } } private void checkHouseOneDay(DataTuple data, int timestamp, int house) { int countOutliers = 0; for (int plug : housePlugs.get(house)) { if (currentMedianOneDayPerPlug.get(plug) > currentGlobalMedianOneDay) countOutliers++; } float shareOutliers = ((float)countOutliers)/ housePlugs.get(house).size(); // System.out.println("1d, mem: "+shareOfOutlierPlugsOneDayPerHouse.get(house)+" cur: "+shareOutliers); if (shareOfOutlierPlugsOneDayPerHouse.get(house) != shareOutliers) { shareOfOutlierPlugsOneDayPerHouse.put(house, shareOutliers); DataTuple output = data.setValues(timestamp - windowOneDayInSec, timestamp, house, shareOutliers); api.send(output); } } private void checkHouseOneHour(DataTuple data, int timestamp, int house) { int countOutliers = 0; for (int plug : housePlugs.get(house)) { if (currentMedianOneHourPerPlug.get(plug) > currentGlobalMedianOneHour) countOutliers++; } float shareOutliers = ((float)countOutliers)/ housePlugs.get(house).size(); // System.out.println("1h, mem: "+shareOfOutlierPlugsOneHourPerHouse.get(house)+" cur: "+shareOutliers); if (shareOfOutlierPlugsOneHourPerHouse.get(house) != shareOutliers) { shareOfOutlierPlugsOneHourPerHouse.put(house, shareOutliers); DataTuple output = data.setValues(timestamp - windowOneHourInSec, timestamp, house, shareOutliers); api.send(output); } } @Override public void processData(List<DataTuple> dataList) { } }