at.sti2.spark.rete.beta.JoinNode.java Source code

Java tutorial

Introduction

Here is the source code for at.sti2.spark.rete.beta.JoinNode.java

Source

/*
 * Copyright (c) 2010, University of Innsbruck, Austria.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package at.sti2.spark.rete.beta;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import at.sti2.spark.core.collect.IndexStructure;
import at.sti2.spark.core.stream.Triple;
import at.sti2.spark.core.triple.RDFTriple;
import at.sti2.spark.core.triple.TripleCondition;
import at.sti2.spark.core.triple.RDFTriple.Field;
import at.sti2.spark.core.triple.RDFValue;
import at.sti2.spark.rete.Token;
import at.sti2.spark.rete.WorkingMemoryElement;
import at.sti2.spark.rete.alpha.AlphaMemory;
import at.sti2.spark.rete.node.RETENode;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;

public class JoinNode extends RETENode {

    private AlphaMemory alphaMemory = null;
    private List<JoinNodeTest> tests = null;
    private long timeWindowLength = 0l;
    private TripleCondition tripleCondition = null;

    public JoinNode(TripleCondition tripleCondition, long timeWindowLength) {
        tests = new ArrayList<JoinNodeTest>();
        this.timeWindowLength = timeWindowLength;
        this.tripleCondition = tripleCondition;
    }

    public AlphaMemory getAlphaMemory() {
        return alphaMemory;
    }

    public void setAlphaMemory(AlphaMemory alphaMemory) {
        this.alphaMemory = alphaMemory;
    }

    public List<JoinNodeTest> getTests() {
        return tests;
    }

    public void addJoinNodeTest(JoinNodeTest test) {
        tests.add(test);
    }

    public TripleCondition getTripleCondition() {
        return tripleCondition;
    }

    /**
     * Activation coming from an alpha memory.
     */
    @Override
    public void rightActivate(WorkingMemoryElement wme) {

        // If the join node is under dummy root beta node left activation should
        // fire      
        if (((BetaMemory) parent).isRootNode()) {

            for (RETENode reteNode : children)
                reteNode.leftActivate(null, wme);

        } else {

            if (tests.size() > 0) {

                Set<Token> resultSet = null;
                Set<Token> intermediateSet = new LinkedHashSet<Token>();

                for (JoinNodeTest test : tests) {

                    Field arg2Field = test.getArg2Field();
                    RDFValue testTokenValue = wme.getTriple().getRDFTriple().getValueOfField(test.getArg1Field());

                    Set<Token> tokensFromIndex = null;
                    if (arg2Field == RDFTriple.Field.SUBJECT) {
                        tokensFromIndex = test.getIndexStructure().getElementsFromSubjectIndex(testTokenValue);
                    } else if (arg2Field == RDFTriple.Field.PREDICATE) {
                        tokensFromIndex = test.getIndexStructure().getElementsFromPredicateIndex(testTokenValue);
                    } else if (arg2Field == RDFTriple.Field.OBJECT) {
                        tokensFromIndex = test.getIndexStructure().getElementsFromObjectIndex(testTokenValue);
                    }

                    // Get Tokens at the level of parent beta memory
                    for (Token token : tokensFromIndex) {
                        Set<Token> childTokensAtBetaMemory = token.getChildTokensAtBetaMemory((BetaMemory) parent);
                        intermediateSet = Sets.union(childTokensAtBetaMemory, intermediateSet);
                    }

                    if (resultSet == null && intermediateSet != null) {
                        resultSet = intermediateSet;
                    } else if (intermediateSet != null) {
                        resultSet = Sets.intersection(resultSet, intermediateSet);
                    }

                }

                if (resultSet != null) {
                    for (Token token : resultSet) {

                        // Check if the token and wme are falling into a window
                        if (token.getWme().getTriple().isPermanent() || performTimeWindowTest(token, wme)) {
                            // All tests successful
                            for (RETENode reteNode : children)
                                reteNode.leftActivate(token, wme);
                        }

                    }
                }
            } else {
                ArrayList<Token> elementsFromTokenQueue = ((BetaMemory) parent).getIndexStructure()
                        .getElementsFromTokenQueue();
                for (RETENode reteNode : children)
                    for (Token token : elementsFromTokenQueue)
                        reteNode.leftActivate(token, wme);
            }

        }
    }

    /**
     * Activation coming from a beta/root node.
     */
    @Override
    public void leftActivate(Token token) {
        leftActivate(token, alphaMemory);
    }

    /**
     * Checks whether there are wme in index structure that match tests and token
     * @param token
     * @param alphaMemory
     */
    private void leftActivate(Token token, AlphaMemory alphaMemory) {

        if (tests.size() > 0) {
            Set<WorkingMemoryElement> resultSet = null;
            Set<WorkingMemoryElement> intermediateSet = null;
            for (JoinNodeTest test : tests) {

                Field arg1Field = test.getArg1Field();
                Token parentToken = token.getParentTokenAtBetaMemory(test.getBetaMemory());
                RDFValue testTokenValue = parentToken.getWme().getTriple().getRDFTriple()
                        .getValueOfField(test.getArg2Field());

                if (arg1Field == RDFTriple.Field.SUBJECT) {
                    intermediateSet = alphaMemory.getIndexStructure().getElementsFromSubjectIndex(testTokenValue);
                } else if (arg1Field == RDFTriple.Field.PREDICATE) {
                    intermediateSet = alphaMemory.getIndexStructure().getElementsFromPredicateIndex(testTokenValue);
                } else if (arg1Field == RDFTriple.Field.OBJECT) {
                    intermediateSet = alphaMemory.getIndexStructure().getElementsFromObjectIndex(testTokenValue);
                }

                if (resultSet == null && intermediateSet != null) {
                    resultSet = intermediateSet;
                } else if (intermediateSet != null) {
                    resultSet = Sets.intersection(resultSet, intermediateSet);
                }

            }

            if (resultSet != null) {
                for (WorkingMemoryElement wme : resultSet) {

                    // Check if the token and wme are falling into a window
                    if (wme.getTriple().isPermanent() || performTimeWindowTest(token, wme)) {
                        // All tests successful
                        for (RETENode reteNode : children)
                            reteNode.leftActivate(token, wme);
                    }

                }
            }

        } else {
            ArrayList<WorkingMemoryElement> elementsFromTokenQueue = alphaMemory.getIndexStructure()
                    .getElementsFromTokenQueue();
            for (WorkingMemoryElement wme : elementsFromTokenQueue) {

                if (wme.getTriple().isPermanent() || performTimeWindowTest(token, wme)) {

                    for (RETENode reteNode : children) {
                        reteNode.leftActivate(token, wme);
                    }
                }
            }
        }

    }

    public void setTests(List<JoinNodeTest> tests) {
        this.tests = tests;
    }

    private boolean performTimeWindowTest(Token token, WorkingMemoryElement wme) {
        Triple triple = wme.getTriple();
        long tripleTimestamp = triple.getTimestamp();
        long tokenStartTime = token.getStartTime();
        long tokenEndTime = token.getEndTime();

        if (tripleTimestamp < tokenStartTime)
            return (tokenEndTime - tripleTimestamp) < timeWindowLength;
        else if (tripleTimestamp > tokenEndTime)
            return (tripleTimestamp - tokenStartTime) < timeWindowLength;
        else
            return tokenEndTime - tokenStartTime < timeWindowLength;
    }

    @Override
    public void leftActivate(Token token, WorkingMemoryElement wme) {
        // TODO Auto-generated method stub
    }

    @Override
    public String toString() {
        StringBuffer buffer = new StringBuffer();

        buffer.append("Tests: \n");
        for (JoinNodeTest test : tests) {
            buffer.append(test.toString());
            buffer.append("\n");
        }

        return buffer.toString();
    }
}