### Question:
Louvain extends Algorithm<Louvain, Louvain> { @Override public Louvain compute() { getProgressLogger().logMessage(":: Start"); Graph workingGraph = rootGraph; NodeProperties nextSeedingValues = seedingValues; long oldNodeCount = rootGraph.nodeCount(); for (ranLevels = 0; ranLevels < config.maxLevels(); ranLevels++) { getProgressLogger().logMessage(formatWithLocale("Level %d :: Start", ranLevels + 1)); assertRunning(); ModularityOptimization modularityOptimization = runModularityOptimization( workingGraph, nextSeedingValues ); modularityOptimization.release(); modularities[ranLevels] = modularityOptimization.getModularity(); dendrograms[ranLevels] = HugeLongArray.newArray(rootGraph.nodeCount(), tracker); long maxCommunityId = buildDendrogram(workingGraph, ranLevels, modularityOptimization); workingGraph = summarizeGraph(workingGraph, modularityOptimization, maxCommunityId); nextSeedingValues = new OriginalIdNodeProperties(workingGraph); getProgressLogger().logMessage(formatWithLocale("Level %d :: Finished", ranLevels + 1)); if (workingGraph.nodeCount() == oldNodeCount || workingGraph.nodeCount() == 1 || hasConverged() ) { resizeResultArrays(); getProgressLogger().logMessage(":: Finished"); break; } oldNodeCount = workingGraph.nodeCount(); } return this; } Louvain(
        Graph graph,
        LouvainBaseConfig config,
        ExecutorService executorService,
        ProgressLogger progressLogger,
        AllocationTracker tracker
    ); @Override Louvain compute(); LouvainBaseConfig config(); HugeLongArray[] dendrograms(); HugeLongArray finalDendrogram(); long getCommunity(long nodeId); long[] getCommunities(long nodeId); int levels(); double[] modularities(); @Override void release(); @Override Louvain me();  }### Answer:
@Test void testCanBeInterruptedByTxCancellation() { HugeGraph graph = RandomGraphGenerator.builder() .nodeCount(100_000) .averageDegree(10) .relationshipDistribution(RelationshipDistribution.UNIFORM) .allocationTracker(AllocationTracker.empty()) .build() .generate(); assertTerminates((terminationFlag) -> new Louvain( graph, defaultConfigBuilder().concurrency(2).build(), Pools.DEFAULT, ProgressLogger.NULL_LOGGER, AllocationTracker.empty() ) .withTerminationFlag(terminationFlag) .compute(), 500, 1000 ); }
@Test void testLogging() { var graph = graphStore.getGraph( NodeLabel.listOf("Node"), RelationshipType.listOf("TYPE_OUT", "TYPE_IN"), Optional.empty() ); var config = defaultConfigBuilder().build(); var testLogger = new TestProgressLogger(0, "Louvain", config.concurrency()); var louvain = new Louvain( graph, config, Pools.DEFAULT, testLogger, AllocationTracker.empty() ); louvain.compute(); assertTrue(testLogger.containsMessage(INFO, ":: Start")); assertTrue(testLogger.containsMessage(INFO, "Level 1 :: Finished")); assertTrue(testLogger.containsMessage(INFO, ":: Finished")); }