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}