Skip to content

Commit

Permalink
Refactor PathUtilities#createUnique
Browse files Browse the repository at this point in the history
  • Loading branch information
c-refice committed Mar 4, 2024
1 parent 4adb1ee commit 52bf5cc
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,18 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.stream.Stream;

import jdk.graal.compiler.debug.DebugOptions;
import jdk.graal.compiler.debug.PathUtilities;
import jdk.graal.compiler.options.OptionKey;
import jdk.graal.compiler.options.OptionValues;
import jdk.graal.compiler.test.AddExports;
import org.junit.Assume;
import org.junit.Test;

import jdk.graal.compiler.debug.PathUtilities;
import jdk.graal.compiler.test.AddExports;

@AddExports("jdk.graal.compiler/jdk.graal.compiler.printer")
public class GraalDebugHandlersFactoryTest extends GraalCompilerTest {

Expand All @@ -53,21 +51,18 @@ public void createUniqueTest() throws Exception {
Assume.assumeFalse("If InaccessibleObjectException is thrown, skip the test, we are on JDK9", ex.getClass().getSimpleName().equals("InaccessibleObjectException"));
}
int maxFileNameLength = maxFileNameLengthField.getInt(null);
Method createUniqueMethod = PathUtilities.class.getDeclaredMethod("createUnique", OptionValues.class, OptionKey.class, String.class, String.class, String.class, boolean.class);
createUniqueMethod.setAccessible(true);
Path tmpDir = Files.createTempDirectory(Paths.get("."), "createUniqueTest");
OptionValues options = new OptionValues(OptionValues.asMap(DebugOptions.DumpPath, tmpDir.toString()));
try {
for (boolean createDirectory : new boolean[]{true, false}) {
for (String ext : new String[]{"", ".bgv", ".graph-strings"}) {
for (int i = 0; i < maxFileNameLength + 5; i++) {
String id = new String(new char[i]).replace('\0', 'i');
String label = "";
createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
PathUtilities.createUnique(tmpDir.toString(), id, label, ext, createDirectory);

id = "";
label = new String(new char[i]).replace('\0', 'l');
createUniqueMethod.invoke(null, options, null, id, label, ext, createDirectory);
PathUtilities.createUnique(tmpDir.toString(), id, label, ext, createDirectory);
}
}
}
Expand All @@ -77,6 +72,8 @@ public void createUniqueTest() throws Exception {
}

private static void deleteTree(Path root) throws IOException {
Files.walk(root).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
try (Stream<Path> elems = Files.walk(root)) {
elems.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import static java.util.FormattableFlags.UPPERCASE;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
Expand Down Expand Up @@ -395,8 +396,7 @@ public String toString() {
}

String getLabel() {
if (compilable instanceof JavaMethod) {
JavaMethod method = (JavaMethod) compilable;
if (compilable instanceof JavaMethod method) {
return method.format("%h.%n(%p)%r");
}
return String.valueOf(compilable);
Expand Down Expand Up @@ -645,7 +645,15 @@ public String getDumpPath(String extension, boolean createMissingDirectory, bool
try {
String id = description == null ? null : description.identifier;
String label = description == null ? null : description.getLabel();
String result = PathUtilities.createUnique(immutable.options, DebugOptions.DumpPath, id, label, extension, createMissingDirectory);
String prefix;
if (id == null) {
prefix = DebugOptions.DumpPath.getValue(immutable.options);
int slash = prefix.lastIndexOf(File.separatorChar);
prefix = prefix.substring(slash + 1);
} else {
prefix = id;
}
String result = PathUtilities.createUnique(DebugOptions.getDumpDirectory(immutable.options), prefix, label, extension, createMissingDirectory);
if (showDumpFiles) {
TTY.println(DUMP_FILE_MESSAGE_FORMAT, result);
}
Expand Down Expand Up @@ -2321,9 +2329,8 @@ private void printMetrics(PrintStream out, Object compilable, Integer identity,
String name = key.getName();
long value = metricValues[index];
String valueString;
if (key instanceof TimerKey) {
if (key instanceof TimerKey timer) {
// Report timers in ms
TimerKey timer = (TimerKey) key;
long ms = timer.getTimeUnit().toMillis(value);
if (ms == 0) {
continue;
Expand All @@ -2343,7 +2350,7 @@ private void printMetrics(PrintStream out, Object compilable, Integer identity,
out.println(new String(new char[title.length()]).replace('\0', '~'));

for (Map.Entry<String, String> e : res.entrySet()) {
out.printf("%-" + String.valueOf(maxKeyWidth) + "s = %20s%n", e.getKey(), e.getValue());
out.printf("%-" + maxKeyWidth + "s = %20s%n", e.getKey(), e.getValue());
}
out.println();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@
import java.util.Iterator;
import java.util.ServiceLoader;

import jdk.graal.compiler.options.OptionKey;
import jdk.graal.compiler.options.OptionValues;

/**
* Miscellaneous methods for modifying and generating file system paths.
*
Expand Down Expand Up @@ -177,39 +174,55 @@ public static String archiveAndDelete(String directory, String zip) throws IOExc

private static final String ELLIPSIS = "...";

static String createUnique(OptionValues options, OptionKey<String> baseNameOption, String id, String label, String ext, boolean createMissingDirectory) throws IOException {
String uniqueTag = "";
int dumpCounter = 1;
String prefix;
if (id == null) {
prefix = baseNameOption.getValue(options);
int slash = prefix.lastIndexOf(File.separatorChar);
prefix = prefix.substring(slash + 1);
/**
* Constructs a filename from the given parts (prefix + label + suffix). If the resulting
* filename would be too long, it is shortened by first truncating the label, and if that is not
* enough, the prefix. The suffix is always left as-is.
*/
private static String constructFileName(String prefix, String label, String suffix) {
int fileNameLengthWithoutLabel = suffix.length() + prefix.length() + "[]".length();
int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
String fileName;
if (labelLengthLimit < ELLIPSIS.length()) {
// `prefix` is very long, so we can't fit the label in the filename
int prefixLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), prefix.length());
fileName = prefix.substring(0, prefixLengthLimit) + suffix;
} else if (label == null) {
fileName = prefix + suffix;
} else {
prefix = id;
String adjustedLabel = label;
if (label.length() > labelLengthLimit) {
adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
}
fileName = prefix + '[' + adjustedLabel + ']' + suffix;
}
return sanitizeFileName(fileName);
}

/**
* Attempts to create a unique file or directory in the given directory. The resulting filename
* is obtained by concatenating the parameters (prefix + label + [uniqueTag] + ext), where
* uniqueTag is chosen to make the resulting filename unique in the given directory.
*
* @param directory the directory in which the unique filename will be created
* @param prefix base name for the resulting filename. May be truncated if it's too large.
* @param label an optional label that will be appended to the prefix if the filename is not too
* large.
* @param ext extension to the unique path. Will always be retained as-is, even if the filename
* would be too large.
* @param createMissingDirectory if true, the unique path, along with any non-existing parent
* directories, is created as a directory instead of a file.
* @return the path to the created unique file or directory.
* @throws IOException if creating the file or directory fails in any way other than it already
* existing.
*/
public static String createUnique(String directory, String prefix, String label, String ext, boolean createMissingDirectory)
throws IOException {
String uniqueTag = "";
int dumpCounter = 1;
for (;;) { // TERMINATION ARGUMENT: Time stamps make collisions very unlikely.
int fileNameLengthWithoutLabel = uniqueTag.length() + ext.length() + prefix.length() + "[]".length();
int labelLengthLimit = MAX_FILE_NAME_LENGTH - fileNameLengthWithoutLabel;
String fileName;
if (labelLengthLimit < ELLIPSIS.length()) {
// This means `id` is very long
String suffix = uniqueTag + ext;
int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), prefix.length());
fileName = sanitizeFileName(prefix.substring(0, idLengthLimit) + suffix);
} else {
if (label == null) {
fileName = sanitizeFileName(prefix + uniqueTag + ext);
} else {
String adjustedLabel = label;
if (label.length() > labelLengthLimit) {
adjustedLabel = label.substring(0, labelLengthLimit - ELLIPSIS.length()) + ELLIPSIS;
}
fileName = sanitizeFileName(prefix + '[' + adjustedLabel + ']' + uniqueTag + ext);
}
}
String dumpDir = DebugOptions.getDumpDirectory(options);
String result = getPath(dumpDir, fileName);
String fileName = constructFileName(prefix, label, uniqueTag + ext);
String result = getPath(directory, fileName);
try {
if (createMissingDirectory) {
if (exists(result)) {
Expand Down

0 comments on commit 52bf5cc

Please sign in to comment.