/**************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
* http://esper.codehaus.org *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package com.espertech.esper.epl.core;
import com.espertech.esper.epl.variable.VariableReader;
import com.espertech.esper.epl.expression.ExprEvaluatorContext;
import com.espertech.esper.client.EventBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* An order-by processor that sorts events according to the expressions
* in the order_by clause.
*/
public class OrderByProcessorRowLimit implements OrderByProcessor {
private static final Log log = LogFactory.getLog(OrderByProcessorImpl.class);
private final VariableReader numRowsVariableReader;
private final VariableReader offsetVariableReader;
private int currentRowLimit;
private int currentOffset;
public OrderByProcessorRowLimit(VariableReader numRowsVariableReader, VariableReader offsetVariableReader, int currentRowLimit, int currentOffset) {
this.numRowsVariableReader = numRowsVariableReader;
this.offsetVariableReader = offsetVariableReader;
this.currentRowLimit = currentRowLimit;
this.currentOffset = currentOffset;
}
public EventBean[] sort(EventBean[] outgoingEvents, EventBean[][] generatingEvents, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext)
{
return applyLimit(outgoingEvents);
}
public EventBean[] sort(EventBean[] outgoingEvents, EventBean[][] generatingEvents, Object[] groupByKeys, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext)
{
return applyLimit(outgoingEvents);
}
public Object getSortKey(EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext)
{
return null;
}
public Object[] getSortKeyPerRow(EventBean[] generatingEvents, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext)
{
return null;
}
public EventBean[] sort(EventBean[] outgoingEvents, Object[] orderKeys, ExprEvaluatorContext exprEvaluatorContext)
{
return applyLimit(outgoingEvents);
}
/**
* Applys the limiting function to outgoing events.
* @param outgoingEvents unlimited
* @return limited
*/
protected EventBean[] applyLimit(EventBean[] outgoingEvents)
{
if (outgoingEvents == null) {
return null;
}
if (numRowsVariableReader != null)
{
Number varValue = (Number) numRowsVariableReader.getValue();
if (varValue != null)
{
currentRowLimit = varValue.intValue();
}
else
{
currentRowLimit = Integer.MAX_VALUE;
}
if (currentRowLimit < 0)
{
currentRowLimit = Integer.MAX_VALUE;
}
}
if (offsetVariableReader != null)
{
Number varValue = (Number) offsetVariableReader.getValue();
if (varValue != null)
{
currentOffset = varValue.intValue();
}
else
{
currentOffset = 0;
}
if (currentOffset < 0)
{
currentOffset = 0;
}
}
// no offset
if (currentOffset == 0)
{
if ((outgoingEvents.length <= currentRowLimit))
{
return outgoingEvents;
}
if (currentRowLimit == 0)
{
return null;
}
EventBean[] limited = new EventBean[currentRowLimit];
System.arraycopy(outgoingEvents, 0, limited, 0, currentRowLimit);
return limited;
}
// with offset
else
{
int maxInterested = currentRowLimit + currentOffset;
if (currentRowLimit == Integer.MAX_VALUE)
{
maxInterested = Integer.MAX_VALUE;
}
// more rows then requested
if (outgoingEvents.length > maxInterested)
{
EventBean[] limited = new EventBean[currentRowLimit];
System.arraycopy(outgoingEvents, currentOffset, limited, 0, currentRowLimit);
return limited;
}
// less or equal rows to offset
if (outgoingEvents.length <= currentOffset)
{
return null;
}
int size = outgoingEvents.length - currentOffset;
EventBean[] limited = new EventBean[size];
System.arraycopy(outgoingEvents, currentOffset, limited, 0, size);
return limited;
}
}
}