001package io.ebeaninternal.server.query;
002
003import io.ebean.meta.MetaQueryMetric;
004import io.ebean.metric.TimedMetric;
005import io.ebean.metric.TimedMetricStats;
006
007/**
008 * Statistics for a specific query plan that can accumulate.
009 */
010public final class CQueryPlanStats {
011
012  private final CQueryPlan queryPlan;
013
014  private final TimedMetric timedMetric;
015
016  private boolean collected;
017
018  private long lastQueryTime;
019
020  /**
021   * Construct for a given query plan.
022   */
023  CQueryPlanStats(CQueryPlan queryPlan) {
024    this.queryPlan = queryPlan;
025    this.timedMetric = queryPlan.createTimedMetric();
026  }
027
028  /**
029   * Return true if there are no statistics collected since the last reset.
030   */
031  public boolean isEmpty() {
032    return timedMetric.isEmpty();
033  }
034
035  /**
036   * Add a query execution to the statistics.
037   */
038  public void add(long timeMicros) {
039    timedMetric.add(timeMicros);
040    // not safe but should be atomic
041    lastQueryTime = System.currentTimeMillis();
042  }
043
044  /**
045   * Reset the internal statistics counters.
046   */
047  public void reset() {
048    timedMetric.reset();
049  }
050
051  /**
052   * Return the last time this query was executed.
053   */
054  long getLastQueryTime() {
055    return lastQueryTime;
056  }
057
058  /**
059   * Return a Snapshot of the query execution statistics potentially resetting the internal counters.
060   */
061  Snapshot getSnapshot(boolean reset) {
062
063    TimedMetricStats collect = timedMetric.collect(reset);
064    Snapshot snapshot = new Snapshot(collected, queryPlan, collect);
065    collected = true;
066    return snapshot;
067  }
068
069  /**
070   * A snapshot of the current statistics for a query plan.
071   */
072  static class Snapshot implements MetaQueryMetric {
073
074    private final boolean collected;
075    private final CQueryPlan queryPlan;
076    private final TimedMetricStats metrics;
077
078    Snapshot(boolean collected, CQueryPlan queryPlan, TimedMetricStats metrics) {
079      this.collected = collected;
080      this.queryPlan = queryPlan;
081      this.metrics = metrics;
082    }
083
084    @Override
085    public String toString() {
086      return "label:" + getLabel() + " location:" + getLocation() + " metrics:" + metrics + " sql:" + getSql();
087    }
088
089    @Override
090    public Class<?> getType() {
091      return queryPlan.getBeanType();
092    }
093
094    @Override
095    public String getLabel() {
096      return queryPlan.getLabel();
097    }
098
099    @Override
100    public String getName() {
101      return queryPlan.getName();
102    }
103
104    @Override
105    public String getLocation() {
106      return queryPlan.getLocation();
107    }
108
109    @Override
110    public long getCount() {
111      return metrics.getCount();
112    }
113
114    @Override
115    public long getTotal() {
116      return metrics.getTotal();
117    }
118
119    @Override
120    public long getMax() {
121      return metrics.getMax();
122    }
123
124    @Override
125    public long getMean() {
126      return metrics.getMean();
127    }
128
129    @Override
130    public String getHash() {
131      return queryPlan.getHash();
132    }
133
134    @Override
135    public String getSql() {
136      return queryPlan.getSql();
137    }
138
139    @Override
140    public boolean initialCollection() {
141      return !collected;
142    }
143
144  }
145
146}