package com.plectix.simulator.staticanalysis.stories.storage; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import com.plectix.simulator.staticanalysis.stories.ActionOfAEvent; import com.plectix.simulator.staticanalysis.stories.MarkOfEvent; import com.plectix.simulator.staticanalysis.stories.State; import com.plectix.simulator.staticanalysis.stories.TypeOfWire; import com.plectix.simulator.staticanalysis.stories.compressions.CompressionPassport; public final class AbstractStorage implements WireStorageInterface { // wireHashKey - wireId // Long - number of Event private LinkedHashMap<WireHashKey, TreeMap<Long, AtomicEvent<?>>> storageWires; private Set<Event> events; private final MasterInformationAboutWires informationAboutWires; // initial solution we interpret as initial event. It has Id= -1 private Event initialEvent; // goal of the story. We interests about cause for its occurrence private Event observableEvent; private double averageTime; private final int iteration; // need for refactoring... private StoragePassport passport; private final StoriesAgentTypesStorage storiesAgentTypesStorage; private StoryBuilder builder; public AbstractStorage(int iteration, StoriesAgentTypesStorage typeById) { this.iteration = iteration; storageWires = new LinkedHashMap<WireHashKey, TreeMap<Long, AtomicEvent<?>>>(); events = new LinkedHashSet<Event>(); observableEvent = null; initialEvent = null; builder = new StoryBuilder(); this.storiesAgentTypesStorage = typeById; informationAboutWires = new MasterInformationAboutWires( new LinkedHashMap<WireHashKey, LinkedHashSet<String>>(), new LinkedHashMap<WireHashKey, LinkedHashSet<StateOfLink>>(), new LinkedHashMap<WireHashKey, Integer>()); } public final EventIteratorInterface eventIterator(WireHashKey wkey, Long first, boolean reverse) throws StoryStorageException { return new EventIteratorOnWire(storageWires.get(wkey), first, reverse); } public final AtomicEvent<?> getAtomicEvent(WireHashKey wkey, Long event) { return storageWires.get(wkey).get(event); } /** * mark all events (without initial event with stepId=-1) */ public final void markAllUnresolved() throws StoryStorageException { concordWires(); for (Event event : events) { if (event == null) { continue; } if (event.getStepId() != -1) { event.setMarkUnresolved(informationAboutWires); } } } public final boolean markAllUnresolvedAsDeleted() throws StoryStorageException { boolean deleted = false; for (Event event : events) { if (event.getMark() == MarkOfEvent.UNRESOLVED) { event.setMark(MarkOfEvent.DELETED, informationAboutWires); deleted = true; } } return deleted; } public final Event initialEvent() throws StoryStorageException { if (initialEvent == null) { throw new StoryStorageException("initial event is null!"); } return initialEvent; } public final Event observableEvent() throws StoryStorageException { if (observableEvent == null) { throw new StoryStorageException("observable event is null!"); } return observableEvent; } public final EventIteratorInterface eventIterator(WireHashKey wkey, boolean reverse) throws StoryStorageException { if (reverse) { return new EventIteratorOnWire(storageWires.get(wkey), storageWires .get(wkey).lastKey(), reverse); } else { return new EventIteratorOnWire(storageWires.get(wkey), storageWires .get(wkey).firstKey(), reverse); } } public final void addLastEventContainer(Event eventContainer, double currentTime) throws StoryStorageException { observableEvent = eventContainer; averageTime = currentTime; builder.setFlagTrue(); addEventContainer(eventContainer); handling(); } final void addEventContainerAndFullOtherMaps(Event eventContainer) throws StoryStorageException { // if (!isOpposite(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)); events.add(eventContainer); if (key.getTypeOfWire() == TypeOfWire.INTERNAL_STATE) { if (informationAboutWires.getInternalStatesByWire().get(key) == null) { LinkedHashSet<String> internalStates = new LinkedHashSet<String>(); informationAboutWires.getInternalStatesByWire().put(key, internalStates); } if (eventContainer.getAtomicEvent(key).getType() == ActionOfAEvent.TEST_AND_MODIFICATION) { informationAboutWires.getInternalStatesByWire().get(key) .add( (String) (eventContainer .getAtomicEvent(key).getState() .getAfterState())); informationAboutWires.getInternalStatesByWire().get(key) .add( (String) (eventContainer .getAtomicEvent(key).getState() .getBeforeState())); } if (eventContainer.getAtomicEvent(key).getType() == ActionOfAEvent.MODIFICATION) { informationAboutWires.getInternalStatesByWire().get(key) .add( (String) (eventContainer .getAtomicEvent(key).getState() .getAfterState())); } } else if (key.getTypeOfWire() == TypeOfWire.LINK_STATE) { if (informationAboutWires.getLinkStatesByWire().get(key) == null) { LinkedHashSet<StateOfLink> linkStates = new LinkedHashSet<StateOfLink>(); informationAboutWires.getLinkStatesByWire().put(key, linkStates); } switch (eventContainer.getAtomicEvent(key).getType()) { case TEST_AND_MODIFICATION: StateOfLink before = (StateOfLink) (eventContainer .getAtomicEvent(key).getState().getBeforeState()); if (before != null && !before.isFree()) informationAboutWires.getLinkStatesByWire().get(key) .add(before); case MODIFICATION: StateOfLink after = (StateOfLink) (eventContainer .getAtomicEvent(key).getState().getAfterState()); if (after != null && !after.isFree()) informationAboutWires.getLinkStatesByWire().get(key) .add(after); break; } } } } public final void addEventContainer(Event eventContainer) throws StoryStorageException { builder.addEventContainer(eventContainer); } /** * return true if there is finished story ^) */ public final boolean isImportantStory() { return observableEvent != null; } /** * not implemented */ public final void clearList() { storageWires.clear(); } public final void handling() throws StoryStorageException { LinkedHashSet<Event> needEvents = new LinkedHashSet<Event>(); needEvents.add(observableEvent); builder.handling(observableEvent, needEvents); builder = null; clearStorage(needEvents); extractPassportMock(); } /** * full other maps and fields * * @param needEvents * @throws StoryStorageException */ final void clearStorage(LinkedHashSet<Event> needEvents) throws StoryStorageException { storageWires = new LinkedHashMap<WireHashKey, TreeMap<Long, AtomicEvent<?>>>(); events = new LinkedHashSet<Event>(); for (Event event : needEvents) { addEventContainerAndFullOtherMaps(event); } initialize(); concordWires(); } final void initialize() throws StoryStorageException { initialEvent = new Event(-1, -1); AtomicEvent<?> initialAEvent; Long p; int temp = 0; Map<WireHashKey, AtomicEvent<?>> map = new LinkedHashMap<WireHashKey, AtomicEvent<?>>(); for (WireHashKey key : storageWires.keySet()) { p = storageWires.get(key).firstKey(); initialAEvent = storageWires.get(key).get(p); // if (initialAEvent.getState().getBeforeState() == null) { continue; } p = Long.valueOf(0); if (initialEvent.getAtomicEvents().get(key) == null) { AtomicEvent<?> initialAEvent2; initialAEvent2 = initialAEvent.cloneWithBefore(initialEvent); map.put(key, initialAEvent2); initialEvent.addToFilter(key); temp++; initialEvent.getAtomicEvents().put(key, initialAEvent2); if (storageWires.get(key) == null) { throw new StoryStorageException(""); } storageWires.get(key).put(Long.valueOf(-1), initialAEvent2); if (initialAEvent.getType() == ActionOfAEvent.TEST && key.getTypeOfWire() == TypeOfWire.INTERNAL_STATE) { informationAboutWires.getInternalStatesByWire().get(key) .add( (String) (initialAEvent.getState() .getBeforeState())); } if (initialAEvent.getType() == ActionOfAEvent.TEST && key.getTypeOfWire() == TypeOfWire.LINK_STATE) { informationAboutWires.getLinkStatesByWire().get(key).add( (StateOfLink) (initialAEvent.getState() .getBeforeState())); } } } if (temp > 0) { initialEvent.setMark(MarkOfEvent.KEPT, informationAboutWires); events.add(initialEvent); } else { } } private final void concordWires() { for (WireHashKey wKey : storageWires.keySet()) { informationAboutWires.putUnresolvedModifyEvent(wKey, 0); } } public final Map<WireHashKey, TreeMap<Long, AtomicEvent<?>>> getStorageWires() { return storageWires; } public final Set<Event> getEvents() { return events; } final void extractPassportMock() { passport = new StoragePassport(this); } /** * return true if removed successfully else remove nothing i think that * arraylist - wires from one agent */ public final boolean removeWire(ArrayList<WireHashKey> wireKeys) { boolean removed = true; boolean deleteInitial = false; for (WireHashKey wk : wireKeys) { TreeMap<Long, AtomicEvent<?>> w = storageWires.get(wk); if (!w.isEmpty()) { if (w.size() > 1 || w.firstKey() != -1) { removed = false; break; } if (!deleteInitial) { deleteInitial = true; } } } if (deleteInitial) { for (WireHashKey wk : wireKeys) { if (wk.getTypeOfWire() == TypeOfWire.BOUND_FREE) { if ((State) (storageWires.get(wk).get(Long.valueOf(-1)) .getState().getAfterState()) != State.FREE_LINK_STATE) { removed = false; } } } } if (removed) { for (WireHashKey wk : wireKeys) { storageWires.remove(wk); informationAboutWires.removeWire(wk); initialEvent.removeWire(wk); } } return removed; } public final CompressionPassport extractPassport() { return passport; } // atomicEvents from wk1 to wk2, first event // change storageWires,internalStatesByWire,numberOfUnresolvedEventOnWire public final void replaceWireToWire(Map<WireHashKey, WireHashKey> map, Long firstEventId, boolean swapTop, TreeMap<Long, AtomicEvent<?>> allEventsByNumber) throws StoryStorageException { LinkedHashSet<Long> stepIdOfEvents = new LinkedHashSet<Long>(); for (WireHashKey wk : map.keySet()) { stepIdOfEvents .addAll(stepIdEventsOnWire(wk, firstEventId, swapTop)); stepIdOfEvents.addAll(stepIdEventsOnWire(map.get(wk), firstEventId, swapTop)); } for (Long number : stepIdOfEvents) { if (number == null) { throw new StoryStorageException("wire = null"); } if (allEventsByNumber.get(number) == null) { throw new StoryStorageException(observableEvent.getStepId()+ " " + number); } if (allEventsByNumber.get(number).getContainer() == null) { throw new StoryStorageException("container = null"); } // rebuild event and numberOfUnresolvedevents on wires List<PointRound> changes = allEventsByNumber.get(number) .getContainer().exchangeWires(map, informationAboutWires); correctChanges(changes); } } final Set<Long> stepIdEventsOnWire(WireHashKey wk, Long firstEventId, boolean swapTop) { if (swapTop) { return storageWires.get(wk).subMap(Long.valueOf(-1), firstEventId + 1).keySet(); } else { return storageWires.get(wk).subMap(firstEventId, observableEvent.getStepId() + 1).keySet(); } } // change storageWires,internalStatesByWire final void correctChanges(List<PointRound> changes) throws StoryStorageException { for (PointRound pr : changes) { Long stepIdOfEvent = pr.number; if (storageWires.get(pr.wk1).get(stepIdOfEvent) == null && storageWires.get(pr.wk2).get(stepIdOfEvent) == null) { throw new StoryStorageException("empty change"); } AtomicEvent<?> ae1 = storageWires.get(pr.wk1).remove(stepIdOfEvent); AtomicEvent<?> ae2 = storageWires.get(pr.wk2).remove(stepIdOfEvent); if (ae1 == null) { storageWires.get(pr.wk1).put(stepIdOfEvent, ae2); continue; } if (ae2 == null) { storageWires.get(pr.wk2).put(stepIdOfEvent, ae1); continue; } storageWires.get(pr.wk1).put(stepIdOfEvent, ae2); storageWires.get(pr.wk2).put(stepIdOfEvent, ae1); } } public final void markAllNull() { for (WireHashKey wk : storageWires.keySet()) { informationAboutWires.getNumberOfUnresolvedEventOnWire().put(wk, 0); } for (Event event : events) { if (event.getStepId() != -1) { event.onlySetMark(null); } } } public final double getAverageTime() { return averageTime; } public final int getIteration() { return iteration; } public final StoriesAgentTypesStorage getStoriesAgentTypesStorage() { return storiesAgentTypesStorage; } @Override public void updateWires(Set<WireHashKey> sets) throws StoryStorageException { informationAboutWires.updateWires(sets, storageWires); } @Override public boolean tryToSwap(long agentId, WireHashKey wk) { if (wk.getTypeOfWire() == TypeOfWire.LINK_STATE) { return informationAboutWires.tryToSwapLink(agentId, storageWires .get(wk)); } return true; } public MasterInformationAboutWires getInformationAboutWires() { return informationAboutWires; } }