package org.radargun.stages.query; import java.util.concurrent.atomic.AtomicIntegerArray; import org.radargun.Operation; import org.radargun.logging.Log; import org.radargun.logging.LogFactory; import org.radargun.stages.test.OperationLogic; import org.radargun.stages.test.Stressor; import org.radargun.traits.Query; import org.radargun.traits.Queryable; import org.radargun.utils.TimeService; /** * @author Radim Vansa <rvansa@redhat.com> */ public class QueryLogic extends OperationLogic { protected final QueryBase queryBase; protected final Log log = LogFactory.getLog(getClass()); protected final Queryable queryable; protected final boolean useTransactions; protected Query.Result previousQueryResult = null; protected Query.Context context; AtomicIntegerArray queryInvocations; public QueryLogic(QueryBase queryBase, Queryable queryable, boolean useTransactions) { this.queryBase = queryBase; this.queryable = queryable; this.useTransactions = useTransactions; queryInvocations = new AtomicIntegerArray(queryBase.getNumQueries()); } @Override public void transactionStarted() { if (context != null) { stressor.wrap(context); } } @Override public void transactionEnded() { if (context != null) { context.close(); context = null; } } @Override public void init(Stressor stressor) { super.init(stressor); stressor.setUseTransactions(useTransactions); } @Override public void run(Operation ignored) throws RequestException { int randomQueryNumber = stressor.getRandom().nextInt(queryBase.getNumQueries()); Query query = queryBase.buildQuery(randomQueryNumber); Query.Result queryResult; context = queryable.createContext(null); long start = TimeService.nanoTime(); queryResult = stressor.makeRequest(new Invocations.Query(query, context)); long end = TimeService.nanoTime(); log.tracef("Invoked query %d (%dth) in %d us", randomQueryNumber, queryInvocations.incrementAndGet(randomQueryNumber), (end - start) / 1000); int size = queryResult.size(); if (previousQueryResult != null) { if (queryBase.isCheckSameResult() && size != previousQueryResult.size()) { throw new IllegalStateException("The query result is different from the previous one. All results should be the same when executing the same query"); } } else { log.info("First result has " + size + " entries"); if (log.isTraceEnabled()) { for (Object entry : queryResult.values()) { log.trace(String.valueOf(entry)); } } int min = queryBase.getMinResultSize(); if (queryBase.isCheckSameResult() && min >= 0 && min != size) { throw new IllegalStateException("Another thread reported " + min + " results while we have " + size); } queryBase.updateMinResultSize(size); int max = queryBase.getMaxResultSize(); if (queryBase.isCheckSameResult() && max >= 0 && max != size) { throw new IllegalStateException("Another thread reported " + max + " results while we have " + size); } queryBase.updateMaxResultSize(size); } previousQueryResult = queryResult; } }