package com.plectix.simulator.staticanalysis.stories.storage; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.TreeMap; import com.plectix.simulator.staticanalysis.stories.ActionOfAEvent; class StoryBuilder { private final LinkedHashMap<WireHashKey, TreeMap<Long, AtomicEvent<?>>> storageWires = new LinkedHashMap<WireHashKey, TreeMap<Long, AtomicEvent<?>>>(); private boolean endFlag; public LinkedHashMap<WireHashKey, TreeMap<Long, AtomicEvent<?>>> getStorageWires() { return storageWires; } public final void addEventContainer(Event eventContainer) throws StoryStorageException { if (!tryToRemoveOppositeBlock(eventContainer)) { for (WireHashKey key : eventContainer.getAtomicEvents().keySet()) { TreeMap<Long, AtomicEvent<?>> tree = storageWires.get(key); if (tree == null) { tree = new TreeMap<Long, AtomicEvent<?>>(); storageWires.put(key, tree); } tree.put(eventContainer.getStepId(), eventContainer .getAtomicEvent(key)); } } } public void setFlagTrue() { endFlag = true; } final boolean tryToRemoveOppositeBlock(Event eventIn) { // may be need for all non-observable events if (endFlag) { return false; } LinkedHashMap<WireHashKey, AtomicEvent<?>> mapIn = getModificationAction(eventIn); Long stepId = eventIn.getStepId(); LinkedHashSet<WireHashKey> set = new LinkedHashSet<WireHashKey>(); LinkedHashSet<Event> listForDel = new LinkedHashSet<Event>(); WireHashKey key; for (Map.Entry<WireHashKey, AtomicEvent<?>> entry : mapIn.entrySet()) { key = entry.getKey(); AtomicEvent<?> aEvent = entry.getValue(); AtomicEvent<?> aEventCheck = getAtomicLastModificationAtomicEvent( key, aEvent, stepId); if (aEventCheck == null) return false; if (aEventCheck.getState().getBeforeState() == null || !aEventCheck.getState().getBeforeState().equals( aEvent.getState().getAfterState())) return false; set.addAll(getModificationAction(aEventCheck.getContainer()) .keySet()); listForDel.add(aEventCheck.getContainer()); } if (mapIn.size() != set.size()) return false; for (Event e : listForDel) { for (WireHashKey wk : e.getAtomicEvents().keySet()) { storageWires.get(wk).remove(e.getStepId()); if (storageWires.get(wk).size() == 0) { storageWires.remove(wk); } } } return true; } final LinkedHashMap<WireHashKey, AtomicEvent<?>> getModificationAction( Event eventIn) { LinkedHashMap<WireHashKey, AtomicEvent<?>> mapIn = new LinkedHashMap<WireHashKey, AtomicEvent<?>>(); for (Map.Entry<WireHashKey, AtomicEvent<?>> entry : eventIn .getAtomicEvents().entrySet()) { AtomicEvent<?> aEvent = entry.getValue(); if (aEvent.getType() != ActionOfAEvent.TEST) mapIn.put(entry.getKey(), aEvent); } return mapIn; } final AtomicEvent<?> getAtomicLastModificationAtomicEvent( WireHashKey key, AtomicEvent<?> aEventIn, Long stepId) { TreeMap<Long, AtomicEvent<?>> wire = storageWires.get(key); if (wire == null) return null; stepId = wire.lowerKey(stepId); if (stepId != null) { AtomicEvent<?> nextAevent = wire.get(stepId); if (nextAevent == null || nextAevent.getType() != ActionOfAEvent.TEST_AND_MODIFICATION) { return null; } else { return nextAevent; } } return null; } // It needs change LinkedHashSet<Event> -> LinkedHashSet<Long> final void handling(Event event, LinkedHashSet<Event> needEvents) throws StoryStorageException { for (Map.Entry<WireHashKey, AtomicEvent<?>> entry : event .getAtomicEvents().entrySet()) { WireHashKey key = entry.getKey(); AtomicEvent<?> aEvent = entry.getValue(); if (!storageWires.get(key).containsValue(aEvent)) { throw new StoryStorageException(""); } Event foundEvent = findCausing(key, aEvent, event.getStepId()); if (foundEvent != null && !needEvents.contains(foundEvent)) { needEvents.add(foundEvent); handling(foundEvent, needEvents); } } } final Event findCausing(WireHashKey key, AtomicEvent<?> event, Long stepId) throws StoryStorageException { TreeMap<Long, AtomicEvent<?>> wire = storageWires.get(key); if (wire == null) { throw new StoryStorageException(" Wire = null!!!! and key = " + key); } stepId = wire.lowerKey(stepId); if (stepId == null) return event.getContainer(); AtomicEvent<?> nextAevent = wire.get(stepId); if (stepId != null) { while (nextAevent != null && nextAevent.getType() == ActionOfAEvent.TEST) { stepId = wire.lowerKey(stepId); if (stepId == null) return event.getContainer(); nextAevent = wire.get(stepId); } } return nextAevent.getContainer(); } }