/** * Constructs RETE pattern matchers for a collection of patterns, if they are not available yet. * Model traversal during the whole construction period is coalesced (which may have an effect on * performance, depending on the matcher context). * * @pre: builder is set. * @param patterns the patterns to be matched. * @throws RetePatternBuildException if construction fails. */ public synchronized void buildMatchersCoalesced(final Collection<PatternDescription> patterns) throws RetePatternBuildException { context.modelReadLock(); try { if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().lock(); try { try { context.coalesceTraversals( new Callable<Void>() { @Override public Void call() throws RetePatternBuildException { for (PatternDescription gtPattern : patterns) { boundary.accessProduction(gtPattern); } return null; } }); } catch (InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause instanceof RetePatternBuildException) throw (RetePatternBuildException) cause; if (cause instanceof RuntimeException) throw (RuntimeException) cause; assert (false); } } finally { if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().unlock(); } settle(); } finally { context.modelReadUnLock(); } }
/** * Accesses the patternmatcher for a given pattern, constructs one if a matcher is not available * yet. * * @pre: builder is set. * @param gtPattern the pattern to be matched. * @return a patternmatcher object that can match occurences of the given pattern. * @throws RetePatternBuildException if construction fails. */ public synchronized RetePatternMatcher accessMatcher(final PatternDescription gtPattern) throws RetePatternBuildException { RetePatternMatcher matcher; // String namespace = gtPattern.getNamespace().getName(); // String name = gtPattern.getName(); // String fqn = namespace + "." + name; matcher = matchers.get(gtPattern); if (matcher == null) { context.modelReadLock(); try { if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().lock(); try { try { context.coalesceTraversals( new Callable<Void>() { @Override public Void call() throws RetePatternBuildException { Address<? extends Production> prodNode; prodNode = boundary.accessProduction(gtPattern); RetePatternMatcher retePatternMatcher = new RetePatternMatcher(ReteEngine.this, prodNode); retePatternMatcher.setTag(gtPattern); matchers.put(gtPattern, retePatternMatcher); return null; } }); } catch (InvocationTargetException ex) { final Throwable cause = ex.getCause(); if (cause instanceof RetePatternBuildException) throw (RetePatternBuildException) cause; if (cause instanceof RuntimeException) throw (RuntimeException) cause; assert (false); } } finally { if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().unlock(); settle(); } } finally { context.modelReadUnLock(); } // reteNet.flushUpdates(); matcher = matchers.get(gtPattern); } return matcher; }
/** * Returns an indexer that groups the contents of this Production node by their projections to a * given mask. Designed to be called by a RetePatternMatcher. * * @param production the production node to be indexed. * @param mask the mask that defines the projection. * @return the Indexer. */ synchronized Indexer accessProjection(Production production, TupleMask mask) { Library library = reteNet.getHeadContainer().getLibrary(); Indexer result = library.peekProjectionIndexer(production, mask); if (result == null) { context.modelReadLock(); try { if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().lock(); try { result = library.accessProjectionIndexerOnetime(production, mask); } finally { if (parallelExecutionEnabled) reteNet.getStructuralChangeLock().unlock(); } } finally { context.modelReadUnLock(); } } return result; }
/** deconstructs engine components */ private synchronized void deconstructEngine() { reteNet.kill(); for (Disconnectable disc : disconnectables) { disc.disconnect(); } this.matchers = null; this.disconnectables = null; this.reteNet = null; this.boundary = null; // this.machineListener = new MachineListener(this); // prerequisite: // framework, disconnectables this.manipulationListener = null; this.traceListener = null; }
/** * Waits until the pattern matcher is in a steady state and output can be retrieved. When steady * state is reached, a retrieval action is executed before the steady state ceases. * * @param action the action to be run when reaching the steady-state. */ public void settle(Runnable action) { reteNet.waitForReteTermination(action); }
/** Waits until the pattern matcher is in a steady state and output can be retrieved. */ public void settle() { reteNet.waitForReteTermination(); }