public List execute()

in core/src/main/java/com/jetbrains/youtrackdb/internal/core/sql/functions/graph/SQLFunctionShortestPath.java [77:231]


  public List<RID> execute(
      Object iThis,
      final Result iCurrentRecord,
      final Object iCurrentResult,
      final Object[] iParams,
      final CommandContext iContext) {

    var session = iContext.getDatabaseSession();
    var record =
        iCurrentRecord != null && iCurrentRecord.isEntity() ? iCurrentRecord.asEntity() : null;

    final var ctx = new ShortestPathContext();

    var source = iParams[0];
    source = getSingleItem(source);
    if (source == null) {
      throw new IllegalArgumentException("Only one sourceVertex is allowed");
    }
    source = SQLHelper.getValue(source, record, iContext);
    if (source instanceof Identifiable) {
      var transaction = session.getActiveTransaction();
      Entity elem = transaction.load(((Identifiable) source));
      if (!elem.isVertex()) {
        throw new IllegalArgumentException("The sourceVertex must be a vertex record");
      }
      ctx.sourceVertex = elem.asVertex();
    } else {
      throw new IllegalArgumentException("The sourceVertex must be a vertex record");
    }

    var dest = iParams[1];
    dest = getSingleItem(dest);
    if (dest == null) {
      throw new IllegalArgumentException("Only one destinationVertex is allowed");
    }
    dest = SQLHelper.getValue(dest, record, iContext);
    if (dest instanceof Identifiable) {
      var transaction = session.getActiveTransaction();
      Entity elem = transaction.load(((Identifiable) dest));
      if (elem == null || !elem.isVertex()) {
        throw new IllegalArgumentException("The destinationVertex must be a vertex record");
      }
      ctx.destinationVertex = elem.asVertex();
    } else {
      throw new IllegalArgumentException("The destinationVertex must be a vertex record");
    }

    if (ctx.sourceVertex.equals(ctx.destinationVertex)) {
      final List<RID> result = new ArrayList<RID>(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) {

      var param = iParams[3];
      if (param instanceof Collection
          && ((Collection) param).stream().allMatch(x -> x instanceof String)) {
        ctx.edgeType = ((Collection<String>) param).stream().collect(Collectors.joining(","));
        ctx.edgeTypeParam = (String[]) ((Collection) param).toArray(new String[0]);
      } else {
        ctx.edgeType = param == null ? null : "" + param;
        ctx.edgeTypeParam = new String[]{ctx.edgeType};
      }
    } else {
      ctx.edgeTypeParam = new String[]{null};
    }

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

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

    ctx.queueRight.add(ctx.destinationVertex);
    ctx.rightVisited.add(ctx.destinationVertex.getIdentity());

    var depth = 1;
    while (true) {
      if (ctx.maxDepth != null && ctx.maxDepth <= depth) {
        break;
      }
      if (ctx.queueLeft.isEmpty() || ctx.queueRight.isEmpty()) {
        break;
      }

      if (Thread.interrupted()) {
        throw new CommandExecutionException(session,
            "The shortestPath() function has been interrupted");
      }

      if (!CommandExecutorAbstract.checkInterruption(iContext)) {
        break;
      }

      List<RID> neighborIdentity;

      if (ctx.queueLeft.size() <= ctx.queueRight.size()) {
        // START EVALUATING FROM LEFT
        neighborIdentity = walkLeft(ctx);
        if (neighborIdentity != null) {
          return neighborIdentity;
        }
        depth++;
        if (ctx.maxDepth != null && ctx.maxDepth <= depth) {
          break;
        }

        if (ctx.queueLeft.isEmpty()) {
          break;
        }

        neighborIdentity = walkRight(ctx);
        if (neighborIdentity != null) {
          return neighborIdentity;
        }

      } else {

        // START EVALUATING FROM RIGHT
        neighborIdentity = walkRight(ctx);
        if (neighborIdentity != null) {
          return neighborIdentity;
        }

        depth++;
        if (ctx.maxDepth != null && ctx.maxDepth <= depth) {
          break;
        }

        if (ctx.queueRight.isEmpty()) {
          break;
        }

        neighborIdentity = walkLeft(ctx);
        if (neighborIdentity != null) {
          return neighborIdentity;
        }
      }

      depth++;
    }
    return new ArrayList<RID>();
  }