'Persist events to db
Args:
events_and_contexts (list[(EventBase, EventContext)]):
backfilled (bool):
delete_existing (bool):
Returns:
Deferred: resolves when the events have been persisted'

@_retry_on_integrity_error
@defer.inlineCallbacks
def _persist_events(self, events_and_contexts, backfilled=False, delete_existing=False):

    if (not events_and_contexts):
        return
    if backfilled:
        stream_ordering_manager = self._backfill_id_gen.get_next_mult(len(events_and_contexts))
    else:
        stream_ordering_manager = self._stream_id_gen.get_next_mult(len(events_and_contexts))
    with stream_ordering_manager as stream_orderings:
        for ((event, context), stream) in zip(events_and_contexts, stream_orderings):
            event.internal_metadata.stream_ordering = stream
        chunks = [events_and_contexts[x:(x + 100)] for x in xrange(0, len(events_and_contexts), 100)]
        for chunk in chunks:
            new_forward_extremeties = {}
            current_state_for_room = {}
            if (not backfilled):
                with Measure(self._clock, '_calculate_state_and_extrem'):
                    events_by_room = {}
                    for (event, context) in chunk:
                        events_by_room.setdefault(event.room_id, []).append((event, context))
                    for (room_id, ev_ctx_rm) in events_by_room.iteritems():
                        latest_event_ids = (yield self.get_latest_event_ids_in_room(room_id))
                        new_latest_event_ids = (yield self._calculate_new_extremeties(room_id, ev_ctx_rm, latest_event_ids))
                        if (new_latest_event_ids == set(latest_event_ids)):
                            continue
                        new_forward_extremeties[room_id] = new_latest_event_ids
                        len_1 = ((len(latest_event_ids) == 1) and (len(new_latest_event_ids) == 1))
                        if len_1:
                            all_single_prev_not_state = all((((len(event.prev_events) == 1) and (not event.is_state())) for (event, ctx) in ev_ctx_rm))
                            if all_single_prev_not_state:
                                continue
                        state = (yield self._calculate_state_delta(room_id, ev_ctx_rm, new_latest_event_ids))
                        if state:
                            current_state_for_room[room_id] = state
            (yield self.runInteraction('persist_events', self._persist_events_txn, events_and_contexts=chunk, backfilled=backfilled, delete_existing=delete_existing, current_state_for_room=current_state_for_room, new_forward_extremeties=new_forward_extremeties))
            persist_event_counter.inc_by(len(chunk))
            for (event, context) in chunk:
                if context.app_service:
                    origin_type = 'local'
                    origin_entity = context.app_service.id
                elif self.hs.is_mine_id(event.sender):
                    origin_type = 'local'
                    origin_entity = '*client*'
                else:
                    origin_type = 'remote'
                    origin_entity = get_domain_from_id(event.sender)
                event_counter.inc(event.type, origin_type, origin_entity)
            for (room_id, (_, _, new_state)) in current_state_for_room.iteritems():
                self.get_current_state_ids.prefill((room_id,), new_state)
            for (room_id, latest_event_ids) in new_forward_extremeties.iteritems():
                self.get_latest_event_ids_in_room.prefill((room_id,), list(latest_event_ids))
