/** * PRE: NodeFactory, ConnectionFactory must exist * * @param reteContainer the ReteNet whose interior is to be mapped. */ public NodeProvisioner(ReteContainer reteContainer) { super(); this.reteContainer = reteContainer; this.nodeFactory = reteContainer.getNodeFactory(); this.connectionFactory = reteContainer.getConnectionFactory(); this.inputConnector = reteContainer.getInputConnectionFactory(); }
/** * Internal message delivery method. * * @pre threads > 0 */ private void sendUpdate( Address<? extends Receiver> receiver, Direction direction, Tuple updateElement) { ReteContainer affectedContainer = receiver.getContainer(); synchronized (globalTerminationCriteria) { long newCriterion = affectedContainer.sendUpdateToLocalAddress(receiver, direction, updateElement); terminationCriterion(affectedContainer, newCriterion); } }
/** * Internal message delivery method. * * @pre threads > 0 */ private void sendUpdates( Address<? extends Receiver> receiver, Direction direction, Collection<Tuple> updateElements) { if (updateElements.isEmpty()) return; ReteContainer affectedContainer = receiver.getContainer(); synchronized (globalTerminationCriteria) { long newCriterion = affectedContainer.sendUpdatesToLocalAddress(receiver, direction, updateElements); terminationCriterion(affectedContainer, newCriterion); } }
public synchronized Address<? extends Node> getOrCreateNodeByRecipe(RecipeTraceInfo recipeTrace) { final ReteNodeRecipe recipe = recipeTrace.getRecipe(); Address<? extends Node> result = getNodesByRecipe().get(recipe); if (result != null) { // NODE ALREADY CONSTRUCTED FOR RECIPE, only needs to add trace if (getRecipeTraces().add(recipeTrace)) result.getNodeCache().assignTraceInfo(recipeTrace); } else { // No node for this recipe object - but equivalent recipes still reusable Collection<ReteNodeRecipe> sameClassRecipes = getSameClassRecipes(recipe); for (ReteNodeRecipe knownRecipe : sameClassRecipes) { if (equivalentRecipes(recipe, knownRecipe)) { // FOUND EQUIVALENT RECIPE result = getNodesByRecipe().get(knownRecipe); getNodesByRecipe().put(recipe, result); result.getNodeCache().assignTraceInfo(recipeTrace); break; } } if (result == null) { // MUST INSTANTIATE NEW NODE FOR RECIPE final Node freshNode = instantiateNodeForRecipe(recipeTrace, recipe, sameClassRecipes); result = reteContainer.makeAddress(freshNode); } } return result; }
// local version public synchronized ProjectionIndexer accessProjectionIndexerOnetime( RecipeTraceInfo supplierTrace, TupleMask mask) { if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) return accessProjectionIndexer(supplierTrace, mask); final Address<? extends Node> supplierAddress = getOrCreateNodeByRecipe(supplierTrace); Supplier supplier = (Supplier) reteContainer.resolveLocal(supplierAddress); reteContainer.flushUpdates(); OnetimeIndexer result = new OnetimeIndexer(reteContainer, mask); reteContainer.sendConstructionUpdates( result, Direction.INSERT, reteContainer.pullContents(supplier)); reteContainer.flushUpdates(); return result; }
private Node instantiateNodeForRecipe( RecipeTraceInfo recipeTrace, final ReteNodeRecipe recipe, Collection<ReteNodeRecipe> sameClassRecipes) { if (recipe instanceof IndexerRecipe) { // INSTANTIATE AND HOOK UP // (cannot delay hooking up, because parent determines indexer implementation) ensureParents(recipeTrace); final ReteNodeRecipe parentRecipe = recipeTrace.getParentRecipeTraces().iterator().next().getRecipe(); final Indexer result = nodeFactory.createIndexer( reteContainer, (IndexerRecipe) recipe, asSupplier( (Address<? extends Supplier>) reteContainer.network.getExistingNodeByRecipe(parentRecipe)), recipeTrace); // REMEMBER if (Options.nodeSharingOption != Options.NodeSharingOption.NEVER) { getNodesByRecipe().put(recipe, reteContainer.makeAddress(result)); sameClassRecipes.add(recipe); } return result; } else { // INSTANTIATE Node result = nodeFactory.createNode(reteContainer, recipe, recipeTrace); // REMEMBER if (Options.nodeSharingOption == Options.NodeSharingOption.ALL) { getNodesByRecipe().put(recipe, reteContainer.makeAddress(result)); sameClassRecipes.add(recipe); } // HOOK UP // (recursion-tolerant due to this delayed order of initialization) ensureParents(recipeTrace); if (recipe instanceof InputRecipe) inputConnector.connectInput((InputRecipe) recipe, result); else connectionFactory.connectToParents(recipeTrace, result); return result; } }
// local version // TODO remove? public synchronized ProjectionIndexer accessProjectionIndexer( RecipeTraceInfo supplierTrace, TupleMask mask) { final org.eclipse.incquery.runtime.rete.recipes.ProjectionIndexerRecipe projectionIndexerRecipe = projectionIndexerRecipe(supplierTrace, mask); final UserRequestTrace indexerTrace = new UserRequestTrace(projectionIndexerRecipe, supplierTrace); final Address<? extends Node> address = getOrCreateNodeByRecipe(indexerTrace); return (ProjectionIndexer) reteContainer.resolveLocal(address); }
/** * Waits until all rete update operations are settled in all containers. Returns immediately, if * no updates are pending. * * <p>To be called from any user thread. */ public void waitForReteTermination() { if (threads > 0) { synchronized (globalTerminationCriteria) { while (!globalTerminationCriteria.isEmpty()) { try { globalTerminationCriteria.wait(); } catch (InterruptedException e) { } } } } else headContainer.messageConsumptionSingleThreaded(); }
// local, read-only version public synchronized ProjectionIndexer peekProjectionIndexer( RecipeTraceInfo supplierTrace, TupleMask mask) { final Address<? extends Node> address = getNodesByRecipe().get(projectionIndexerRecipe(supplierTrace, mask)); return address == null ? null : (ProjectionIndexer) reteContainer.resolveLocal(address); }
/** The powerful method for accessing any (supplier) Address as a local supplier. */ public Supplier asSupplier(Address<? extends Supplier> address) { if (!reteContainer.isLocal(address)) return accessRemoteSupplier(address); else return reteContainer.resolveLocal(address); }
/** * Internal message delivery method for single-threaded operation * * @pre threads == 0 */ private void sendUpdateSingleThreaded( Address<? extends Receiver> receiver, Direction direction, Tuple updateElement) { ReteContainer affectedContainer = receiver.getContainer(); affectedContainer.sendUpdateToLocalAddressSingleThreaded(receiver, direction, updateElement); }
/** Kills this Network along with all containers and message consumption cycles. */ public void kill() { for (ReteContainer container : containers) { container.kill(); } containers.clear(); }
protected void propagateUpdate(Direction direction, Tuple updateElement) { for (Receiver r : children) reteContainer.sendUpdateInternal(r, direction, updateElement); }
public StandardNode(ReteContainer reteContainer) { this.reteContainer = reteContainer; this.nodeId = reteContainer.registerNode(this); children = new LinkedList<Receiver>(); }