package rocks.inspectit.server.indexing.impl;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
import rocks.inspectit.server.indexing.impl.RootBranchFactory.RootBranch;
import rocks.inspectit.shared.all.communication.DefaultData;
import rocks.inspectit.shared.cs.indexing.buffer.IBufferBranchIndexer;
import rocks.inspectit.shared.cs.indexing.buffer.IBufferTreeComponent;
import rocks.inspectit.shared.cs.indexing.buffer.impl.Branch;
import rocks.inspectit.shared.cs.indexing.buffer.impl.BufferBranchIndexer;
import rocks.inspectit.shared.cs.indexing.impl.IndexingException;
import rocks.inspectit.shared.cs.indexing.indexer.impl.ObjectTypeIndexer;
import rocks.inspectit.shared.cs.indexing.indexer.impl.PlatformIdentIndexer;
import rocks.inspectit.shared.cs.indexing.indexer.impl.TimestampIndexer;
/**
* Factory that creates the root branch for indexing tree. This root branch will be injected in
* Spring as a bean.
*
* @author Ivan Senic
*
*/
@Component
public class RootBranchFactory implements FactoryBean<RootBranch<DefaultData>> {
/**
* {@inheritDoc}
*/
@Override
public RootBranch<DefaultData> getObject() throws Exception {
BufferBranchIndexer<DefaultData> timestampIndexer = new BufferBranchIndexer<>(new TimestampIndexer<>());
BufferBranchIndexer<DefaultData> objectTypeIndexer = new BufferBranchIndexer<>(new ObjectTypeIndexer<>(), timestampIndexer);
BufferBranchIndexer<DefaultData> platformIndexer = new BufferBranchIndexer<>(new PlatformIdentIndexer<>(), objectTypeIndexer);
return new RootBranch<>(platformIndexer);
}
/**
* {@inheritDoc}
*/
@Override
public Class<?> getObjectType() {
return IBufferTreeComponent.class;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isSingleton() {
return true;
}
/**
* Root branch. It has additional functionality of generating IDs for the elements that need to
* be put into the indexing tree.
*
* @author Ivan Senic
*
*/
public static class RootBranch<E extends DefaultData> extends Branch<E> {
/**
* Runnable for cutting the empty tree components.
*/
private Runnable clearEmptyComponentsRunnable = new Runnable() {
@Override
public void run() {
RootBranch.this.clearEmptyComponents();
}
};
/**
* Future that holds state of clear empty components runnable.
*/
private Future<?> clearEmptyComponentsFuture;
/**
* Default constructor.
*
* @param branchIndexer
* Branch indexer for root branch.
*/
public RootBranch(IBufferBranchIndexer<E> branchIndexer) {
super(branchIndexer);
}
/**
* {@inheritDoc}
* <p>
* This method also sets the ID of the element that is put into the indexing tree.
*/
@Override
public E put(E element) throws IndexingException {
if (null == element) {
throw new IndexingException("Null object can not be indexed.");
}
return super.put(element);
}
/**
* {@inheritDoc}
*/
@Override
public void cleanWithRunnable(ExecutorService executorService) {
super.cleanWithRunnable(executorService);
if ((clearEmptyComponentsFuture == null) || clearEmptyComponentsFuture.isDone()) {
// Submit runnable only if the future is signaling that the last one was done.
clearEmptyComponentsFuture = executorService.submit(clearEmptyComponentsRunnable);
}
}
}
}