'Checks the database to see if we should backfill before paginating,
and if so do.'

@defer.inlineCallbacks
def maybe_backfill(self, room_id, current_depth):

    extremities = (yield self.store.get_oldest_events_with_depth_in_room(room_id))
    if (not extremities):
        logger.debug('Not    backfilling    as    no    extremeties    found.')
        return
    sorted_extremeties_tuple = sorted(extremities.items(), key=(lambda e: (- int(e[1]))))
    max_depth = sorted_extremeties_tuple[0][1]
    extremities = dict(sorted_extremeties_tuple[:5])
    if (current_depth > max_depth):
        logger.debug("Not    backfilling    as    we    don't    need    to.    %d    <    %d", max_depth, current_depth)
        return
    curr_state = (yield self.state_handler.get_current_state(room_id))
    def get_domains_from_state(state):
        joined_users = [(state_key, int(event.depth)) for ((e_type, state_key), event) in state.items() if ((e_type == EventTypes.Member) and (event.membership == Membership.JOIN))]
        joined_domains = {}
        for (u, d) in joined_users:
            try:
                dom = get_domain_from_id(u)
                old_d = joined_domains.get(dom)
                if old_d:
                    joined_domains[dom] = min(d, old_d)
                else:
                    joined_domains[dom] = d
            except:
                pass
        return sorted(joined_domains.items(), key=(lambda d: d[1]))
    curr_domains = get_domains_from_state(curr_state)
    likely_domains = [domain for (domain, depth) in curr_domains if (domain != self.server_name)]
    @defer.inlineCallbacks
    def try_backfill(domains):
        for dom in domains:
            try:
                (yield self.backfill(dom, room_id, limit=100, extremities=[e for e in extremities.keys()]))
                defer.returnValue(True)
            except SynapseError as e:
                logger.info('Failed    to    backfill    from    %s    because    %s', dom, e)
                continue
            except CodeMessageException as e:
                if (400 <= e.code < 500):
                    raise
                logger.info('Failed    to    backfill    from    %s    because    %s', dom, e)
                continue
            except NotRetryingDestination as e:
                logger.info(e.message)
                continue
            except Exception as e:
                logger.exception('Failed    to    backfill    from    %s    because    %s', dom, e)
                continue
        defer.returnValue(False)
    success = (yield try_backfill(likely_domains))
    if success:
        defer.returnValue(True)
    tried_domains = set(likely_domains)
    tried_domains.add(self.server_name)
    event_ids = list(extremities.keys())
    logger.debug('calling    resolve_state_groups    in    _maybe_backfill')
    states = (yield preserve_context_over_deferred(defer.gatherResults([preserve_fn(self.state_handler.resolve_state_groups)(room_id, [e]) for e in event_ids])))
    states = dict(zip(event_ids, [s.state for s in states]))
    state_map = (yield self.store.get_events([e_id for ids in states.values() for e_id in ids], get_prev_content=False))
    states = {key: {k: state_map[e_id] for (k, e_id) in state_dict.items() if (e_id in state_map)} for (key, state_dict) in states.items()}
    for (e_id, _) in sorted_extremeties_tuple:
        likely_domains = get_domains_from_state(states[e_id])
        success = (yield try_backfill([dom for dom in likely_domains if (dom not in tried_domains)]))
        if success:
            defer.returnValue(True)
        tried_domains.update(likely_domains)
    defer.returnValue(False)
