async def METHOD_NAME(self, state_groups: Set[int]) -> Set[int]:
    """Used when purging history to figure out which state groups can be
    deleted.
    Args:
        state_groups: Set of state groups referenced by events
            that are going to be deleted.
    Returns:
        The set of state groups that can be deleted.
    """
    # Set of events that we have found to be referenced by events
    referenced_groups = set()
    # Set of state groups we've already seen
    state_groups_seen = set(state_groups)
    # Set of state groups to handle next.
    next_to_search = set(state_groups)
    while next_to_search:
        # We bound size of groups we're looking up at once, to stop the
        # SQL query getting too big
        if len(next_to_search) < 100:
            current_search = next_to_search
            next_to_search = set()
        else:
            current_search = set(itertools.islice(next_to_search, 100))
            next_to_search -= current_search
        referenced = await self.stores.main.get_referenced_state_groups(
            current_search
        )
        referenced_groups |= referenced
        # We don't continue iterating up the state group graphs for state
        # groups that are referenced.
        current_search -= referenced
        edges = await self.stores.state.get_previous_state_groups(current_search)
        prevs = set(edges.values())
        # We don't bother re-handling groups we've already seen
        prevs -= state_groups_seen
        next_to_search |= prevs
        state_groups_seen |= prevs
    to_delete = state_groups_seen - referenced_groups
    return to_delete