def run_groomer(self):
    self.db_access = appscale_datastore_batch.DatastoreFactory.getDatastore(
      self.table_name)
    self.ds_access = datastore_server.DatastoreDistributed(
      datastore_batch=self.db_access, zookeeper=self.zoo_keeper)

    logging.info("Groomer started")
    start = time.time()

    self.reset_statistics()
    self.composite_index_cache = {}

    tasks = [
      {
        'id': self.CLEAN_ENTITIES_TASK,
        'description': 'clean up entities',
        'function': self.clean_up_entities,
        'args': []
      },
      {
        'id': self.CLEAN_ASC_INDICES_TASK,
        'description': 'clean up ascending indices',
        'function': self.clean_up_indexes,
        'args': [datastore_pb.Query_Order.ASCENDING]
      },
      {
        'id': self.CLEAN_DSC_INDICES_TASK,
        'description': 'clean up descending indices',
        'function': self.clean_up_indexes,
        'args': [datastore_pb.Query_Order.DESCENDING]
      },
      {
        'id': self.CLEAN_KIND_INDICES_TASK,
        'description': 'clean up kind indices',
        'function': self.clean_up_kind_indices,
        'args': []
      },
      {
        'id': self.CLEAN_LOGS_TASK,
        'description': 'clean up old logs',
        'function': self.remove_old_logs,
        'args': [self.LOG_STORAGE_TIMEOUT]
      },
      {
        'id': self.CLEAN_TASKS_TASK,
        'description': 'clean up old tasks',
        'function': self.remove_old_tasks_entities,
        'args': []
      },
      {
        'id': self.CLEAN_DASHBOARD_TASK,
        'description': 'clean up old dashboard items',
        'function': self.remove_old_dashboard_data,
        'args': []
      }
    ]

    groomer_state = self.zoo_keeper.get_node(self.GROOMER_STATE_PATH)
    logging.info('groomer_state: {}'.format(groomer_state))
    if groomer_state:
      self.update_groomer_state(
        groomer_state[0].split(self.GROOMER_STATE_DELIMITER))

    for task_number in range(len(tasks)):
      task = tasks[task_number]
      if (len(self.groomer_state) > 0 and self.groomer_state[0] != '' and
        self.groomer_state[0] != task['id']):
        continue
      logging.info('Starting to {}'.format(task['description']))
      try:
        task['function'](*task['args'])
        if task_number != len(tasks) - 1:
          next_task = tasks[task_number + 1]
          self.update_groomer_state([next_task['id']])
      except Exception as exception:
        logging.error('Exception encountered while trying to {}:'.
          format(task['description']))
        logging.exception(exception)

    self.update_groomer_state([])

    timestamp = datetime.datetime.utcnow()

    if not self.update_statistics(timestamp):
      logging.error("There was an error updating the statistics")

    if not self.update_namespaces(timestamp):
      logging.error("There was an error updating the namespaces")

    del self.db_access
    del self.ds_access

    time_taken = time.time() - start
    logging.info("Groomer cleaned {0} journal entries".format(
      self.journal_entries_cleaned))
    logging.info("Groomer checked {0} index entries".format(
      self.index_entries_checked))
    logging.info("Groomer cleaned {0} index entries".format(
      self.index_entries_cleaned))
    if self.index_entries_delete_failures > 0:
      logging.info("Groomer failed to remove {0} index entries".format(
        self.index_entries_delete_failures))
    logging.info("Groomer took {0} seconds".format(str(time_taken)))
Check whether pdu is a DLR or not, will return None if not
dataset/ETHPy150Open AppScale/appscale/AppDB/groomer.py/DatastoreGroomer.run_groomer--crossover with--dataset/ETHPy150Open jookies/jasmin/jasmin/protocols/smpp/operations.py/SMPPOperationFactory.isDeliveryReceipt