/* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * The Original Code is HAT. The Initial Developer of the * Original Code is Bill Foote, with contributions from others * at JavaSoft/Sun. */ package com.sun.tools.hat.internal.parser; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Consumer; public class LoadProgress { private List<ProgressElement> elements = Collections.synchronizedList(new ArrayList<>()); public void startLoadingStream(String heapFile, PositionDataInputStream stream) { elements.add(new StreamProgress(heapFile, stream)); } public TickedProgress startTickedProgress(String name, int numTicks) { TickedProgress progress = new TickedProgress(name, numTicks); elements.add(progress); return progress; } public void end() { synchronized (elements) { elements.get(elements.size() - 1).end(); } } public void each(Consumer<ProgressElement> callback) { synchronized (elements) { for (ProgressElement progress : elements) { callback.accept(progress); } } } public static abstract class ProgressElement { private final long startTime; private volatile boolean ended = false; public ProgressElement() { this.startTime = System.currentTimeMillis(); } protected abstract double getPercentDone(); protected abstract String getLoadDescription(); public String getLoadString() { double percentDone = getPercentDone(); String loadTime = "unknown"; long elapsed = System.currentTimeMillis() - startTime; if (elapsed > 0 && percentDone > 0.0) { double totalExpectedMillis = (elapsed / (percentDone / 100.0)) - elapsed; if (totalExpectedMillis > 60000.0) { loadTime = String.format("%1.1f minutes", totalExpectedMillis / 60000.0); } else { loadTime = String.format("%1.1f seconds", totalExpectedMillis / 1000.0); } } return String.format("%s: %1.1f%%, estimated remaining load time: %s", getLoadDescription(), percentDone, loadTime); } public void end() { ended = true; } protected boolean isEnded() { return ended; } } public static class StreamProgress extends ProgressElement { private final String heapFile; private final PositionDataInputStream stream; private final long length; public StreamProgress(String heapFile, PositionDataInputStream stream) { this.heapFile = heapFile; this.stream = stream; this.length = new File(heapFile).length(); } @Override protected double getPercentDone() { if (isEnded()) { return 100.0; } return ((double) stream.position() / (double) length) * 100.0; } @Override protected String getLoadDescription() { return String.format("%s is loading", heapFile); } } public static class TickedProgress extends ProgressElement { private final String name; private final int numTicks; private volatile int progress = 0; public TickedProgress(String name, int numTicks) { this.name = name; this.numTicks = numTicks; } public void tick() { progress++; } @Override protected double getPercentDone() { if (isEnded()) { return 100.0; } return ((double) progress / (double) numTicks) * 100.0; } @Override protected String getLoadDescription() { return name; } } }