def METHOD_NAME(
    self,
    columns: List[str],
    num_parallel_calls=tf.data.AUTOTUNE,
    row_set: bigtable_row_set.RowSet = None,
    filter: filters.BigtableFilter = None,
    output_type=tf.string,
):
    """Retrieves values from Google Bigtable in parallel. The ammount of work
    is split between workers based on SampleRowKeys. Keep in mind that when
    reading in parallel, rows are not read in any particular order.
    Args:
        columns (List[str]): the list of columns to read from; the order on
            this list will determine the order in the output tensors
        num_parallel_calls: number of workers assigned to reading the data.
        row_set (RowSet): set of rows to read.
    Returns:
        A `tf.data.Dataset` returning the cell contents.
    """
    # We have to make sure that all the default arguments are initialized
    # on each invocation. For more info see read_rows method.
    if row_set is None:
        row_set = bigtable_row_set.from_rows_or_ranges(
            bigtable_row_range.infinite()
        )
    if filter is None:
        filter = filters.latest()
    samples = core_ops.bigtable_split_row_set_evenly(
        self._client_resource, row_set._impl, self._table_id, num_parallel_calls
    )
    def map_func(idx):
        return self.read_rows(
            columns, bigtable_row_set.RowSet(samples[idx]), filter, output_type
        )
    # We interleave a dataset of sample's indexes instead of a dataset of
    # samples, because Dataset.from_tensor_slices attempts to copy the
    # resource tensors using DeepCopy from tensor_util.cc which is not
    # possible for tensors of type DT_RESOURCE.
    return tf.data.Dataset.range(samples.shape[0]).interleave(
        map_func=map_func,
        cycle_length=num_parallel_calls,
        block_length=1,
        num_parallel_calls=num_parallel_calls,
        deterministic=False,
    )