PartialStateSystemRequest(ITmfStateProvider sci, TmfTimeRange range) {
   super(
       ITmfEvent.class,
       range,
       0,
       ITmfEventRequest.ALL_DATA,
       ITmfEventRequest.ExecutionType.BACKGROUND);
   this.sci = sci;
   this.trace = sci.getTrace();
 }
    public CheckpointsRequest(ITmfStateProvider input, Map<Long, Long> checkpoints) {
      super(
          ITmfEvent.class,
          TmfTimeRange.ETERNITY,
          0,
          ITmfEventRequest.ALL_DATA,
          ITmfEventRequest.ExecutionType.FOREGROUND);
      checkpoints.clear();
      this.trace = input.getTrace();
      this.checkpts = checkpoints;
      eventCount = 0;
      lastCheckpointAt = 0;

      /* Insert a checkpoint at the start of the trace */
      checkpoints.put(input.getStartTime(), 0L);
    }
  @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();
  }
 private void registerCheckpoints() {
   ITmfEventRequest request = new CheckpointsRequest(fPartialInput, fCheckpoints);
   fPartialInput.getTrace().sendRequest(request);
   /* The request will countDown the checkpoints latch once it's finished */
 }