<commit_before>/*
 *
 *  *  Copyright 2010-2016 OrientDB LTD (http://orientdb.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://orientdb.com
 *
 */
package com.orientechnologies.orient.graph.sql.functions;

import com.orientechnologies.common.collection.OMultiValue;
import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.command.OCommandExecutorAbstract;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.exception.OCommandExecutionException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.impl.ODocument;
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 java.util.*;

/**
 * Shortest path algorithm to find the shortest path from one node to another node in a directed graph.
 *
 * @author <NAME> (l.garulli--(at)--orientdb.com)
 * @deprecated see {@link com.orientechnologies.orient.core.sql.functions.graph.OSQLFunctionShortestPath} instead
 *
 */
@Deprecated
public class OSQLFunctionShortestPath extends OSQLFunctionMathAbstract {
  public static final String NAME = "shortestPath";
  public static final String PARAM_MAX_DEPTH = "maxDepth";

  protected static final float DISTANCE = 1f;

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

  private class OShortestPathContext {
    OrientVertex sourceVertex;
    OrientVertex destinationVertex;
    Direction directionLeft  = Direction.BOTH;
    Direction directionRight = Direction.BOTH;

    String   edgeType;
    String[] edgeTypeParam;

    ArrayDeque<OrientVertex> queueLeft  = new ArrayDeque<OrientVertex>();
    ArrayDeque<OrientVertex> queueRight = new ArrayDeque<OrientVertex>();

    final Set<ORID> leftVisited  = new HashSet<ORID>();
    final Set<ORID> rightVisited = new HashSet<ORID>();

    final Map<ORID, ORID> previouses = new HashMap<ORID, ORID>();
    final Map<ORID, ORID> nexts      = new HashMap<ORID, ORID>();

    OrientVertex current;
    OrientVertex currentRight;
    public Integer maxDepth;
  }

  public List<ORID> execute(Object iThis, final OIdentifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams,
      final OCommandContext iContext) {

    return OGraphCommandExecutorSQLFactory.runWithAnyGraph(new OGraphCommandExecutorSQLFactory.GraphCallBack<List<ORID>>() {
      @Override
      public List<ORID> call(final OrientBaseGraph graph) {
        final ORecord record = iCurrentRecord != null ? iCurrentRecord.getRecord() : null;

        final OShortestPathContext ctx = new OShortestPathContext();

        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);
        }
        ctx.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);
        }
        ctx.destinationVertex = graph.getVertex(OSQLHelper.getValue(dest, record, iContext));

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

        if (iParams.length > 2 && iParams[2] != null) {
          ctx.directionLeft = Direction.valueOf(iParams[2].toString().toUpperCase(Locale.ENGLISH));
        }
        if (ctx.directionLeft == Direction.OUT) {
          ctx.directionRight = Direction.IN;
        } else if (ctx.directionLeft == Direction.IN) {
          ctx.directionRight = Direction.OUT;
        }

        ctx.edgeType = null;
        if (iParams.length > 3) {
          ctx.edgeType = iParams[3] == null ? null : "" + iParams[3];
        }
        ctx.edgeTypeParam = new String[] { ctx.edgeType };

        if (iParams.length > 4) {
          bindAdditionalParams(iParams[4], ctx);
        }

        ctx.queueLeft.add(ctx.sourceVertex);
        ctx.leftVisited.add(ctx.sourceVertex.getIdentity());
<commit_msg>Add support for multiple labels in shortestPath() function<commit_after>/*
 *
 *  *  Copyright 2010-2016 OrientDB LTD (http://orientdb.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://orientdb.com
 *
 */
package com.orientechnologies.orient.graph.sql.functions;

import com.orientechnologies.common.collection.OMultiValue;
import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.command.OCommandExecutorAbstract;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.exception.OCommandExecutionException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.impl.ODocument;
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 java.util.*;

/**
 * Shortest path algorithm to find the shortest path from one node to another node in a directed graph.
 *
 * @author <NAME> (l.garulli--(at)--orientdb.com)
 * @deprecated see {@link com.orientechnologies.orient.core.sql.functions.graph.OSQLFunctionShortestPath} instead
 *
 */
@Deprecated
public class OSQLFunctionShortestPath extends OSQLFunctionMathAbstract {
  public static final String NAME            = "shortestPath";
  public static final String PARAM_MAX_DEPTH = "maxDepth";

  protected static final float DISTANCE = 1f;

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

  private class OShortestPathContext {
    OrientVertex sourceVertex;
    OrientVertex destinationVertex;
    Direction directionLeft  = Direction.BOTH;
    Direction directionRight = Direction.BOTH;

    String   edgeType;
    String[] edgeTypeParam;

    ArrayDeque<OrientVertex> queueLeft  = new ArrayDeque<OrientVertex>();
    ArrayDeque<OrientVertex> queueRight = new ArrayDeque<OrientVertex>();

    final Set<ORID> leftVisited  = new HashSet<ORID>();
    final Set<ORID> rightVisited = new HashSet<ORID>();

    final Map<ORID, ORID> previouses = new HashMap<ORID, ORID>();
    final Map<ORID, ORID> nexts      = new HashMap<ORID, ORID>();

    OrientVertex current;
    OrientVertex currentRight;
    public Integer maxDepth;
  }

  public List<ORID> execute(Object iThis, final OIdentifiable iCurrentRecord, final Object iCurrentResult, final Object[] iParams,
      final OCommandContext iContext) {

    return OGraphCommandExecutorSQLFactory.runWithAnyGraph(new OGraphCommandExecutorSQLFactory.GraphCallBack<List<ORID>>() {
      @Override
      public List<ORID> call(final OrientBaseGraph graph) {
        final ORecord record = iCurrentRecord != null ? iCurrentRecord.getRecord() : null;

        final OShortestPathContext ctx = new OShortestPathContext();

        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);
        }
        ctx.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);
        }
        ctx.destinationVertex = graph.getVertex(OSQLHelper.getValue(dest, record, iContext));

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

        if (iParams.length > 2 && iParams[2] != null) {
          ctx.directionLeft = Direction.valueOf(iParams[2].toString().toUpperCase(Locale.ENGLISH));
        }
        if (ctx.directionLeft == Direction.OUT) {
          ctx.directionRight = Direction.IN;
        } else if (ctx.directionLeft == Direction.IN) {
          ctx.directionRight = Direction.OUT;
        }

        ctx.edgeType = null;
        if (iParams.length > 3) {
          ctx.edgeType = iParams[3] == null ? null : "" + iParams[3];
        }
        if (iParams != null && iParams.length > 2 && iParams[3] instanceof Collection) {
          ctx.edgeTypeParam = new String[((Collection) iParams[3]).size()];
          Collection coll = (Collection) iParams[3];
          int i = 0;
          for (Object o : coll) {
            ctx.edgeTypeParam[i++] = "" + o;
          }
        } else {
          ctx.edgeTypeParam = new String[] { ctx.edgeType };
        }

        if (iParams.length > 4) {
          bindAdditionalParams(iParams[4], ctx);
        }

        ctx.queueLeft.add(ctx.sourceVertex);
        ctx.leftVisited.add(ctx.sourceVertex.getIdentity());

{'fraction_non_alphanumeric': 0.10328176696771886, 'fraction_numerical': 0.00545470803898775, 'mean_word_length': 3.4879614767255216, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7255281', 'n_tokens_mistral': 3321, 'n_tokens_neox': 3231, 'n_words': 755}