/** Test toStrings */
 @Test
 public void testToString() {
   final String expectedLinear = "TmfTimestampTransformLinearFast [ slope = 314.0, offset = 0.0 ]";
   final String expectedLinearBigDec =
       "TmfTimestampTransformLinearFast [ slope = 314, offset = 0 ]";
   final String expectedOffset = "TmfConstantTransform [ offset = 314 ]";
   final String expectedIdentity = "TmfTimestampTransform [ IDENTITY ]";
   final String expectedOffset100 = "TmfConstantTransform [ offset = 100 ]";
   assertEquals(expectedLinear, TimestampTransformFactory.createLinear(314, 0).toString());
   assertEquals(
       expectedLinearBigDec,
       TimestampTransformFactory.createLinear(
               NonNullUtils.checkNotNull(BigDecimal.valueOf(314)),
               NonNullUtils.checkNotNull(BigDecimal.ZERO))
           .toString());
   assertEquals(expectedOffset, TimestampTransformFactory.createLinear(1, 314).toString());
   assertEquals(expectedOffset, TimestampTransformFactory.createWithOffset(314).toString());
   assertEquals(
       expectedOffset,
       TimestampTransformFactory.createWithOffset(14)
           .composeWith(TimestampTransformFactory.createWithOffset(300))
           .toString());
   assertEquals(
       expectedIdentity,
       TimestampTransformFactory.createWithOffset(314)
           .composeWith(TimestampTransformFactory.createWithOffset(-314))
           .toString());
   assertEquals(expectedIdentity, TimestampTransformFactory.createWithOffset(0).toString());
   assertEquals(expectedIdentity, identity1.toString());
   assertEquals(expectedOffset100, offset1.toString());
   assertEquals(expectedOffset100, offset2.toString());
   assertEquals(expectedOffset100, offset3.toString());
   assertEquals(expectedOffset100, offset4.toString());
 }
/**
 * This class represents a virtual CPU, which is a CPU running on a guest. It associates the guest
 * CPU ID to a virtual machine of the model.
 *
 * @author Geneviève Bastien
 */
public class VirtualCPU {

  private static final Table<VirtualMachine, Long, VirtualCPU> VIRTUAL_CPU_TABLE =
      NonNullUtils.checkNotNull(HashBasedTable.<VirtualMachine, Long, VirtualCPU>create());

  private final VirtualMachine fVm;
  private final Long fCpuId;

  /**
   * Return the virtual CPU for to the virtual machine and requested CPU ID
   *
   * @param vm The virtual machine
   * @param cpu the CPU number
   * @return the virtual CPU
   */
  public static synchronized VirtualCPU getVirtualCPU(VirtualMachine vm, Long cpu) {
    VirtualCPU ht = VIRTUAL_CPU_TABLE.get(vm, cpu);
    if (ht == null) {
      ht = new VirtualCPU(vm, cpu);
      VIRTUAL_CPU_TABLE.put(vm, cpu, ht);
    }
    return ht;
  }

  private VirtualCPU(VirtualMachine vm, Long cpu) {
    fVm = vm;
    fCpuId = cpu;
  }

  /**
   * Get the CPU ID of this virtual CPU
   *
   * @return The zero-based CPU ID
   */
  public Long getCpuId() {
    return fCpuId;
  }

  /**
   * Get the virtual machine object this virtual CPU belongs to
   *
   * @return The guest Virtual Machine
   */
  public VirtualMachine getVm() {
    return fVm;
  }

  @Override
  public String toString() {
    return "VirtualCPU: [" + fVm + ',' + fCpuId + ']'; // $NON-NLS-1$
  }
}
/**
 * Timestamp transform tests
 *
 * @author Matthew Khouzam
 */
@NonNullByDefault
public class TsTransformFactoryTest {
  private final ITmfTimestamp t0 = TmfTimestamp.fromSeconds(0);
  private final ITmfTimestamp t100 = TmfTimestamp.fromSeconds(100);
  private final ITmfTimestamp t1e2 = TmfTimestamp.create(1, 2);
  private final ITmfTimestamp t1e3 = TmfTimestamp.create(1, 3);
  private final ITmfTimestamp tn0 = TmfTimestamp.fromNanos(0);
  private final ITmfTimestamp tn100 = TmfTimestamp.fromNanos(100);
  private final ITmfTimestamp tn1 = TmfTimestamp.fromNanos(1);
  private final ITmfTimestampTransform identity1 =
      TimestampTransformFactory.createLinear(1.0, TmfTimestamp.fromNanos(0));
  private final ITmfTimestampTransform offset1 = TimestampTransformFactory.createWithOffset(100);
  private final ITmfTimestampTransform offset2 =
      TimestampTransformFactory.createLinear(
          NonNullUtils.checkNotNull(BigDecimal.ONE),
          NonNullUtils.checkNotNull(new BigDecimal(100)));
  private final ITmfTimestampTransform offset3 = TimestampTransformFactory.createLinear(1.0, 100);
  private final ITmfTimestampTransform offset4 =
      TimestampTransformFactory.createLinear(1.0, TmfTimestamp.fromNanos(100));

