RowGarbageCollector extends AbstractScheduledService { @VisibleForTesting @Override public void runOneIteration() { LOG.info("Scanning database tables for unreferenced rows."); final AtomicLong deletedCount = new AtomicLong(); for (Class<? extends GarbageCollectedTableMapper> tableClass : TABLES) { storage.write((NoResult.Quiet) storeProvider -> { try (SqlSession session = sessionFactory.openSession(true)) { GarbageCollectedTableMapper table = session.getMapper(tableClass); for (long rowId : table.selectAllRowIds()) { try { table.deleteRow(rowId); deletedCount.incrementAndGet(); } catch (PersistenceException e) { } } } }); } LOG.info("Deleted " + deletedCount.get() + " unreferenced rows."); } @Inject  RowGarbageCollector(
      Scheduler iterationScheduler,
      SqlSessionFactory sessionFactory,
      Storage storage); @VisibleForTesting @Override void runOneIteration();  }
@Test public void testNoop() { rowGc.runOneIteration(); }
@Test public void testGarbageCollection() { rowGc.runOneIteration(); assertEquals(ImmutableList.of(), jobKeyMapper.selectAll()); assertEquals(ImmutableList.of(), taskConfigMapper.selectConfigsByJob(JOB_A)); assertEquals(ImmutableList.of(), taskConfigMapper.selectConfigsByJob(JOB_B)); jobKeyMapper.merge(JOB_A); rowGc.runOneIteration(); assertEquals(ImmutableList.of(), jobKeyMapper.selectAll()); assertEquals(ImmutableList.of(), taskConfigMapper.selectConfigsByJob(JOB_A)); assertEquals(ImmutableList.of(), taskConfigMapper.selectConfigsByJob(JOB_B)); jobKeyMapper.merge(JOB_A); taskConfigMapper.insert(CONFIG_A, new InsertResult()); InsertResult a2Insert = new InsertResult(); taskConfigMapper.insert(TASK_A2.getAssignedTask().getTask(), a2Insert); taskMapper.insertScheduledTask(TASK_A2, a2Insert.getId(), new InsertResult()); jobKeyMapper.merge(JOB_B); taskConfigMapper.insert(CONFIG_B, new InsertResult()); rowGc.runOneIteration(); assertEquals(ImmutableList.of(JOB_A.newBuilder()), jobKeyMapper.selectAll()); assertEquals( TASK_A2.getAssignedTask().getTask().getRamMb(), Iterables.getOnlyElement(taskConfigMapper.selectConfigsByJob(JOB_A)).toImmutable() .getRamMb()); assertEquals(ImmutableList.of(), taskConfigMapper.selectConfigsByJob(JOB_B)); }