<commit_before>package io.github.lukehutch.fastclasspathscanner.utils;

import java.text.DecimalFormat;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;

public class Log {

    /** Class for accumulating ordered log entries from sub-threads, for later writing to the log. */
    public static class DeferredLog {
        private static class DeferredLogEntry {
            final int indentLevel;
            final String msg;
            final long elapsedTimeNanos;

            public DeferredLogEntry(final int indentLevel, final String msg, final long elapsedTimeNanos) {
                this.indentLevel = indentLevel;
                this.msg = msg;
                this.elapsedTimeNanos = elapsedTimeNanos;
            }

            public DeferredLogEntry(final int indentLevel, final String msg) {
                this.indentLevel = indentLevel;
                this.msg = msg;
                this.elapsedTimeNanos = -1L;
            }

            public void sendToLog() {
                if (elapsedTimeNanos < 0L) {
                    Log.log(indentLevel, msg);
                } else {
                    Log.log(indentLevel, msg, elapsedTimeNanos);
                }
            }
        }

        private final List<DeferredLogEntry> logEntries = new ArrayList<>();

        private static Object lock = new Object();

        public void log(final int indentLevel, final String msg) {
            logEntries.add(new DeferredLogEntry(indentLevel, msg));
        }

        public void log(final String msg) {
            logEntries.add(new DeferredLogEntry(0, msg));
        }

        public void log(final int indentLevel, final String msg, final long elapsedTimeNanos) {
            logEntries.add(new DeferredLogEntry(indentLevel, msg, elapsedTimeNanos));
        }

        public void log(final String msg, final long elapsedTimeNanos) {
            logEntries.add(new DeferredLogEntry(0, msg, elapsedTimeNanos));
        }

        public void flush() {
            if (!logEntries.isEmpty()) {
                synchronized (lock) {
                    for (final DeferredLogEntry entry : logEntries) {
                        entry.sendToLog();
                    }
                    logEntries.clear();
                    Log.flush();
                }
            }
        }
    }

    private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
            .withZone(ZoneOffset.UTC);

    private static DecimalFormat nanoFormatter = new DecimalFormat("0.000000");

    private Log() {
    }

    private static String indent(final int indentLevel, final String msg) {
        final int numIndentChars = 2 * indentLevel;
        final StringBuilder buf = new StringBuilder(msg.length() + numIndentChars);
        for (int i = 0; i < numIndentChars - 1; i++) {
            buf.append('-');
        }
        if (numIndentChars > 0) {
            buf.append(" ");
        }
        buf.append(msg);
        return buf.toString();
    }<commit_msg>Fix race<commit_after>package io.github.lukehutch.fastclasspathscanner.utils;

import java.text.DecimalFormat;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;

public class Log {

    /** Class for accumulating ordered log entries from sub-threads, for later writing to the log. */
    public static class DeferredLog {
        private static class DeferredLogEntry {
            final int indentLevel;
            final String msg;
            final long elapsedTimeNanos;

            public DeferredLogEntry(final int indentLevel, final String msg, final long elapsedTimeNanos) {
                this.indentLevel = indentLevel;
                this.msg = msg;
                this.elapsedTimeNanos = elapsedTimeNanos;
            }

            public DeferredLogEntry(final int indentLevel, final String msg) {
                this.indentLevel = indentLevel;
                this.msg = msg;
                this.elapsedTimeNanos = -1L;
            }

            public void sendToLog() {
                if (elapsedTimeNanos < 0L) {
                    Log.log(indentLevel, msg);
                } else {
                    Log.log(indentLevel, msg, elapsedTimeNanos);
                }
            }
        }

        private final Queue<DeferredLogEntry> logEntries = new ConcurrentLinkedQueue<>();

        private static Object lock = new Object();

        public void log(final int indentLevel, final String msg) {
            logEntries.add(new DeferredLogEntry(indentLevel, msg));
        }

        public void log(final String msg) {
            logEntries.add(new DeferredLogEntry(0, msg));
        }

        public void log(final int indentLevel, final String msg, final long elapsedTimeNanos) {
            logEntries.add(new DeferredLogEntry(indentLevel, msg, elapsedTimeNanos));
        }

        public void log(final String msg, final long elapsedTimeNanos) {
            logEntries.add(new DeferredLogEntry(0, msg, elapsedTimeNanos));
        }

        public void flush() {
            if (!logEntries.isEmpty()) {
                synchronized (lock) {
                    for (DeferredLogEntry entry; (entry = logEntries.poll()) != null;) {
                        entry.sendToLog();
                    }
                    Log.flush();
                }
            }
        }
    }

    private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
            .withZone(ZoneOffset.UTC);

    private static DecimalFormat nanoFormatter = new DecimalFormat("0.000000");

    private Log() {
    }

    private static String indent(final int indentLevel, final String msg) {
        final int numIndentChars = 2 * indentLevel;
        final StringBuilder buf = new StringBuilder(msg.length() + numIndentChars);
        for (int i = 0; i < numIndentChars - 1; i++) {
            buf.append('-');
        }
        if (numIndentChars > 0) {
            buf.append(" ");
        }
        buf.append(msg);
        return buf.toString();
    }
{'fraction_non_alphanumeric': 0.08675300358870339, 'fraction_numerical': 0.004680917459822125, 'mean_word_length': 1.9457720588235294, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5108105', 'n_tokens_mistral': 1735, 'n_tokens_neox': 1622, 'n_words': 429}