/**************************************************************************************
* 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.join.base;
import com.espertech.esper.client.EventBean;
import com.espertech.esper.collection.MultiKey;
import com.espertech.esper.collection.UniformPair;
import com.espertech.esper.epl.expression.ExprEvaluatorContext;
import com.espertech.esper.epl.join.table.EventTable;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* Implements the function to determine a join result for a unidirectional stream-to-window joins,
* in which a single stream's events are ever only evaluated using a query strategy.
*/
public class JoinSetComposerStreamToWinImpl implements JoinSetComposer
{
private final EventTable[][] repositories;
private final int streamNumber;
private final QueryStrategy queryStrategy;
private final boolean isResetSelfJoinRepositories;
private final boolean[] selfJoinRepositoryResets;
private Set<MultiKey<EventBean>> emptyResults = new LinkedHashSet<MultiKey<EventBean>>();
private Set<MultiKey<EventBean>> newResults = new LinkedHashSet<MultiKey<EventBean>>();
/**
* Ctor.
* @param repositories - for each stream an array of (indexed/unindexed) tables for lookup.
* @param isPureSelfJoin for self-joins
* @param streamNumber is the undirectional stream
* @param queryStrategy is the lookup query strategy for the stream
* @param selfJoinRepositoryResets indicators for any stream's table that reset after strategy executon
*/
public JoinSetComposerStreamToWinImpl(Map<String, EventTable>[] repositories, boolean isPureSelfJoin, int streamNumber, QueryStrategy queryStrategy, boolean[] selfJoinRepositoryResets)
{
this.repositories = JoinSetComposerUtil.toArray(repositories);
this.streamNumber = streamNumber;
this.queryStrategy = queryStrategy;
this.selfJoinRepositoryResets = selfJoinRepositoryResets;
if (isPureSelfJoin)
{
isResetSelfJoinRepositories = true;
Arrays.fill(selfJoinRepositoryResets, true);
}
else
{
boolean flag = false;
for (boolean selfJoinRepositoryReset : selfJoinRepositoryResets)
{
flag |= selfJoinRepositoryReset;
}
this.isResetSelfJoinRepositories = flag;
}
}
public void init(EventBean[][] eventsPerStream)
{
for (int i = 0; i < eventsPerStream.length; i++)
{
if ((eventsPerStream[i] != null) && (i != streamNumber))
{
for (int j = 0; j < repositories[i].length; j++)
{
repositories[i][j].add((eventsPerStream[i]));
}
}
}
}
public void destroy()
{
for (EventTable[] repository : repositories)
{
if (repository != null) {
for (EventTable table : repository)
{
table.clear();
}
}
}
}
public UniformPair<Set<MultiKey<EventBean>>> join(EventBean[][] newDataPerStream, EventBean[][] oldDataPerStream, ExprEvaluatorContext exprEvaluatorContext)
{
newResults.clear();
// We add and remove data in one call to each index.
// Most indexes will add first then remove as newdata and olddata may contain the same event.
// Unique indexes may remove then add.
for (int stream = 0; stream < newDataPerStream.length; stream++) {
if (stream != streamNumber) {
for (int j = 0; j < repositories[stream].length; j++)
{
repositories[stream][j].addRemove(newDataPerStream[stream], oldDataPerStream[stream]);
}
}
}
// join new data
if (newDataPerStream[streamNumber] != null)
{
queryStrategy.lookup(newDataPerStream[streamNumber], newResults, exprEvaluatorContext);
}
// on self-joins there can be repositories which are temporary for join execution
if (isResetSelfJoinRepositories)
{
for (int i = 0; i < selfJoinRepositoryResets.length; i++)
{
if (!selfJoinRepositoryResets[i])
{
continue;
}
for (int j = 0; j < repositories[i].length; j++)
{
repositories[i][j].clear();
}
}
}
return new UniformPair<Set<MultiKey<EventBean>>>(newResults, emptyResults);
}
public Set<MultiKey<EventBean>> staticJoin()
{
throw new UnsupportedOperationException("Iteration over a unidirectional join is not supported");
}
}