/*******************************************************************************
* Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Gabor Bergmann - initial API and implementation
*******************************************************************************/
package org.eclipse.incquery.runtime.rete.index;
import java.util.Collection;
import org.eclipse.incquery.runtime.rete.network.Direction;
import org.eclipse.incquery.runtime.rete.network.ReteContainer;
import org.eclipse.incquery.runtime.rete.tuple.Tuple;
import org.eclipse.incquery.runtime.rete.tuple.TupleMask;
/**
* @author Gabor Bergmann
*
*/
public class JoinNode extends DualInputNode {
/**
* @param reteContainer
* @param primarySlot
* @param secondarySlot
*/
public JoinNode(ReteContainer reteContainer, IterableIndexer primarySlot, Indexer secondarySlot,
TupleMask complementerSecondaryMask) {
super(reteContainer, primarySlot, secondarySlot, complementerSecondaryMask);
// TODO Auto-generated constructor stub
}
@Override
public Tuple calibrate(Tuple primary, Tuple secondary) {
return unify(primary, secondary);
}
// public static Tuple calibrate(Tuple primary, Tuple secondary,
// TupleMask complementerSecondaryMask) {
// return complementerSecondaryMask.combine(primary, secondary,
// Options.enableInheritance, true);
// }
@Override
public void notifyUpdate(Side side, Direction direction, Tuple updateElement, Tuple signature, boolean change) {
Collection<Tuple> opposites = retrieveOpposites(side, signature);
if (opposites != null) {
for (Tuple opposite : opposites) {
propagateUpdate(direction, unify(side, updateElement, opposite));
}
}
// compensate for coincidence of slots
if (coincidence) {
if (opposites != null) {
for (Tuple opposite : opposites) {
if (opposite.equals(updateElement))
continue; // INSERT: already joined with itself
propagateUpdate(direction, unify(opposite, updateElement));
}
}
if (direction == Direction.REVOKE) // missed joining with itself
propagateUpdate(direction, unify(updateElement, updateElement));
//
// switch(direction) {
// case INSERT:
// opposites = new ArrayList<Tuple>(opposites);
// opposites.remove(updateElement);
// break;
// case REVOKE:
// opposites = (opposites == null) ? new ArrayList<Tuple>() : new ArrayList<Tuple>(opposites);
// opposites.add(updateElement);
// break;
// }
//
}
}
@Override
public void pullInto(Collection<Tuple> collector) {
reteContainer.flushUpdates();
for (Tuple signature : primarySlot.getSignatures()) {
Collection<Tuple> primaries = primarySlot.get(signature); // not null due to the contract of
// IterableIndex.getSignatures()
Collection<Tuple> opposites = secondarySlot.get(signature);
if (opposites != null)
for (Tuple ps : primaries)
for (Tuple opposite : opposites) {
collector.add(unify(ps, opposite));
}
}
}
}