def bulk_get_subscriber_user_ids(stream_dicts: Iterable[Mapping[(str, Any)]], user_profile: UserProfile, sub_dict: Mapping[(int, bool)], stream_recipient: StreamRecipientMap) -> Dict[(int, List[int])]:
    'sub_dict maps stream_id => whether the user is subscribed to that stream.'
    target_stream_dicts = []
    for stream_dict in stream_dicts:
        stream_recipient.populate_with(stream_id=stream_dict['id'], recipient_id=stream_dict['recipient_id'])
        try:
            validate_user_access_to_subscribers_helper(user_profile, stream_dict, (lambda user_profile: sub_dict[stream_dict['id']]))
        except JsonableError:
            continue
        target_stream_dicts.append(stream_dict)
    stream_ids = [stream['id'] for stream in target_stream_dicts]
    recipient_ids = sorted([stream_recipient.recipient_id_for(stream_id) for stream_id in stream_ids])
    result: Dict[(int, List[int])] = {stream['id']: [] for stream in stream_dicts}
    if (not recipient_ids):
        return result
    '\n    The raw SQL below leads to more than a 2x speedup when tested with\n    20k+ total subscribers.  (For large realms with lots of default\n    streams, this function deals with LOTS of data, so it is important\n    to optimize.)\n    '
    query = SQL('\n        SELECT\n            zerver_subscription.recipient_id,\n            zerver_subscription.user_profile_id\n        FROM\n            zerver_subscription\n        INNER JOIN zerver_userprofile ON\n            zerver_userprofile.id = zerver_subscription.user_profile_id\n        WHERE\n            zerver_subscription.recipient_id in %(recipient_ids)s AND\n            zerver_subscription.active AND\n            zerver_userprofile.is_active\n        ORDER BY\n            zerver_subscription.recipient_id,\n            zerver_subscription.user_profile_id\n        ')
    cursor = connection.cursor()
    cursor.execute(query, {'recipient_ids': tuple(recipient_ids)})
    rows = cursor.fetchall()
    cursor.close()
    recip_to_stream_id = stream_recipient.recipient_to_stream_id_dict()
    '\n    Using groupby/itemgetter here is important for performance, at scale.\n    It makes it so that all interpreter overhead is just O(N) in nature.\n    '
    for (recip_id, recip_rows) in itertools.groupby(rows, itemgetter(0)):
        user_profile_ids = [r[1] for r in recip_rows]
        stream_id = recip_to_stream_id[recip_id]
        result[stream_id] = list(user_profile_ids)
    return result
sub_dict maps stream_id => whether the user is subscribed to that stream.
def bulk_get_subscriber_user_ids(stream_dicts: Iterable[Mapping[(str, Any)]], user_profile: UserProfile, sub_dict: Mapping[(int, bool)], stream_recipient: StreamRecipientMap) -> Dict[(int, List[int])]:
    
    target_stream_dicts = []
    for stream_dict in stream_dicts:
        stream_recipient.populate_with(stream_id=stream_dict['id'], recipient_id=stream_dict['recipient_id'])
        try:
            validate_user_access_to_subscribers_helper(user_profile, stream_dict, (lambda user_profile: sub_dict[stream_dict['id']]))
        except JsonableError:
            continue
        target_stream_dicts.append(stream_dict)
    stream_ids = [stream['id'] for stream in target_stream_dicts]
    recipient_ids = sorted([stream_recipient.recipient_id_for(stream_id) for stream_id in stream_ids])
    result: Dict[(int, List[int])] = {stream['id']: [] for stream in stream_dicts}
    if (not recipient_ids):
        return result
    '\n    The raw SQL below leads to more than a 2x speedup when tested with\n    20k+ total subscribers.  (For large realms with lots of default\n    streams, this function deals with LOTS of data, so it is important\n    to optimize.)\n    '
    query = SQL('\n        SELECT\n            zerver_subscription.recipient_id,\n            zerver_subscription.user_profile_id\n        FROM\n            zerver_subscription\n        INNER JOIN zerver_userprofile ON\n            zerver_userprofile.id = zerver_subscription.user_profile_id\n        WHERE\n            zerver_subscription.recipient_id in %(recipient_ids)s AND\n            zerver_subscription.active AND\n            zerver_userprofile.is_active\n        ORDER BY\n            zerver_subscription.recipient_id,\n            zerver_subscription.user_profile_id\n        ')
    cursor = connection.cursor()
    cursor.execute(query, {'recipient_ids': tuple(recipient_ids)})
    rows = cursor.fetchall()
    cursor.close()
    recip_to_stream_id = stream_recipient.recipient_to_stream_id_dict()
    '\n    Using groupby/itemgetter here is important for performance, at scale.\n    It makes it so that all interpreter overhead is just O(N) in nature.\n    '
    for (recip_id, recip_rows) in itertools.groupby(rows, itemgetter(0)):
        user_profile_ids = [r[1] for r in recip_rows]
        stream_id = recip_to_stream_id[recip_id]
        result[stream_id] = list(user_profile_ids)
    return result