Newer
Older
void-pack-super-server / work / decompile-ee3ecae0 / net / minecraft / server / MethodProfiler.java
package net.minecraft.server;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongMaps;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.function.IntSupplier;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.Supplier;

public class MethodProfiler implements GameProfilerFillerActive {

    private static final long a = Duration.ofMillis(100L).toNanos();
    private static final Logger LOGGER = LogManager.getLogger();
    private final List<String> c = Lists.newArrayList();
    private final LongList d = new LongArrayList();
    private final Map<String, MethodProfiler.a> e = Maps.newHashMap();
    private final IntSupplier f;
    private final long g;
    private final int h;
    private String i = "";
    private boolean j;
    @Nullable
    private MethodProfiler.a k;
    private final boolean l;

    public MethodProfiler(long i, IntSupplier intsupplier, boolean flag) {
        this.g = i;
        this.h = intsupplier.getAsInt();
        this.f = intsupplier;
        this.l = flag;
    }

    @Override
    public void a() {
        if (this.j) {
            MethodProfiler.LOGGER.error("Profiler tick already started - missing endTick()?");
        } else {
            this.j = true;
            this.i = "";
            this.c.clear();
            this.enter("root");
        }
    }

    @Override
    public void b() {
        if (!this.j) {
            MethodProfiler.LOGGER.error("Profiler tick already ended - missing startTick()?");
        } else {
            this.exit();
            this.j = false;
            if (!this.i.isEmpty()) {
                MethodProfiler.LOGGER.error("Profiler tick ended before path was fully popped (remainder: '{}'). Mismatched push/pop?", new Supplier[]{() -> {
                            return MethodProfilerResults.b(this.i);
                        }});
            }

        }
    }

    @Override
    public void enter(String s) {
        if (!this.j) {
            MethodProfiler.LOGGER.error("Cannot push '{}' to profiler if profiler tick hasn't started - missing startTick()?", s);
        } else {
            if (!this.i.isEmpty()) {
                this.i = this.i + '\u001e';
            }

            this.i = this.i + s;
            this.c.add(this.i);
            this.d.add(SystemUtils.getMonotonicNanos());
            this.k = null;
        }
    }

    @Override
    public void a(java.util.function.Supplier<String> java_util_function_supplier) {
        this.enter((String) java_util_function_supplier.get());
    }

    @Override
    public void exit() {
        if (!this.j) {
            MethodProfiler.LOGGER.error("Cannot pop from profiler if profiler tick hasn't started - missing startTick()?");
        } else if (this.d.isEmpty()) {
            MethodProfiler.LOGGER.error("Tried to pop one too many times! Mismatched push() and pop()?");
        } else {
            long i = SystemUtils.getMonotonicNanos();
            long j = this.d.removeLong(this.d.size() - 1);

            this.c.remove(this.c.size() - 1);
            long k = i - j;
            MethodProfiler.a methodprofiler_a = this.e();

            methodprofiler_a.a = methodprofiler_a.a + k;
            methodprofiler_a.b = methodprofiler_a.b + 1L;
            if (this.l && k > MethodProfiler.a) {
                MethodProfiler.LOGGER.warn("Something's taking too long! '{}' took aprox {} ms", new Supplier[]{() -> {
                            return MethodProfilerResults.b(this.i);
                        }, () -> {
                            return (double) k / 1000000.0D;
                        }});
            }

            this.i = this.c.isEmpty() ? "" : (String) this.c.get(this.c.size() - 1);
            this.k = null;
        }
    }

    @Override
    public void exitEnter(String s) {
        this.exit();
        this.enter(s);
    }

    private MethodProfiler.a e() {
        if (this.k == null) {
            this.k = (MethodProfiler.a) this.e.computeIfAbsent(this.i, (s) -> {
                return new MethodProfiler.a();
            });
        }

        return this.k;
    }

    @Override
    public void c(String s) {
        this.e().c.addTo(s, 1L);
    }

    @Override
    public void c(java.util.function.Supplier<String> java_util_function_supplier) {
        this.e().c.addTo(java_util_function_supplier.get(), 1L);
    }

    @Override
    public MethodProfilerResults d() {
        return new MethodProfilerResultsFilled(this.e, this.g, this.h, SystemUtils.getMonotonicNanos(), this.f.getAsInt());
    }

    static class a implements MethodProfilerResult {

        private long a;
        private long b;
        private Object2LongOpenHashMap<String> c;

        private a() {
            this.c = new Object2LongOpenHashMap();
        }

        @Override
        public long a() {
            return this.a;
        }

        @Override
        public long b() {
            return this.b;
        }

        @Override
        public Object2LongMap<String> c() {
            return Object2LongMaps.unmodifiable(this.c);
        }
    }
}