/* *************************************************************************************** * 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.epl.join.table; import com.espertech.esper.client.EPException; import com.espertech.esper.client.EventBean; import com.espertech.esper.client.EventPropertyGetter; import com.espertech.esper.collection.MultiKeyUntyped; import com.espertech.esper.epl.expression.core.ExprEvaluatorContext; import com.espertech.esper.metrics.instrumentation.InstrumentationHelper; import java.util.*; public class PropertyIndexedEventTableUnique extends PropertyIndexedEventTable implements EventTableAsSet { protected final Map<MultiKeyUntyped, EventBean> propertyIndex; private final boolean canClear; public PropertyIndexedEventTableUnique(EventPropertyGetter[] propertyGetters, EventTableOrganization organization) { super(propertyGetters, organization); propertyIndex = new HashMap<MultiKeyUntyped, EventBean>(); this.canClear = true; } public PropertyIndexedEventTableUnique(EventPropertyGetter[] propertyGetters, EventTableOrganization organization, Map<MultiKeyUntyped, EventBean> propertyIndex) { super(propertyGetters, organization); this.propertyIndex = propertyIndex; this.canClear = false; } /** * Remove then add events. * @param newData to add * @param oldData to remove * @param exprEvaluatorContext evaluator context */ @Override public void addRemove(EventBean[] newData, EventBean[] oldData, ExprEvaluatorContext exprEvaluatorContext) { if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().qIndexAddRemove(this, newData, oldData); } if (oldData != null) { for (EventBean theEvent : oldData) { remove(theEvent, exprEvaluatorContext); } } if (newData != null) { for (EventBean theEvent : newData) { add(theEvent, exprEvaluatorContext); } } if (InstrumentationHelper.ENABLED) { InstrumentationHelper.get().aIndexAddRemove(); } } public Set<EventBean> lookup(Object[] keys) { MultiKeyUntyped key = new MultiKeyUntyped(keys); EventBean event = propertyIndex.get(key); if (event != null) { return Collections.singleton(event); } return null; } public void add(EventBean theEvent, ExprEvaluatorContext exprEvaluatorContext) { MultiKeyUntyped key = getMultiKey(theEvent); EventBean existing = propertyIndex.put(key, theEvent); if (existing != null && !existing.equals(theEvent)) { throw handleUniqueIndexViolation(organization.getIndexName(), key); } } public static EPException handleUniqueIndexViolation(String indexName, Object key) { String indexNameDisplay = indexName == null ? "" : " '" + indexName + "'"; throw new EPException("Unique index violation, index" + indexNameDisplay + " is a unique index and key '" + key + "' already exists"); } public void remove(EventBean theEvent, ExprEvaluatorContext exprEvaluatorContext) { MultiKeyUntyped key = getMultiKey(theEvent); propertyIndex.remove(key); } public boolean isEmpty() { return propertyIndex.isEmpty(); } public Iterator<EventBean> iterator() { return propertyIndex.values().iterator(); } public void clear() { if (canClear) { propertyIndex.clear(); } } public void destroy() { clear(); } public Integer getNumberOfEvents() { return propertyIndex.size(); } public int getNumKeys() { return propertyIndex.size(); } public Object getIndex() { return propertyIndex; } public Set<EventBean> allValues() { if (propertyIndex.isEmpty()) { return Collections.emptySet(); } return new HashSet<EventBean>(propertyIndex.values()); } public Class getProviderClass() { return PropertyIndexedEventTableUnique.class; } }