GenerateKeyedColumnsFromInput(const OpInputList& indices_list_in,
                              const OpInputList& values_list_in,
                              const OpInputList& shapes_list_in,
                              const OpInputList& dense_list_in,
                              std::vector<int64> keys) {
  std::vector<std::unique_ptr<ColumnInterface<InternalType>>> columns;
  const int64 batch_size = CalculateBatchSize(shapes_list_in, dense_list_in);
  const int64 number_of_columns = shapes_list_in.size();

  std::vector<std::vector<int64>> feature_counts(number_of_columns,
                                                 std::vector<int64>());
  std::vector<std::vector<int64>> feature_start_indices(number_of_columns,
                                                        std::vector<int64>());

  ExtractFeatureData(indices_list_in, batch_size, &feature_counts,
                     &feature_start_indices);

  columns.reserve(values_list_in.size());
  for (int i = 0; i < values_list_in.size(); ++i) {
    columns.emplace_back(new KeyedSparseTensorColumn<InternalType>(
        values_list_in[i], std::move(feature_counts[i]),
        std::move(feature_start_indices[i]), keys));
  }
  for (int i = 0; i < dense_list_in.size(); ++i) {
    columns.emplace_back(
        new KeyedDenseTensorColumn<InternalType>(dense_list_in[i], keys));
  }

  return columns;
}
GenerateKeyedColumnsFromInput(const OpInputList& indices_list_in,
                              const OpInputList& values_list_in,
                              const OpInputList& shapes_list_in,
                              const OpInputList& dense_list_in,
                              std::vector<int64> keys) {
  std::vector<std::unique_ptr<ColumnInterface<InternalType>>> columns;
  const int64 batch_size = CalculateBatchSize(shapes_list_in, dense_list_in);
  const int64 number_of_columns = shapes_list_in.size();

  std::vector<std::vector<int64>> feature_counts(number_of_columns,
                                                 std::vector<int64>());
  std::vector<std::vector<int64>> feature_start_indices(number_of_columns,
                                                        std::vector<int64>());

  ExtractFeatureData(indices_list_in, batch_size, &feature_counts,
                     &feature_start_indices);

  columns.reserve(values_list_in.size());
  for (int i = 0; i < values_list_in.size(); ++i) {
    columns.emplace_back(new KeyedSparseTensorColumn<InternalType>(
        values_list_in[i], std::move(feature_counts[i]),
        std::move(feature_start_indices[i]), keys));
  }
  for (int i = 0; i < dense_list_in.size(); ++i) {
    columns.emplace_back(
        new KeyedDenseTensorColumn<InternalType>(dense_list_in[i], keys));
  }

  return columns;
}