package rocks.inspectit.server.dao.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import rocks.inspectit.shared.all.communication.DefaultData;
import rocks.inspectit.shared.all.indexing.IIndexQuery;
import rocks.inspectit.shared.cs.indexing.aggregation.IAggregator;
import rocks.inspectit.shared.cs.indexing.aggregation.impl.AggregationPerformer;
import rocks.inspectit.shared.cs.indexing.buffer.IBufferTreeComponent;
/**
* Abstract class for all buffer data DAO service.
*
* @param <E>
* Type of the data to be queried.
*
* @author Ivan Senic
*
*/
public abstract class AbstractBufferDataDao<E extends DefaultData> {
/**
* Indexing tree to search for data.
*/
@Autowired
private IBufferTreeComponent<E> indexingTree;
/**
* ForkJoinPool to manage the forks.
*/
@Autowired
@Qualifier("indexingTreeForkJoinPool")
private ForkJoinPool forkJoinPool;
/**
* Executes the query on the indexing tree.
*
* @param indexQuery
* Index query to execute.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, boolean useForkJoin) {
return this.executeQuery(indexQuery, null, null, -1, useForkJoin);
}
/**
* Executes the query on the indexing tree. If the {@link IAggregator} is not <code>null</code>
* then the results will be aggregated based on the given {@link IAggregator}.
*
* @param indexQuery
* Index query to execute.
* @param aggregator
* {@link IAggregator}. Pass <code>null</code> if no aggregation is needed.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, IAggregator<E> aggregator, boolean useForkJoin) {
return this.executeQuery(indexQuery, aggregator, null, -1, useForkJoin);
}
/**
* Executes the query on the indexing tree. Results can be sorted by comparator.
*
* @param indexQuery
* Index query to execute.
* @param comparator
* If supplied the final result list will be sorted by this comparator.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, Comparator<? super E> comparator, boolean useForkJoin) {
return this.executeQuery(indexQuery, null, comparator, -1, useForkJoin);
}
/**
* Executes the query on the indexing tree. Furthermore the result list can be limited.
*
* @param indexQuery
* Index query to execute.
* @param limit
* Limit the number of results by given number. Value <code>-1</code> means no limit.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, int limit, boolean useForkJoin) {
return this.executeQuery(indexQuery, null, null, limit, useForkJoin);
}
/**
* Executes the query on the indexing tree. If the {@link IAggregator} is not <code>null</code>
* then the results will be aggregated based on the given {@link IAggregator}.
*
* @param indexQuery
* Index query to execute.
* @param aggregator
* {@link IAggregator}. Pass <code>null</code> if no aggregation is needed.
* @param comparator
* If supplied the final result list will be sorted by this comparator.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, IAggregator<E> aggregator, Comparator<? super E> comparator, boolean useForkJoin) {
return this.executeQuery(indexQuery, aggregator, comparator, -1, useForkJoin);
}
/**
* Executes the query on the indexing tree. If the {@link IAggregator} is not <code>null</code>
* then the results will be aggregated based on the given {@link IAggregator}. Furthermore the
* result list can be limited.
*
* @param indexQuery
* Index query to execute.
* @param aggregator
* {@link IAggregator}. Pass <code>null</code> if no aggregation is needed.
* @param limit
* Limit the number of results by given number. Value <code>-1</code> means no limit.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, IAggregator<E> aggregator, int limit, boolean useForkJoin) {
return this.executeQuery(indexQuery, aggregator, null, limit, useForkJoin);
}
/**
* Executes the query on the indexing tree. Results can be sorted by comparator. Furthermore the
* result list can be limited.
*
* @param indexQuery
* Index query to execute.
*
* @param comparator
* If supplied the final result list will be sorted by this comparator.
* @param limit
* Limit the number of results by given number. Value <code>-1</code> means no limit.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, Comparator<? super E> comparator, int limit, boolean useForkJoin) {
return this.executeQuery(indexQuery, null, comparator, limit, useForkJoin);
}
/**
* Executes the query on the indexing tree. If the {@link IAggregator} is not <code>null</code>
* then the results will be aggregated based on the given {@link IAggregator}. Results can be
* sorted by comparator. Furthermore the result list can be limited.
*
* @param indexQuery
* Index query to execute.
* @param aggregator
* {@link IAggregator}. Pass <code>null</code> if no aggregation is needed.
* @param comparator
* If supplied the final result list will be sorted by this comparator.
* @param limit
* Limit the number of results by given number. Value <code>-1</code> means no limit.
* @param useForkJoin
* true, if forkJoinPool should be used
* @return Result list.
*/
protected List<E> executeQuery(IIndexQuery indexQuery, IAggregator<E> aggregator, Comparator<? super E> comparator, int limit, boolean useForkJoin) {
List<E> data;
if (useForkJoin) {
data = indexingTree.query(indexQuery, forkJoinPool);
} else {
data = indexingTree.query(indexQuery);
}
if (null != aggregator) {
AggregationPerformer<E> aggregationPerformer = new AggregationPerformer<>(aggregator);
aggregationPerformer.processCollection(data);
data = aggregationPerformer.getResultList();
}
if (null != comparator) {
Collections.sort(data, comparator);
}
if ((limit > -1) && (data.size() > limit)) {
data = new ArrayList<>(data.subList(0, limit));
}
return data;
}
/**
* Gets {@link #indexingTree}.
*
* @return {@link #indexingTree}
*/
protected IBufferTreeComponent<E> getIndexingTree() {
return indexingTree;
}
}