Package lupos.distributed.p2p.storage

Source Code of lupos.distributed.p2p.storage.StorageWithDistributionStrategy

/**
* 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.p2p.storage;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import lupos.datastructures.bindings.Bindings;
import lupos.datastructures.bindings.BindingsFactory;
import lupos.datastructures.items.Item;
import lupos.datastructures.items.Triple;
import lupos.datastructures.items.Variable;
import lupos.datastructures.items.literal.Literal;
import lupos.datastructures.queryresult.QueryResult;
import lupos.distributed.p2p.network.AbstractP2PNetwork;
import lupos.distributed.storage.IStorage;
import lupos.distributed.storage.distributionstrategy.IDistribution;
import lupos.distributed.storage.distributionstrategy.TriplePatternNotSupportedError;
import lupos.engine.operators.multiinput.join.parallel.ResultCollector;
import lupos.engine.operators.tripleoperator.TriplePattern;
import lupos.distributed.storage.distributionstrategy.tripleproperties.KeyContainer;

/**
* This is the {@link IStorage} used for P2P distribution. The class holds
* connection to the p2p network for adding, removing and getting items.
*
* @author Bjoern
*
* @param <T>
*            The type of distribution used in {@link KeyContainer}.
* @see BlockStorageWithDistributionStrategy
*/
public class StorageWithDistributionStrategy<T> implements IStorage {

  /**
   * The distribution strategy
   */
  protected final IDistribution<KeyContainer<T>> distribution;
  /**
   * the p2p network
   */
  protected AbstractP2PNetwork<Triple> p2p;

  /**
   * Returns the used distribution strategy
   *
   * @return the distribution strategy
   */
  public IDistribution<KeyContainer<T>> getDistribution() {
    return this.distribution;
  }

  /**
   * New storage for luposdate connected with a p2p-network implementation and
   * the used distribution strategy with new bindings factory
   *
   * @param p2pImplementation
   *            the p2p implementation
   * @param distribution
   *            the distribution strategy
   */
  @Deprecated
  public StorageWithDistributionStrategy(
      AbstractP2PNetwork<Triple> p2pImplementation,
      IDistribution<KeyContainer<T>> distribution) {
    if (distribution == null || p2pImplementation == null)
      throw new RuntimeException(
          "No valid arguments in STORAGE-implementation.");
    this.distribution = distribution;
    this.p2p = p2pImplementation;
    this.bindingsFactory = BindingsFactory.createBindingsFactory();
  }
 
  /**
   * New storage for luposdate connected with a p2p-network implementation and
   * the used distribution strategy.
   *
   * @param p2pImplementation
   *            the p2p implementation
   * @param distribution
   *            the distribution strategy
   *            @param bindingsFactory the bindings factory
   */
  public StorageWithDistributionStrategy(
      AbstractP2PNetwork<Triple> p2pImplementation,
      IDistribution<KeyContainer<T>> distribution,
      final BindingsFactory bindingsFactory) {
    if (distribution == null || p2pImplementation == null)
      throw new RuntimeException(
          "No valid arguments in STORAGE-implementation.");
    this.distribution = distribution;
    this.p2p = p2pImplementation;
    this.bindingsFactory = bindingsFactory;
  }
 
 
  @Override
  public void endImportData() {
    /*
     * used if block-wise import, maybe for later versions
     */
  }

  @Override
  public void addTriple(Triple triple) {
    KeyContainer<T>[] keys = this.distribution.getKeysForStoring(triple);
    for (final KeyContainer<T> key : keys) {
      /*
       * store each key
       */
      String newKey = getKey(key);
      addTriple(newKey, triple);
    }
  }

  protected void addTriple(String key, Triple t) {
    this.p2p.add(key, t);
  }

  @Override
  public boolean containsTriple(Triple triple) {
    KeyContainer<T>[] keys = this.distribution.getKeysForStoring(triple);
    for (final KeyContainer<T> key : keys) {
      String newKey = getKey(key);
      // we need here only to check one existing, or?
      return this.p2p.contains(newKey, triple);
    }
    return false;
  }