  /** Test with identity */
  @Test
  public void transformIdentity() {
    final ITmfTimestampTransform identity = TimestampTransformFactory.createWithOffset(0);
    final ITmfTimestampTransform innefficientIdentity = new TmfConstantTransform();
    final ITmfTimestampTransform compositeInnefficientIdentity =
        identity.composeWith(innefficientIdentity);
    final ITmfTimestampTransform compositeInnefficientIdentity2 =
        innefficientIdentity.composeWith(innefficientIdentity);
    final ITmfTimestampTransform compositeInnefficientIdentity3 =
        innefficientIdentity.composeWith(identity);
    assertEquals(t0, identity.transform(t0));
    assertEquals(tn0, identity.transform(tn0));
    assertEquals(t100, identity.transform(t100));
    assertEquals(t1e2, identity.transform(t100));
    assertEquals(t1e2, identity.transform(t1e2));
    assertEquals(t1e3, identity.transform(t1e3));
    assertEquals(tn100, identity.transform(tn100));
    assertEquals(t0, innefficientIdentity.transform(t0)); // bad practice
    assertEquals(t0, compositeInnefficientIdentity.transform(t0)); // bad
    // practice
    assertEquals(t0, compositeInnefficientIdentity2.transform(t0)); // bad
    // practice
    assertEquals(t0, compositeInnefficientIdentity3.transform(t0)); // bad
    // practice
  }

  /** Test with an offset of 100 */
  @Test
  public void transformOffset() {
    final ITmfTimestampTransform offset = offset1;
    final ITmfTimestampTransform compositeTransform =
        offset.composeWith(
            TimestampTransformFactory.createWithOffset(TmfTimestamp.fromNanos(-100)));
    assertEquals(tn100, offset.transform(t0));
    assertEquals(tn100, offset.transform(tn0));
    assertEquals(tn0, compositeTransform.transform(tn0));
    assertEquals(t0, compositeTransform.transform(t0));
    assertEquals(200, offset1.transform(100));
    assertEquals(200, offset2.transform(100));
    assertEquals(200, offset3.transform(100));
    assertEquals(200, offset4.transform(100));
  }

  /** Test with a slope */
  @Test
  public void transformSlope() {
    final ITmfTimestampTransform slope = TimestampTransformFactory.createLinear(10, 0);
    final ITmfTimestampTransform slope1 =
        TimestampTransformFactory.createLinear(10.0, TmfTimestamp.fromNanos(0));
    assertEquals(t1e3, slope.transform(t1e2));
    assertEquals(tn100, slope.transform(TmfTimestamp.fromNanos(10)));
    assertEquals(tn100, slope.transform(slope.transform(tn1)));
    assertEquals(tn100, slope.composeWith(slope).transform(tn1));
    assertEquals(tn100, slope1.transform(TmfTimestamp.fromNanos(10)));
  }

