All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.stat.internal.ConcurrentQueryStatisticsImpl Maven / Gradle / Ivy

There is a newer version: 6.5.0.CR2
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or .
 */
package org.hibernate.stat.internal;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.hibernate.stat.QueryStatistics;

/**
 * Query statistics (HQL and SQL)
 * 

* Note that for a cached query, the cache miss is equals to the db count * * @author Alex Snaps */ public class ConcurrentQueryStatisticsImpl extends CategorizedStatistics implements QueryStatistics { private final AtomicLong cacheHitCount = new AtomicLong(); private final AtomicLong cacheMissCount = new AtomicLong(); private final AtomicLong cachePutCount = new AtomicLong(); private final AtomicLong executionCount = new AtomicLong(); private final AtomicLong executionRowCount = new AtomicLong(); private final AtomicLong executionMaxTime = new AtomicLong(); private final AtomicLong executionMinTime = new AtomicLong(Long.MAX_VALUE); private final AtomicLong totalExecutionTime = new AtomicLong(); private final Lock readLock; private final Lock writeLock; { ReadWriteLock lock = new ReentrantReadWriteLock(); readLock = lock.readLock(); writeLock = lock.writeLock(); } ConcurrentQueryStatisticsImpl(String query) { super(query); } /** * queries executed to the DB */ public long getExecutionCount() { return executionCount.get(); } /** * Queries retrieved successfully from the cache */ public long getCacheHitCount() { return cacheHitCount.get(); } public long getCachePutCount() { return cachePutCount.get(); } public long getCacheMissCount() { return cacheMissCount.get(); } /** * Number of lines returned by all the executions of this query (from DB) * For now, {@link org.hibernate.Query#iterate()} * and {@link org.hibernate.Query#scroll()()} do not fill this statistic * * @return The number of rows cumulatively returned by the given query; iterate * and scroll queries do not effect this total as their number of returned rows * is not known at execution time. */ public long getExecutionRowCount() { return executionRowCount.get(); } /** * average time in ms taken by the execution of this query onto the DB */ public long getExecutionAvgTime() { return (long) getExecutionAvgTimeAsDouble(); } /** * average time in ms as double taken by the execution of this query onto the DB */ public double getExecutionAvgTimeAsDouble() { // We write lock here to be sure that we always calculate the average time // with all updates from the executed applied: executionCount and totalExecutionTime // both used in the calculation writeLock.lock(); try { double avgExecutionTime = 0; if ( executionCount.get() > 0 ) { avgExecutionTime = totalExecutionTime.get() / (double) executionCount .get(); } return avgExecutionTime; } finally { writeLock.unlock(); } } /** * max time in ms taken by the execution of this query onto the DB */ public long getExecutionMaxTime() { return executionMaxTime.get(); } /** * min time in ms taken by the execution of this query onto the DB */ public long getExecutionMinTime() { return executionMinTime.get(); } /** * total time in ms taken by the execution of this query onto the DB */ public long getExecutionTotalTime() { return totalExecutionTime.get(); } /** * add statistics report of a DB query * * @param rows rows count returned * @param time time taken */ void executed(long rows, long time) { // read lock is enough, concurrent updates are supported by the underlying type AtomicLong // this only guards executed(long, long) to be called, when another thread is executing getExecutionAvgTime() readLock.lock(); try { // Less chances for a context switch for (long old = executionMinTime.get(); (time < old) && !executionMinTime.compareAndSet(old, time); old = executionMinTime.get()) {} for (long old = executionMaxTime.get(); (time > old) && !executionMaxTime.compareAndSet(old, time); old = executionMaxTime.get()) {} executionCount.getAndIncrement(); executionRowCount.addAndGet(rows); totalExecutionTime.addAndGet(time); } finally { readLock.unlock(); } } public String toString() { return "QueryStatistics" + "[cacheHitCount=" + this.cacheHitCount + ",cacheMissCount=" + this.cacheMissCount + ",cachePutCount=" + this.cachePutCount + ",executionCount=" + this.executionCount + ",executionRowCount=" + this.executionRowCount + ",executionAvgTime=" + this.getExecutionAvgTime() + ",executionMaxTime=" + this.executionMaxTime + ",executionMinTime=" + this.executionMinTime + ']'; } void incrementCacheHitCount() { cacheHitCount.getAndIncrement(); } void incrementCacheMissCount() { cacheMissCount.getAndIncrement(); } void incrementCachePutCount() { cachePutCount.getAndIncrement(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy