/** * 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(); } }
/** initializes engine components */ private synchronized void initEngine() { this.disconnectables = new LinkedList<Disconnectable>(); // this.caughtExceptions = new LinkedBlockingQueue<Throwable>(); this.reteNet = new Network(reteThreads, context); this.boundary = new ReteBoundary<PatternDescription>(this); // prerequisite: network this.matchers = new HashMap<PatternDescription, RetePatternMatcher>(); /* this.matchersScoped = new HashMap<PatternDescription, Map<Map<Integer,Scope>,RetePatternMatcher>>(); */ // prerequisite: network, framework, boundary, disconnectables this.manipulationListener = context.subscribePatternMatcherForUpdates(this); // prerequisite: boundary, disconnectables this.traceListener = context.subscribePatternMatcherForTraceInfluences(this); }
/** * 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; }