Package com.orientechnologies.orient.graph.sql.functions

Source Code of com.orientechnologies.orient.graph.sql.functions.OSQLFunctionShortestPath

/*
  *
  *  *  Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
  *  *
  *  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  *  you may not use this file except in compliance with the License.
  *  *  You may obtain a copy of the License at
  *  *
  *  *       http://www.apache.org/licenses/LICENSE-2.0
  *  *
  *  *  Unless required by applicable law or agreed to in writing, software
  *  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  *  See the License for the specific language governing permissions and
  *  *  limitations under the License.
  *  *
  *  * For more information: http://www.orientechnologies.com
  *
  */
package com.orientechnologies.orient.graph.sql.functions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.orientechnologies.common.collection.OMultiValue;
import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.sql.OSQLHelper;
import com.orientechnologies.orient.core.sql.functions.math.OSQLFunctionMathAbstract;
import com.orientechnologies.orient.graph.sql.OGraphCommandExecutorSQLFactory;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientBaseGraph;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;
import com.tinkerpop.pipes.util.structures.ArrayQueue;

/**
* Shortest path algorithm to find the shortest path from one node to another node in a directed graph.
*
* @author Luca Garulli (l.garulli--at--orientechnologies.com)
*
*/
public class OSQLFunctionShortestPath extends OSQLFunctionMathAbstract {
  public static final String   NAME     = "shortestPath";

  protected static final float DISTANCE = 1f;

  public OSQLFunctionShortestPath() {
    super(NAME, 2, 3);
  }

  public Object execute(Object iThis, final OIdentifiable iCurrentRecord, Object iCurrentResult, final Object[] iParams,
      final OCommandContext iContext) {
    final OrientBaseGraph graph = OGraphCommandExecutorSQLFactory.getGraph(false);

    final ORecord record = (ORecord) (iCurrentRecord != null ? iCurrentRecord.getRecord() : null);

    Object source = iParams[0];
    if (OMultiValue.isMultiValue(source)) {
      if (OMultiValue.getSize(source) > 1)
        throw new IllegalArgumentException("Only one sourceVertex is allowed");
      source = OMultiValue.getFirstValue(source);
    }
    OrientVertex sourceVertex = graph.getVertex(OSQLHelper.getValue(source, record, iContext));

    Object dest = iParams[1];
    if (OMultiValue.isMultiValue(dest)) {
      if (OMultiValue.getSize(dest) > 1)
        throw new IllegalArgumentException("Only one destinationVertex is allowed");
      dest = OMultiValue.getFirstValue(dest);
    }
    OrientVertex destinationVertex = graph.getVertex(OSQLHelper.getValue(dest, record, iContext));

    if (sourceVertex.equals(destinationVertex)) {
      final List<ORID> result = new ArrayList<ORID>(1);
      result.add(destinationVertex.getIdentity());
      return result;
    }

    Direction direction = Direction.BOTH;
    if (iParams.length > 2)
      direction = Direction.valueOf(iParams[2].toString().toUpperCase());

    final ArrayQueue<OrientVertex> queue = new ArrayQueue<OrientVertex>();
    final Set<ORID> visited = new HashSet<ORID>();
    final Map<ORID, ORID> previouses = new HashMap<ORID, ORID>();

    queue.add(sourceVertex);
    visited.add(sourceVertex.getIdentity());

    OrientVertex current;
    while (!queue.isEmpty()) {
      current = queue.poll();

      final Iterable<Vertex> neighbors = current.getVertices(direction);
      for (Vertex neighbor : neighbors) {
        final OrientVertex v = (OrientVertex) neighbor;
        final ORID neighborIdentity = v.getIdentity();

        if (!visited.contains(neighborIdentity)) {

          previouses.put(neighborIdentity, current.getIdentity());

          if (destinationVertex.equals(neighbor))
            return computePath(previouses, neighborIdentity);

          queue.offer(v);
          visited.add(neighborIdentity);
        }

      }
    }

    return new ArrayList<ORID>();
  }

  public String getSyntax() {
    return "shortestPath(<sourceVertex>, <destinationVertex>, [<direction>])";
  }

  private Object computePath(final Map<ORID, ORID> distances, final ORID neighbor) {
    final List<ORID> result = new ArrayList<ORID>();

    ORID current = neighbor;
    while (current != null) {
      result.add(0, current);

      current = distances.get(current);
    }

    return result;
  }
}
TOP

Related Classes of com.orientechnologies.orient.graph.sql.functions.OSQLFunctionShortestPath

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.