/* * StreamCruncher: Copyright (c) 2006-2008, Ashwin Jayaprakash. All Rights Reserved. * Contact: ashwin {dot} jayaprakash {at} gmail {dot} com * Web: http://www.StreamCruncher.com * * This file is part of StreamCruncher. * * StreamCruncher is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * StreamCruncher 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with StreamCruncher. If not, see <http://www.gnu.org/licenses/>. */ package streamcruncher.innards.core.partition.correlation; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; /* * Author: Ashwin Jayaprakash Date: Feb 26, 2007 Time: 6:39:43 PM */ public class DelayedMatcher extends ImmediateMatcher { protected final Set<Object> waitAndWatchCorrIdList; protected final List<Object> emptyList; public DelayedMatcher(String[] presentAliases, String[] notPresentAliases) { super(presentAliases, notPresentAliases); this.waitAndWatchCorrIdList = new HashSet<Object>(); this.emptyList = new ArrayList<Object>(); } // ---------- @Override public void eventExpelled(String alias, Object id) { int bitPositionForAlias = aliasAndBitPatterns.get(alias); Integer pattern = workingPatternSet.get(id); if (pattern == null) { pattern = stalePatternSet.get(id); if (pattern == null) { // Can't happen. } else { pattern = pattern & ~bitPositionForAlias; if (pattern == 0) { stalePatternSet.remove(id); waitAndWatchCorrIdList.remove(id); } else { // Put it back. Nothing further to do. stalePatternSet.put(id, pattern); } } } else { Integer oldPattern = pattern; pattern = pattern & ~bitPositionForAlias; /* * Patterns that change to "Hit" when an Event is expelled are * ignored. Because it means that a Present and Not-Present Alias * was "on" and now the Not-Present Event got expelled, so the * Pattern is being asserted now, which is not what we want. We are * only looking for Patterns that were "on" and now because one of * the Key Aliases is being expelled, the Pattern is "off". Also, we * only want to trigger Patterns that got asserted as virgin * Present-Only patterns and not ones that changed to Present-Only * Patterns along the way. */ if (oldPattern == targetBitPattern && waitAndWatchCorrIdList.contains(id) == true) { /* * Put this Corr-Id into potential hit list. Wait for * endExpulsions() to see if this Pattern makes it to the end. */ corrIdSessionHitList.add(id); } if (pattern == 0) { workingPatternSet.remove(id); waitAndWatchCorrIdList.remove(id); } else { // Put it back. workingPatternSet.put(id, pattern); } } } @Override public List<Object> endExpulsions() { ArrayList<Object> results = new ArrayList<Object>(corrIdSessionHitList); for (Iterator iter = corrIdSessionHitList.iterator(); iter.hasNext();) { Object staleId = iter.next(); iter.remove(); Integer pattern = workingPatternSet.remove(staleId); stalePatternSet.put(staleId, pattern); waitAndWatchCorrIdList.remove(staleId); } return results; } @Override protected void handleWorkingSetArrival(Object id, int bitPositionForAlias, Integer pattern) { Integer updatedPattern = pattern | bitPositionForAlias; if (updatedPattern == targetBitPattern) { /* * Put this Corr-Id into potential hit list. Wait for endArrivals() * to see if this Pattern makes it to the end. */ corrIdSessionHitList.add(id); } else { /* * Withdraw from hit list (if present) as a Not-Required Event also * arrived in this cycle along with a Required Event. */ corrIdSessionHitList.remove(id); /* * And event was asserted as a virgin Present-Only Pattern (110), * and then later the Not-Present alias arrived and went out before * or along with a Present alias. [110 -> 111 -> 110 -> 100*] Since * this scenario does not leave the Pattern as a virgin pattern, it * has to be removed from the list. */ waitAndWatchCorrIdList.remove(id); } workingPatternSet.put(id, updatedPattern); } @Override public List<Object> endArrivals() { /* * Don't send these off immediately. Wait and watch. */ waitAndWatchCorrIdList.addAll(corrIdSessionHitList); corrIdSessionHitList.clear(); return emptyList; } }