package org.jactr.core.module.declarative.search.local;
/*
* default logging
*/
import java.util.Collection;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.chunk.IChunk;
import org.jactr.core.chunktype.IChunkType;
import org.jactr.core.module.declarative.search.filter.AcceptAllFilter;
import org.jactr.core.module.declarative.search.filter.IChunkFilter;
import org.jactr.core.production.request.ChunkTypeRequest;
import org.jactr.core.utils.collections.SkipListSetFactory;
/**
* basic implementation of a hideously inefficient partial matching (but it is
* by necessity)
*
* @author harrison
*/
public class PartialSingleThreadedSearchDelegate implements ISearchDelegate
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(PartialSingleThreadedSearchDelegate.class);
public PartialSingleThreadedSearchDelegate()
{
}
/**
* partial matching
*/
@Override
public SortedSet<IChunk> find(ChunkTypeRequest pattern,
Comparator<IChunk> sortRule, IChunkFilter filter,
DefaultSearchSystem searchSystem)
{
Collection<IChunk> candidates = null;
SortedSet<IChunk> returnCandidates = null;
IChunkType chunkType = pattern.getChunkType();
if (chunkType != null)
candidates = chunkType.getSymbolicChunkType().getChunks();
else
try
{
candidates = searchSystem._module.getChunks().get();
}
catch (Exception e)
{
LOGGER
.error("Failed to fetch all chunks for null chunktype search ", e);
}
if (candidates.size() != 0)
{
/*
* we now need to deal with those that are actually the correct chunk
* type. Iteration over the candidates doing an isA() test would be
* O(candidates.size). candidates.retainAll(chunksOfType) is either
* O(candidates.size)*O(log(chunksOfType.size) or
* O(chunksOfType.size)*O(log(candidates.size)). Until the Fast
* collections come out with their predicate iterators, we will just
* iterate raw. And use the opportunity to filter and sort.
*/
Comparator<IChunk> comparator = searchSystem._chunkNameComparator;
if (sortRule != null) comparator = sortRule;
IChunkFilter chunkFilter = filter == null ? new AcceptAllFilter()
: filter;
returnCandidates = SkipListSetFactory.newInstance(comparator);
for (IChunk candidate : candidates)
if (chunkType == null || candidate.isA(chunkType))
if (chunkFilter.accept(candidate)) returnCandidates.add(candidate);
searchSystem.recycleCollection(candidates);
}
else
returnCandidates = new TreeSet<IChunk>();
if (LOGGER.isDebugEnabled())
LOGGER.debug("First pass candidates for " + pattern + " chunks: "
+ returnCandidates);
return returnCandidates;
}
}