/** * Constructor * * @param ssid The state system's ID * @param partialInput The state change input object that was used to build the upstream state * system. This partial history will make its own copy (since they have different targets). * @param pss The partial history's inner state system. It should already be assigned to * partialInput. * @param realBackend The real state history back-end to use. It's supposed to be modular, so it * should be able to be of any type. * @param granularity Configuration parameter indicating how many trace events there should be * between each checkpoint */ public PartialHistoryBackend( @NonNull String ssid, ITmfStateProvider partialInput, PartialStateSystem pss, IStateHistoryBackend realBackend, long granularity) { if (granularity <= 0 || partialInput == null || pss == null || partialInput.getAssignedStateSystem() != pss) { throw new IllegalArgumentException(); } final long startTime = realBackend.getStartTime(); fSSID = ssid; fPartialInput = partialInput; fPartialSS = pss; fInnerHistory = realBackend; fGranularity = granularity; fLatestTime = startTime; registerCheckpoints(); }
@Override public void insertPastState( long stateStartTime, long stateEndTime, int quark, ITmfStateValue value) throws TimeRangeException { waitForCheckpoints(); /* Update the latest time */ if (stateEndTime > fLatestTime) { fLatestTime = stateEndTime; } /* * Check if the interval intersects the previous checkpoint. If so, * insert it in the real history back-end. * * FIXME since intervals are inserted in order of rank, we could avoid * doing a map lookup every time here (just compare with the known * previous one). */ if (stateStartTime <= fCheckpoints.floorKey(stateEndTime)) { fInnerHistory.insertPastState(stateStartTime, stateEndTime, quark, value); } }
@Override public void doQuery(List<@Nullable ITmfStateInterval> currentStateInfo, long t) throws TimeRangeException, StateSystemDisposedException { /* Wait for required steps to be done */ waitForCheckpoints(); fPartialSS.getUpstreamSS().waitUntilBuilt(); if (!checkValidTime(t)) { throw new TimeRangeException( fSSID + " Time:" + t + ", Start:" + getStartTime() + ", End:" + getEndTime()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } /* Reload the previous checkpoint */ long checkpointTime = fCheckpoints.floorKey(t); fInnerHistory.doQuery(currentStateInfo, checkpointTime); /* * Set the initial contents of the partial state system (which is the * contents of the query at the checkpoint). */ List<@NonNull ITmfStateInterval> filledStateInfo = checkNotNullContents(currentStateInfo.stream()).collect(Collectors.toList()); fPartialSS.takeQueryLock(); fPartialSS.replaceOngoingState(filledStateInfo); /* Send an event request to update the state system to the target time. */ TmfTimeRange range = new TmfTimeRange( /* * The state at the checkpoint already includes any state change * caused by the event(s) happening exactly at 'checkpointTime', * if any. We must not include those events in the query. */ TmfTimestamp.fromNanos(checkpointTime + 1), TmfTimestamp.fromNanos(t)); ITmfEventRequest request = new PartialStateSystemRequest(fPartialInput, range); fPartialInput.getTrace().sendRequest(request); try { request.waitForCompletion(); } catch (InterruptedException e) { e.printStackTrace(); } /* * Now the partial state system should have the ongoing time we are * looking for. However, the method expects a List of *state intervals*, * not state values, so we'll create intervals with a dummy end time. */ for (int i = 0; i < currentStateInfo.size(); i++) { long start = 0; start = ((ITmfStateSystem) fPartialSS).getOngoingStartTime(i); ITmfStateValue val = ((ITmfStateSystem) fPartialSS).queryOngoingState(i); ITmfStateInterval interval = new TmfStateInterval(start, t, i, checkNotNull(val)); currentStateInfo.set(i, interval); } fPartialSS.releaseQueryLock(); }
@Override public void dispose() { fPartialInput.dispose(); fPartialSS.dispose(); fInnerHistory.dispose(); }
@Override public void removeFiles() { fInnerHistory.removeFiles(); }
@Override public long supplyAttributeTreeWriterFilePosition() { return fInnerHistory.supplyAttributeTreeWriterFilePosition(); }
@Override public File supplyAttributeTreeWriterFile() { return fInnerHistory.supplyAttributeTreeWriterFile(); }
@Override public FileInputStream supplyAttributeTreeReader() { return fInnerHistory.supplyAttributeTreeReader(); }
@Override public void finishedBuilding(long endTime) throws TimeRangeException { fInnerHistory.finishedBuilding(endTime); }
@Override public long getStartTime() { return fInnerHistory.getStartTime(); }