  /** Test toStrings */
  @Test
  public void testToString() {
    final String expectedLinear = "TmfTimestampTransformLinearFast [ slope = 314.0, offset = 0.0 ]";
    final String expectedLinearBigDec =
        "TmfTimestampTransformLinearFast [ slope = 314, offset = 0 ]";
    final String expectedOffset = "TmfConstantTransform [ offset = 314 ]";
    final String expectedIdentity = "TmfTimestampTransform [ IDENTITY ]";
    final String expectedOffset100 = "TmfConstantTransform [ offset = 100 ]";
    assertEquals(expectedLinear, TimestampTransformFactory.createLinear(314, 0).toString());
    assertEquals(
        expectedLinearBigDec,
        TimestampTransformFactory.createLinear(
                NonNullUtils.checkNotNull(BigDecimal.valueOf(314)),
                NonNullUtils.checkNotNull(BigDecimal.ZERO))
            .toString());
    assertEquals(expectedOffset, TimestampTransformFactory.createLinear(1, 314).toString());
    assertEquals(expectedOffset, TimestampTransformFactory.createWithOffset(314).toString());
    assertEquals(
        expectedOffset,
        TimestampTransformFactory.createWithOffset(14)
            .composeWith(TimestampTransformFactory.createWithOffset(300))
            .toString());
    assertEquals(
        expectedIdentity,
        TimestampTransformFactory.createWithOffset(314)
            .composeWith(TimestampTransformFactory.createWithOffset(-314))
            .toString());
    assertEquals(expectedIdentity, TimestampTransformFactory.createWithOffset(0).toString());
    assertEquals(expectedIdentity, identity1.toString());
    assertEquals(expectedOffset100, offset1.toString());
    assertEquals(expectedOffset100, offset2.toString());
    assertEquals(expectedOffset100, offset3.toString());
    assertEquals(expectedOffset100, offset4.toString());
  }
}
  @Override
  protected void buildEntryList(
      @NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor) {
    // TODO Auto-generated method stub
    // TODO Auto-generated method stub
    final ITmfStateSystem ssq =
        TmfStateSystemAnalysisModule.getStateSystem(trace, OPS_NEUTRON_MODULE.ID);
    if (ssq == null) {
      return;
    }

    Comparator<ITimeGraphEntry> comparator =
        new Comparator<ITimeGraphEntry>() {
          @Override
          public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
            return ((OPS_NEUTRON_ENTRY) o1).compareTo(o2);
          }
        };

    // Map<Integer, ServiceEntry> entryMap = new HashMap<>();
    TimeGraphEntry traceEntry = null;
    TimeGraphEntry traceEntry1 = null;
    Map<String, TimeGraphEntry> mapservice = new HashMap();
    long startTime = ssq.getStartTime();
    long start = startTime;
    setStartTime(Math.min(getStartTime(), startTime));
    boolean complete = false;
    while (!complete) {
      if (monitor.isCanceled()) {
        return;
      }
      complete = ssq.waitUntilBuilt(BUILD_UPDATE_TIMEOUT);
      if (ssq.isCancelled()) {
        return;
      }
      long end = ssq.getCurrentEndTime();
      if (start == end && !complete) { // when complete execute one last time regardless of end time
        continue;
      }
      long endTime = end + 1;
      setEndTime(Math.max(getEndTime(), endTime));

      if (traceEntry == null) {
        traceEntry = new OPS_NEUTRON_ENTRY(trace, trace.getName(), startTime, endTime, "SERVICEs");
        traceEntry.sortChildren(comparator);
        List<TimeGraphEntry> entryList = Collections.singletonList(traceEntry);
        addToEntryList(parentTrace, ssq, entryList);
      } else {
        traceEntry.updateEndTime(endTime);
      } // ---------
      if (traceEntry1 == null) {
        traceEntry1 = new OPS_NEUTRON_ENTRY(trace, trace.getName(), startTime, endTime, "SERVICEs");
      } else {
        traceEntry1.updateEndTime(endTime);
      }

      List<Integer> servicesQuarks = ssq.getQuarks("SERVICEs", "*"); // $NON-NLS-1$
      for (Integer serviceQuark : servicesQuarks) {
        String serv = ssq.getAttributeName(serviceQuark).toString();
        if (serv.contains(".")) {
          String service = serv.split("\\.")[0]; // find service name
          String subservice = serv.replace(service + ".", ""); // get sub service name
          TimeGraphEntry subServiceEntry =
              new OPS_NEUTRON_ENTRY(
                  serviceQuark, trace, startTime, endTime, Type.SERVICE, subservice);
          if (mapservice.containsKey(service)) {
            NonNullUtils.checkNotNull(mapservice.get(service)).addChild(subServiceEntry);
          } else {
            TimeGraphEntry ServiceEntry =
                new OPS_NEUTRON_ENTRY(
                    serviceQuark, trace, startTime, endTime, Type.SERVICE, service);
            mapservice.put(service, ServiceEntry);
            ServiceEntry.addChild(subServiceEntry);
            traceEntry.addChild(ServiceEntry);
          }
        }
      }

      if (parentTrace.equals(getTrace())) {
        refresh();
      }
      final List<? extends ITimeGraphEntry> traceEntryChildren = traceEntry1.getChildren();
      final long resolution = Math.max(1, (endTime - ssq.getStartTime()) / getDisplayWidth());
      final long qStart = start;
      final long qEnd = end;
      queryFullStates(
          ssq,
          qStart,
          qEnd,
          resolution,
          monitor,
          new IQueryHandler() {
            @Override
            public void handle(
                List<List<ITmfStateInterval>> fullStates, List<ITmfStateInterval> prevFullState) {
              for (ITimeGraphEntry child : traceEntryChildren) {
                if (monitor.isCanceled()) {
                  return;
                }
                if (child instanceof TimeGraphEntry) {
                  TimeGraphEntry entry = (TimeGraphEntry) child;
                  List<ITimeEvent> eventList =
                      getEventList(entry, ssq, fullStates, prevFullState, monitor);
                  if (eventList != null) {
                    for (ITimeEvent event : eventList) {
                      entry.addEvent(event);
                    }
                  }
                }
              }
            }
          });

      start = end;
    }
  }