void applyTypedWithInstance()

in velox/functions/prestosql/ArrayPosition.cpp [172:284]


void applyTypedWithInstance(
    const SelectivityVector& rows,
    DecodedVector& arrayDecoded,
    const DecodedVector& elementsDecoded,
    const DecodedVector& searchDecoded,
    const DecodedVector& instanceDecoded,
    FlatVector<int64_t>& flatResult) {
  using T = typename TypeTraits<kind>::NativeType;

  auto baseArray = arrayDecoded.base()->as<ArrayVector>();
  auto rawSizes = baseArray->rawSizes();
  auto rawOffsets = baseArray->rawOffsets();
  auto indices = arrayDecoded.indices();

  int startIndex;
  int endIndex;
  int step;

  if (elementsDecoded.isIdentityMapping() && !elementsDecoded.mayHaveNulls() &&
      searchDecoded.isConstantMapping() &&
      instanceDecoded.isConstantMapping()) {
    auto instance = instanceDecoded.valueAt<int64_t>(0);
    VELOX_USER_CHECK_NE(
        instance,
        0,
        "array_position cannot take a 0-valued instance argument.");

    // Fast path for array vector of boolean.
    if constexpr (std::is_same_v<bool, T>) {
      auto rawElements = elementsDecoded.values<uint64_t>();

      auto search = bits::isBitSet(searchDecoded.values<uint64_t>(), 0);

      rows.applyToSelected([&](auto row) {
        auto offset = rawOffsets[indices[row]];
        getLoopBoundary(
            rawSizes, indices, row, instance, startIndex, endIndex, step);

        int i;
        for (i = startIndex; i != endIndex; i += step) {
          if (bits::isBitSet(rawElements, offset + i) == search) {
            --instance;
            if (instance == 0) {
              flatResult.set(row, i + 1);
              break;
            }
          }
        }
        if (i == endIndex) {
          flatResult.set(row, 0);
        }
      });
      return;
    }

    // Fast path for array vector of types other than boolean.
    auto rawElements = elementsDecoded.values<T>();

    auto search = searchDecoded.valueAt<T>(0);

    rows.applyToSelected([&](auto row) {
      auto offset = rawOffsets[indices[row]];
      getLoopBoundary(
          rawSizes, indices, row, instance, startIndex, endIndex, step);

      int i;
      for (i = startIndex; i != endIndex; i += step) {
        if (rawElements[offset + i] == search) {
          --instance;
          if (instance == 0) {
            flatResult.set(row, i + 1);
            break;
          }
        }
      }
      if (i == endIndex) {
        flatResult.set(row, 0);
      }
    });
    return;
  }

  // Regular path where no assumption is made about the encodings of
  // searchDecoded and elementsDecoded.
  rows.applyToSelected([&](auto row) {
    auto offset = rawOffsets[indices[row]];
    auto search = searchDecoded.valueAt<T>(row);

    auto instance = instanceDecoded.valueAt<int64_t>(row);
    VELOX_USER_CHECK_NE(
        instance,
        0,
        "array_position cannot take a 0-valued instance argument.");

    getLoopBoundary(
        rawSizes, indices, row, instance, startIndex, endIndex, step);

    int i;
    for (i = startIndex; i != endIndex; i += step) {
      if (!elementsDecoded.isNullAt(offset + i) &&
          elementsDecoded.valueAt<T>(offset + i) == search) {
        --instance;
        if (instance == 0) {
          flatResult.set(row, i + 1);
          break;
        }
      }
    }
    if (i == endIndex) {
      flatResult.set(row, 0);
    }
  });
}