/**************************************************************************************
* 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.view.ext;
import com.espertech.esper.client.EventType;
import com.espertech.esper.core.context.util.AgentInstanceViewFactoryChainContext;
import com.espertech.esper.core.service.ExprEvaluatorContextStatement;
import com.espertech.esper.core.service.StatementContext;
import com.espertech.esper.epl.expression.ExprEvaluator;
import com.espertech.esper.epl.expression.ExprNode;
import com.espertech.esper.epl.expression.ExprNodeUtility;
import com.espertech.esper.epl.expression.ExprOrderedExpr;
import com.espertech.esper.view.*;
import com.espertech.esper.view.window.RandomAccessByIndexGetter;
import java.util.List;
/**
* Factory for sort window views.
*/
public class SortWindowViewFactory implements DataWindowViewFactory, DataWindowViewWithPrevious
{
private final static String NAME = "Sort view";
private List<ExprNode> viewParameters;
/**
* The sort-by expressions.
*/
protected ExprNode[] sortCriteriaExpressions;
/**
* The flags defining the ascending or descending sort order.
*/
protected boolean[] isDescendingValues;
/**
* The sort window size.
*/
protected int sortWindowSize;
private EventType eventType;
public void setViewParameters(ViewFactoryContext viewFactoryContext, List<ExprNode> viewParams) throws ViewParameterException
{
this.viewParameters = viewParams;
}
public void attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, List<ViewFactory> parentViewFactories) throws ViewParameterException
{
eventType = parentEventType;
String message = NAME + " requires a numeric size parameter and a list of expressions providing sort keys";
if (viewParameters.size() < 2)
{
throw new ViewParameterException(message);
}
ExprNode[] validated = ViewFactorySupport.validate(NAME, parentEventType, statementContext, viewParameters, true);
for (int i = 1; i < validated.length; i++)
{
ViewFactorySupport.assertReturnsNonConstant(NAME, validated[i], i);
}
ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
Object sortSize = ViewFactorySupport.evaluateAssertNoProperties(NAME, validated[0], 0, exprEvaluatorContext);
if ((sortSize == null) || (!(sortSize instanceof Number)))
{
throw new ViewParameterException(message);
}
sortWindowSize = ((Number) sortSize).intValue();
sortCriteriaExpressions = new ExprNode[validated.length - 1];
isDescendingValues = new boolean[sortCriteriaExpressions.length];
for (int i = 1; i < validated.length; i++)
{
if (validated[i] instanceof ExprOrderedExpr)
{
isDescendingValues[i - 1] = ((ExprOrderedExpr) validated[i]).isDescending();
sortCriteriaExpressions[i - 1] = validated[i].getChildNodes().get(0);
}
else
{
sortCriteriaExpressions[i - 1] = validated[i];
}
}
}
public View makeView(AgentInstanceViewFactoryChainContext agentInstanceViewFactoryContext)
{
IStreamSortRankRandomAccess sortedRandomAccess = ViewServiceHelper.getOptPreviousExprSortedRankedAccess(agentInstanceViewFactoryContext);
boolean useCollatorSort = false;
if (agentInstanceViewFactoryContext.getAgentInstanceContext().getStatementContext().getConfigSnapshot() != null)
{
useCollatorSort = agentInstanceViewFactoryContext.getAgentInstanceContext().getStatementContext().getConfigSnapshot().getEngineDefaults().getLanguage().isSortUsingCollator();
}
ExprEvaluator[] childEvals = ExprNodeUtility.getEvaluators(sortCriteriaExpressions);
return new SortWindowView(this, sortCriteriaExpressions, childEvals, isDescendingValues, sortWindowSize, sortedRandomAccess, useCollatorSort, agentInstanceViewFactoryContext);
}
public Object makePreviousGetter() {
return new RandomAccessByIndexGetter();
}
public EventType getEventType()
{
return eventType;
}
public boolean canReuse(View view)
{
if (!(view instanceof SortWindowView))
{
return false;
}
SortWindowView other = (SortWindowView) view;
if ((other.getSortWindowSize() != sortWindowSize) ||
(!compare(other.getIsDescendingValues(), isDescendingValues)) ||
(!ExprNodeUtility.deepEquals(other.getSortCriteriaExpressions(), sortCriteriaExpressions)) )
{
return false;
}
return other.isEmpty();
}
private boolean compare(boolean[] one, boolean[] two)
{
if (one.length != two.length)
{
return false;
}
for (int i = 0; i < one.length; i++)
{
if (one[i] != two[i])
{
return false;
}
}
return true;
}
}