/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * 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.core.start; import com.espertech.esper.client.EventBean; import com.espertech.esper.core.context.util.AgentInstanceContext; import com.espertech.esper.epl.agg.service.AggregationRowPair; import com.espertech.esper.epl.expression.core.ExprNode; import com.espertech.esper.epl.expression.core.ExprNodeUtility; import com.espertech.esper.epl.fafquery.FireAndForgetQueryExec; import com.espertech.esper.epl.join.plan.QueryGraph; import com.espertech.esper.epl.table.mgmt.TableServiceImpl; import com.espertech.esper.epl.table.mgmt.TableStateInstance; import com.espertech.esper.epl.table.strategy.ExprTableEvalLockUtil; import com.espertech.esper.epl.virtualdw.VirtualDWView; import com.espertech.esper.util.CollectionUtil; import com.espertech.esper.view.Viewable; import java.lang.annotation.Annotation; import java.util.ArrayDeque; import java.util.Collection; import java.util.Collections; import java.util.Iterator; public class FireAndForgetInstanceTable extends FireAndForgetInstance { private final TableStateInstance instance; public FireAndForgetInstanceTable(TableStateInstance instance) { this.instance = instance; } public EventBean[] processInsert(EPPreparedExecuteIUDSingleStreamExecInsert insert) { ExprTableEvalLockUtil.obtainLockUnless(instance.getTableLevelRWLock().writeLock(), insert.getServices().getTableService().getTableExprEvaluatorContext()); EventBean theEvent = insert.getInsertHelper().process(new EventBean[0], true, true, insert.getExprEvaluatorContext()); AggregationRowPair aggs = instance.getTableMetadata().getRowFactory().makeAggs(insert.getExprEvaluatorContext().getAgentInstanceId(), null, null, instance.getAggregationServicePassThru()); ((Object[]) theEvent.getUnderlying())[0] = aggs; instance.addEvent(theEvent); return CollectionUtil.EVENTBEANARRAY_EMPTY; } public EventBean[] processDelete(EPPreparedExecuteIUDSingleStreamExecDelete delete) { ExprTableEvalLockUtil.obtainLockUnless(instance.getTableLevelRWLock().writeLock(), delete.getServices().getTableService().getTableExprEvaluatorContext()); if (delete.getOptionalWhereClause() == null) { instance.clearInstance(); return CollectionUtil.EVENTBEANARRAY_EMPTY; } Collection<EventBean> found = snapshotAndApplyFilter(delete.getQueryGraph(), delete.getAnnotations(), delete.getOptionalWhereClause(), instance.getAgentInstanceContext()); for (EventBean event : found) { instance.deleteEvent(event); } return CollectionUtil.EVENTBEANARRAY_EMPTY; } public EventBean[] processUpdate(EPPreparedExecuteIUDSingleStreamExecUpdate update) { ExprTableEvalLockUtil.obtainLockUnless(instance.getTableLevelRWLock().writeLock(), update.getServices().getTableService().getTableExprEvaluatorContext()); Collection<EventBean> events = snapshotAndApplyFilter(update.getQueryGraph(), update.getAnnotations(), update.getOptionalWhereClause(), instance.getAgentInstanceContext()); if (events != null && events.isEmpty()) { return CollectionUtil.EVENTBEANARRAY_EMPTY; } EventBean[] eventsPerStream = new EventBean[3]; if (events == null) { update.getTableUpdateStrategy().updateTable(instance.getEventCollection(), instance, eventsPerStream, instance.getAgentInstanceContext()); } else { update.getTableUpdateStrategy().updateTable(events, instance, eventsPerStream, instance.getAgentInstanceContext()); } return CollectionUtil.EVENTBEANARRAY_EMPTY; } public Collection<EventBean> snapshotBestEffort(EPPreparedExecuteMethodQuery query, QueryGraph queryGraph, Annotation[] annotations) { ExprTableEvalLockUtil.obtainLockUnless(instance.getTableLevelRWLock().readLock(), query.getAgentInstanceContext()); Collection<EventBean> events = snapshotNullWhenNoIndex(queryGraph, annotations, null, null); if (events != null) { return events; } return instance.getEventCollection(); } private Collection<EventBean> snapshotAndApplyFilter(QueryGraph queryGraph, Annotation[] annotations, ExprNode filterExpr, AgentInstanceContext agentInstanceContext) { Collection<EventBean> indexedResult = snapshotNullWhenNoIndex(queryGraph, annotations, null, null); if (indexedResult != null) { if (indexedResult.isEmpty() || filterExpr == null) { return indexedResult; } ArrayDeque<EventBean> deque = new ArrayDeque<EventBean>(Math.min(indexedResult.size(), 16)); ExprNodeUtility.applyFilterExpressionIterable(indexedResult.iterator(), filterExpr.getExprEvaluator(), agentInstanceContext, deque); return deque; } // fall back to window operator if snapshot doesn't resolve successfully Collection<EventBean> sourceCollection = instance.getEventCollection(); Iterator<EventBean> it = sourceCollection.iterator(); if (!it.hasNext()) { return Collections.EMPTY_LIST; } ArrayDeque<EventBean> deque = new ArrayDeque<EventBean>(sourceCollection.size()); if (filterExpr != null) { ExprNodeUtility.applyFilterExpressionIterable(sourceCollection.iterator(), filterExpr.getExprEvaluator(), agentInstanceContext, deque); } else { while (it.hasNext()) { deque.add(it.next()); } } return deque; } /** * Returns null when a filter cannot be applied, and a collection iterator must be used instead. * Returns best-effort matching events otherwise which should still be run through any filter expressions. */ private Collection<EventBean> snapshotNullWhenNoIndex(QueryGraph queryGraph, Annotation[] annotations, ExprNode optionalWhereClause, AgentInstanceContext agentInstanceContext) { // return null when filter cannot be applies return FireAndForgetQueryExec.snapshot(queryGraph, annotations, null, instance.getIndexRepository(), instance.getTableMetadata().isQueryPlanLogging(), TableServiceImpl.getQueryPlanLog(), instance.getTableMetadata().getTableName(), instance.getAgentInstanceContext()); } public AgentInstanceContext getAgentInstanceContext() { return instance.getAgentInstanceContext(); } public Viewable getTailViewInstance() { return null; } public VirtualDWView getVirtualDataWindow() { return null; } }