@@ -0,0 +1,2212 @@
+package com.conveyal.r5.util;%0A%0Aimport org.slf4j.Logger;%0A%0A/**%0A * Allows counting iterations and logging inside lambda expressions, including those within parallel streams.%0A * Java does not allow you to modify a primitive in a lambda expression, but you can modify a primitive via a constant%0A * reference to an object containing it. The thinking behind disallowing such modifications is that it prevents%0A * non-threadsafe access, which is odd considering that you can do all sorts of other non threadsafe things and%0A * people are not always using parallel streams.%0A *%0A * To solve all these problems, this class allows you to update a counter in a threadsafe way and log messages when%0A * it passes certain values. An instance that is %22effectively final%22 can still have its increment method called in%0A * a lambda function.%0A */%0Apublic class LambdaCounter %7B%0A%0A    private Logger logger;%0A%0A    private int count = 0;%0A%0A    private int total;%0A%0A    private int logFrequency = 10000;%0A%0A    private String message;%0A%0A    /**%0A     * Create a counter that will log the number of iterations out of a specified total.%0A     * It expects a message string with two %7B%7D placeholders. The first is the count and the second is the total.%0A     */%0A    public LambdaCounter(Logger logger, int total, int logFrequency, String message) %7B%0A        this.logger = logger;%0A        this.total = total;%0A        this.logFrequency = logFrequency;%0A        this.message = message;%0A    %7D%0A%0A    /**%0A     * Create a counter that will log only the number of iterations with no total. It expects a message string with%0A     * a single %7B%7D placeholder.%0A     */%0A    public LambdaCounter(Logger logger, int logFrequency, String message) %7B%0A        this(logger, 0, logFrequency, message);%0A    %7D%0A%0A    public synchronized void increment() %7B%0A        count += 1;%0A        if (count %25 logFrequency == 0) %7B%0A            log();%0A        %7D%0A    %7D%0A%0A    public synchronized int getCount() %7B%0A        return count;%0A    %7D%0A%0A    private void log () %7B%0A        if (total %3E 0) %7B%0A            logger.info(message, count, total);%0A        %7D else %7B%0A            logger.info(message, count);%0A        %7D%0A    %7D%0A%0A    public void done () %7B%0A        message = %22Done. %22 + message;%0A        log();%0A    %7D%0A%0A%7D%0A

Add LambdaCounter class that can count iterations within parallelized lambdas.