code: def _split_single_block(
      block_id: int,
      block: Block,
      meta: BlockMetadata,
      split_indices: List[int],
  ) -> Tuple[Union[Tuple[int, List[BlockMetadata]], Block], ...]:
      """Split the provided block at the given indices.
  
      Args:
          block_id: the id of this block in the block list.
          block: block to be split.
          meta: metadata of the block, we expect meta.num is valid.
          split_indices: the indices where the block should be split.
      Returns:
          returns block_id, split blocks metadata, and a list of blocks
          in the following form. We return blocks in this way
          so that the owner of blocks could be the caller(driver)
          instead of worker itself.
          Tuple(block_id, split_blocks_meta), block0, block1 ...
      """
      split_meta = []
      split_blocks = []
      block_accessor = BlockAccessor.for_block(block)
      prev_index = 0
      # append one more entry at the last so we don't
      # need handle empty edge case.
      split_indices.append(meta.num_rows)
      for index in split_indices:
          logger.debug(f"slicing block {prev_index}:{index}")
          stats = BlockExecStats.builder()
          split_block = block_accessor.slice(prev_index, index)
          accessor = BlockAccessor.for_block(split_block)
          _meta = BlockMetadata(
              num_rows=accessor.num_rows(),
              size_bytes=accessor.size_bytes(),
              schema=meta.schema,
              input_files=meta.input_files,
              exec_stats=stats.build(),
          )
          split_meta.append(_meta)
          split_blocks.append(split_block)
          prev_index = index
      results = [(block_id, split_meta)]
      results.extend(split_blocks)
      return tuple(results)
  
file_path: ray/python/ray/data/_internal/split.py
imports: import itertools
  import logging
  from typing import Iterable, List, Tuple, Union
  import ray
  from ray.data._internal.block_list import BlockList
  from ray.data._internal.memory_tracing import trace_deallocation
  from ray.data._internal.remote_fn import cached_remote_fn
  from ray.data.block import Block, BlockAccessor, BlockExecStats, BlockMetadata, BlockPartition
  from ray.types import ObjectRef
label_desc: Use image node_id 4 for calling a global function with example usage: _split_single_block(block_id, block, meta, split_indices) and returns: tuple