@SuppressWarnings("unchecked")
public ObjectSet execute(JODBSession session, Predicate predicate, Comparator comparator) throws IOException
{
IOBase base = session.getBase();
IOTicket ticket = base.getIOTicket(true, false);
try {
JODBOperationContext context = new JODBOperationContext(session, ticket, null, null,null);
INqLoader loader = getLoader(context, predicate, comparator);
if(!loader.isPredicateOptimized() || !loader.isComparatorOptimized()){
return executeUnoptimized(session, predicate, comparator, loader);
}
Class predicateSubjectClass = loader.getPredicateSubjectClass();
//ClassDescriptor predicateSubjectClassDescriptor = session.getDescriptorForClass(predicateSubjectClass);
//Method setProxyMethod = loader.getSyntheticProxySetMethod();
//Class syntheticPredicate;
Class syntheticPredicateSubjectClass = loader.loadClass(predicateSubjectClass.getName());
SyntheticSubject syntheticSubject = new SyntheticSubject(context, loader,syntheticPredicateSubjectClass);
Class syntheticPredicateClass = loader.loadClass(predicate.getClass().getName());
Predicate syntheticPredicate = (Predicate) instantiateSyntheticPredicate(session, predicate, syntheticPredicateClass);// (Predicate)syntheticPredicateClass.newInstance();
Comparator syntheticComparator = null;
if(comparator!=null){
Class syntheticComparatorClass = loader.loadClass(comparator.getClass().getName());
syntheticComparator = (Comparator) instantiateSyntheticPredicate(session, comparator, syntheticComparatorClass);
//(Comparator) session.getDescriptorForClass(syntheticComparatorClass).newInstance();
}
//int[] predicateSubjectFields = loader.getPredicateSubjectFields();
JODBIndexingRootAgent indexingRootAgent = session.getIndexingRootAgent();
JODBIndexingAgent indexingAgent = null;
Iterator<Integer> predicateSubjectAccessedFields = loader.getAccessedPredicateSubjectFields();
while (predicateSubjectAccessedFields.hasNext() && indexingAgent == null) {
indexingAgent = indexingRootAgent.getIndexingAgent(predicateSubjectAccessedFields.next(), session.getBase());
}
ByteBuffer indexDataBuffer = null;
int indexField = -1;
IndexDataIterator indexIterator = null;
if(indexingAgent!=null){
indexField = indexingAgent.getFieldId();
indexDataBuffer = ByteBuffer.allocate(16);
indexIterator = indexingAgent.getIndexIterator(true);
}
if(indexIterator==null){
indexIterator = new LArrayIndexIterator(base.getForAllObjects(ticket));
}
SyntheticSubject syntheticSubjectPrev = null;
COMPARISON_STATE comparison_state= COMPARISON_STATE.UNKNOWN;
LArrayChunkedBuffer acceptedIdsBuffer = new LArrayChunkedBuffer();
while (indexIterator.hasNext()) {
if(indexDataBuffer != null){
indexDataBuffer.clear();
}
long nextObjectId = indexIterator.next(indexDataBuffer);
if(!syntheticSubject.setObjectData(nextObjectId, indexField, indexDataBuffer)){
continue;
}
if(!syntheticPredicate.match(syntheticSubject._syntheticSubject)){
continue;
}
acceptedIdsBuffer.add(nextObjectId);
if(syntheticComparator!=null && comparison_state!=COMPARISON_STATE.MIXED){
if(syntheticSubjectPrev!=null ){
int compareResult = syntheticComparator.compare(syntheticSubjectPrev._syntheticSubject, syntheticSubject._syntheticSubject);
if ((compareResult < 0 && comparison_state == COMPARISON_STATE.DESCENDING)
|| (compareResult > 0 && comparison_state == COMPARISON_STATE.ASCENDING))
{
comparison_state = COMPARISON_STATE.MIXED;
continue;
}else if(compareResult!=0){
comparison_state = compareResult < 0? COMPARISON_STATE.ASCENDING : COMPARISON_STATE.DESCENDING;
}
SyntheticSubject swapHolder = syntheticSubjectPrev;
syntheticSubjectPrev = syntheticSubject;
syntheticSubject = swapHolder;
}else{
syntheticSubjectPrev = syntheticSubject;
syntheticSubject = new SyntheticSubject(context, loader,syntheticPredicateSubjectClass);
continue;
}
}
}
if(comparator!=null){
if(comparison_state == COMPARISON_STATE.MIXED){
long[] acceptedIds = acceptedIdsBuffer.toArray();
acceptedIdsBuffer = null;//for GC
NQueryUtils.quickQuerySort(acceptedIds, syntheticComparator, syntheticSubject, syntheticSubjectPrev);
return new SimpleArrayQueryList(acceptedIds,session);
}else if (comparison_state == COMPARISON_STATE.DESCENDING){
acceptedIdsBuffer.setIteratorDirection(false);
}
}
return new ChunkedBufferQueryList(acceptedIdsBuffer, session);
} catch (Exception e) {
// TODO log
throw new JodbIOException(e);
} finally {
ticket.close();
}
//return null;
}