  @Override
  public void remove(Triple triple) {
    KeyContainer<T>[] keys = this.distribution.getKeysForStoring(triple);
    for (final KeyContainer<T> key : keys) {
      String newKey = getKey(key);
      // we need here only to check one existing, or?
      /*
       * we have to prevent double insertion of same triples!, then this
       * suffers
       */
      remove(newKey, triple);
    }
  }

  protected void remove(String key, Triple t) {
    this.p2p.remove(key, t);
  }

  @Override
  public QueryResult evaluateTriplePattern(final TriplePattern triplePattern)
      throws Exception {
    l.debug("evaluateTriplePattern " + triplePattern);
    try {
      final KeyContainer<T>[] keys = this.distribution
          .getKeysForQuerying(triplePattern);
      if (keys.length == 1) {
        return this.evaluateTriplePatternAfterAdding(keys[0],
            triplePattern);
      } else {
        // fix
        final ResultCollector resultCollector = new ResultCollector();
 
        // asynchronously retrieve the results...
        resultCollector.setNumberOfThreads(keys.length);
        final Thread[] threads = new Thread[keys.length];
        for (int i = 0; i < keys.length; i++) {
          final KeyContainer<T> key = keys[i];
          threads[i] = new Thread() {
            @Override
            public void run() {
              resultCollector.process(
                  StorageWithDistributionStrategy.this
                      .evaluateTriplePatternAfterAdding(
                          key, triplePattern), 0);
              resultCollector.incNumberOfThreads();
            }
          };
          threads[i]
              .setName(String
                  .format("Parallel pattern evaluation: key=%s%s, pattern=%s",
                      key.type, key.key, triplePattern));
          threads[i].start();
        }
        return resultCollector.getResult();
      }
    } catch (final TriplePatternNotSupportedError e) {
      return this.evaluateTriplePatternAfterAdding(triplePattern);
    }

  }

  public QueryResult evaluateTriplePatternAfterAdding(
      final TriplePattern triplePattern)
      throws TriplePatternNotSupportedError {
    throw new TriplePatternNotSupportedError(this.distribution,
        triplePattern);
  }

  /**
   * produces a new key with the given keycontainer
   *
   * @param keyContainer
   *            the key container
   * @return new key = %type%.concat(%key%)
   */
  public static String getKey(KeyContainer<?> keyContainer) {
    return String.format("%s%s", keyContainer.type, keyContainer.key);
  }

  private QueryResult evaluateTriplePatternAfterAdding(
      KeyContainer<T> keyContainer, TriplePattern triplePattern) {
    String newKey = getKey(keyContainer);
    List<Triple> foundTriples = this.p2p.get(newKey);
    return tripleResultAsQueryResult(triplePattern, foundTriples);
  }

  private QueryResult tripleResultAsQueryResult(TriplePattern triplePattern,
      List<Triple> foundTriples) {
    QueryResult result = QueryResult.createInstance();
    if (foundTriples != null)
      for (Triple t : foundTriples) {
        Bindings b = addVariablesToBindings(triplePattern.getItems(), t);
        if (b != null)
          result.add(b);
      }
    return result;
  }

  private Bindings addVariablesToBindings(Item[] items, Triple t) {
   
    Bindings b = bindingsFactory.createInstance();
    for (int i = 0; i < items.length; i++) {
      Item item = items[i];
      if (item.getClass() == Variable.class) {
        Variable v = (Variable) item;
        b.add(v, t.getPos(i));

      } else {
        if (t.getPos(i)
            .compareToNotNecessarilySPARQLSpecificationConform(
                (Literal) item) != 0) {
          return null;
        }
      }
    }
    return b;
  }

  private static Logger l = LoggerFactory
      .getLogger(StorageWithDistributionStrategy.class);

 
  /**
   * for creating bindings...
   */
  protected BindingsFactory bindingsFactory;
 
 
  @Override
  public void setBindingsFactory(BindingsFactory bindingsFactory) {
    this.bindingsFactory = bindingsFactory;
  }
}
TOP

Related Classes of lupos.distributed.p2p.storage.StorageWithDistributionStrategy

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.