Package lupos.distributed.operator

Source Code of lupos.distributed.operator.SubgraphContainer

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.distributed.operator;

import lupos.datastructures.bindings.BindingsFactory;
import lupos.datastructures.queryresult.QueryResult;
import lupos.distributed.operator.format.SubgraphContainerFormatter;
import lupos.distributed.storage.distributionstrategy.tripleproperties.KeyContainer;
import lupos.engine.operators.BasicOperator;
import lupos.engine.operators.RootChild;
import lupos.engine.operators.SimpleOperatorGraphVisitor;
import lupos.engine.operators.index.Dataset;
import lupos.engine.operators.index.Root;
import lupos.engine.operators.messages.BindingsFactoryMessage;
import lupos.engine.operators.messages.BoundVariablesMessage;
import lupos.engine.operators.messages.Message;
import lupos.engine.operators.singleinput.Result;
import lupos.rdf.Prefix;

import org.json.JSONException;
import org.json.JSONObject;

/**
* This container contains all operators that shall be send to a node for execution.
*
* @param <K> the type of key used to address the node where this operator graph is sent to.
* @since 12/2013 - added support for retrieving variables via {@link BoundVariablesMessage}
*/
public class SubgraphContainer<K> extends RootChild {

  /**
   * The root node of the sub graph.
   */
  private final Root rootNodeOfSubGraph;

  /**
   * the key which identifies to which node the operator graph is sent to
   */
  private K key;

  /**
   * the executor to submit a subgraph and retrieve its query result...
   */
  protected final ISubgraphExecutor<K> subgraphExecutor;

  /**
   * for creating Bindings...
   */
  protected BindingsFactory bindingsFactory;


  /**
   * Instantiates a new sub graph container.
   *
   * @param rootNodeOfSubGraph
   *     the root node of sub graph
   * @param key the key which identifies to which node the operator graph is sent to
   * @throws JSONException
   */
  public SubgraphContainer(final Root rootNodeOfSubGraph, final K key, final ISubgraphExecutor<K> subgraphExecutor) throws JSONException {
    this.key = key;
    this.rootNodeOfSubGraph = rootNodeOfSubGraph;
    this.subgraphExecutor = subgraphExecutor;
  }

  @Override
  public Message preProcessMessage(final BindingsFactoryMessage msg){
    this.bindingsFactory = msg.getBindingsFactory();
    return msg;
  }


  /**
   * Gets called when the operator is to be executed. When called this method sends the sub graph to the responsible
   * nodes for execution and waits for the result to return.
   *
   * @param dataset
   *     the data set
   *
   * @return the result of the query execution
   */
  @Override
  public QueryResult process(final Dataset dataset) {
    final SubgraphContainerFormatter serializer = new SubgraphContainerFormatter();
    try {
      final JSONObject serializedGraph = serializer.serialize(this.rootNodeOfSubGraph, 0);
      final QueryResult result = this.subgraphExecutor.evaluate(this.key,  serializedGraph.toString(),this.bindingsFactory);
      result.materialize(); // just for now read all from the stream sent by the endpoint, otherwise it may be blocked! (may be removed if each endpoint can work completely in parallel!)
      return result;
    } catch (final JSONException e) {
      System.err.println(e);
      e.printStackTrace();
      return null;
    }
  }



  /**
   * Returns the key of the {@link SubgraphContainer}
   * @return the key used for distribution
   */
  public K getKey() {
    return this.key;
  }


  @Override
  public String toString() {
    if (this.key instanceof KeyContainer) {
      /*
       * this is only for debugging, so that in visual editor, the key of the subgraph is to be read
       * (works here only if KeyContainer is used as key)
       */
      return String.format("SubgraphContainer \r\n[%s%s]",((KeyContainer<?>)this.key).type,((KeyContainer<?>)this.key).key);
    } else {
      return "SubgraphContainer";
    }
  }


  @Override
  public String toString(final Prefix prefixInstance) {
    return this.toString();
  }

  /**
   * Returns the inner root of the {@link SubgraphContainer}
   * @return the root
   */
  public Root getRootOfSubgraph(){
    return this.rootNodeOfSubGraph;
  }

  @Override
  public Message preProcessMessage(final BoundVariablesMessage msg) {
    final BoundVariablesMessage newMsg = new BoundVariablesMessage(msg);
    //Send Message through the subgraph container graph
    this.getRootOfSubgraph().sendMessage(new BoundVariablesMessage());
    // Search for "result"-node
    final Result result = (Result) this.getRootOfSubgraph().visitAndStop(new SimpleOperatorGraphVisitor(){
      @Override
      public Object visit(final BasicOperator basicOperator) {
        if(basicOperator instanceof Result) {
          return basicOperator;
        } else {
          return null;
        }
      }});
    //set the union variables of the result node of the subgraph
    newMsg.setVariables(result.getUnionVariables());
    this.unionVariables = result.getUnionVariables();
    this.intersectionVariables = result.getUnionVariables();
    return newMsg;
  }

  /**
   * Allows to change the Key of the SubgraphContainer, used in optimization if a better key could be used
   * @param newKey the new key
   */
  public void changeKey(final K newKey) {
    if (newKey != null) {
      this.key  = newKey;
    }
  }

  @Override
  public BasicOperator getContainedGraph(){
    return this.rootNodeOfSubGraph;
  }
}
TOP

Related Classes of lupos.distributed.operator.SubgraphContainer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.