001package org.hl7.fhir.utilities;
002
003import java.util.ArrayList;
004import java.util.List;
005
006public class TimeTracker {
007
008  public class Counter {
009    private String name;
010    private int count;
011    private long length;
012    public Counter(String name) {
013      this.name = name;
014    }
015  }
016  
017  public class Session {
018    private long start = System.nanoTime();
019    private String name;
020    public Session(String name) {
021      this.name = name;
022    }
023    public void end() {
024      endSession(this);
025    }
026  }
027  
028  private List<Session> sessions = new ArrayList<>();
029  private List<Counter> records = new ArrayList<>();
030  private long globalStart;
031  private long milestone = 0;
032  
033  
034  public TimeTracker() {
035    super();
036    globalStart = System.nanoTime();
037  }
038
039  public Session start(String name) {
040    Counter c = null;
041    for (Counter t : records) {
042      if (t.name.equals(name)) {
043        c = t;
044      }
045    }
046    if (c == null) {
047      c = new Counter(name);
048      records.add(c);
049    }
050    Session session = new Session(name);
051    sessions.add(session);
052    return session;
053  }
054
055  private void endSession(Session session) {
056    sessions.remove(session);
057    Counter c = null;
058    for (Counter t : records) {
059      if (t.name.equals(session.name)) {
060        c = t;
061      }
062    }
063    c.count++;
064    c.length = c.length + System.nanoTime() - session.start;
065  }
066  
067  public String report() {
068    CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
069    for (Counter c : records) {
070      if (c.count == 1) {
071        b.append(c.name+": "+ DurationUtil.presentDuration(c.length));
072      }
073    }
074    for (Counter c : records) {
075      if (c.count > 1) {
076        b.append(c.name+": "+ DurationUtil.presentDuration(c.length)+" (#"+c.count+")");
077      }
078    }
079    return "Times: "+b.toString();
080  }
081  
082  public String clock() {
083    return DurationUtil.presentDuration(System.nanoTime() - globalStart);
084  }
085
086  public String instant() {
087    return DurationUtil.presentDuration(System.nanoTime() - globalStart);
088  }
089
090  public String milestone() {
091    long start = milestone == 0 ? globalStart : milestone ;
092    milestone = System.nanoTime();
093    return DurationUtil.presentDuration(milestone - start);
094  }
095
096}