mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
89 lines
2.9 KiB
Java
89 lines
2.9 KiB
Java
package io.ebeaninternal.server.query;
|
|
|
|
import io.ebean.meta.MetaQueryPlan;
|
|
import io.ebean.meta.QueryPlanRequest;
|
|
import io.ebean.metric.TimedMetric;
|
|
import io.ebeaninternal.api.ExtraMetrics;
|
|
import io.ebeaninternal.api.QueryPlanManager;
|
|
import io.ebeaninternal.api.SpiDbQueryPlan;
|
|
import io.ebeaninternal.api.SpiQueryBindCapture;
|
|
import io.ebeaninternal.api.SpiQueryPlan;
|
|
import io.ebeaninternal.server.transaction.TransactionManager;
|
|
import io.ebeaninternal.server.type.bindcapture.BindCapture;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.SQLException;
|
|
import java.util.List;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import static java.util.Collections.emptyList;
|
|
|
|
public class CQueryPlanManager implements QueryPlanManager {
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(CQueryPlanManager.class);
|
|
|
|
private static final Object dummy = new Object();
|
|
|
|
private final ConcurrentHashMap<CQueryBindCapture, Object> plans = new ConcurrentHashMap<>();
|
|
|
|
private final TransactionManager transactionManager;
|
|
|
|
private final long defaultThreshold;
|
|
|
|
private final QueryPlanLogger planLogger;
|
|
|
|
private final TimedMetric timeCollection;
|
|
|
|
private final TimedMetric timeBindCapture;
|
|
|
|
public CQueryPlanManager(TransactionManager transactionManager, long defaultThreshold, QueryPlanLogger planLogger, ExtraMetrics extraMetrics) {
|
|
this.transactionManager = transactionManager;
|
|
this.defaultThreshold = defaultThreshold;
|
|
this.planLogger = planLogger;
|
|
this.timeCollection = extraMetrics.getPlanCollect();
|
|
this.timeBindCapture = extraMetrics.getBindCapture();
|
|
}
|
|
|
|
@Override
|
|
public SpiQueryBindCapture createBindCapture(SpiQueryPlan queryPlan) {
|
|
return new CQueryBindCapture(this, queryPlan, defaultThreshold);
|
|
}
|
|
|
|
public void notifyBindCapture(CQueryBindCapture planBind, long startNanos) {
|
|
plans.put(planBind, dummy);
|
|
timeBindCapture.addSinceNanos(startNanos);
|
|
}
|
|
|
|
@Override
|
|
public List<MetaQueryPlan> collect(QueryPlanRequest request) {
|
|
if (plans.isEmpty()) {
|
|
return emptyList();
|
|
}
|
|
return collectPlans(request);
|
|
}
|
|
|
|
private List<MetaQueryPlan> collectPlans(QueryPlanRequest request) {
|
|
try (Connection connection = transactionManager.getQueryPlanConnection()) {
|
|
CQueryPlanRequest req = new CQueryPlanRequest(connection, request, plans.keySet().iterator());
|
|
while (req.hasNext()) {
|
|
req.nextCapture();
|
|
}
|
|
return req.getPlans();
|
|
} catch (SQLException e) {
|
|
log.error("Error during query plan collection", e);
|
|
return emptyList();
|
|
}
|
|
}
|
|
|
|
public SpiDbQueryPlan collectPlan(Connection connection, SpiQueryPlan queryPlan, BindCapture last) {
|
|
long startNanos = System.nanoTime();
|
|
try {
|
|
return planLogger.collectPlan(connection, queryPlan, last);
|
|
} finally {
|
|
timeCollection.addSinceNanos(startNanos);
|
|
}
|
|
}
|
|
}
|