mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8259947: (fs) Optimize UnixPath.encode implementation
Reviewed-by: chegar, shade, alanb
This commit is contained in:
parent
69f90b5fd4
commit
5891509d13
6 changed files with 64 additions and 67 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,9 +25,6 @@
|
||||||
|
|
||||||
package sun.nio.fs;
|
package sun.nio.fs;
|
||||||
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bsd specific system calls.
|
* Bsd specific system calls.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,9 +25,6 @@
|
||||||
|
|
||||||
package sun.nio.fs;
|
package sun.nio.fs;
|
||||||
|
|
||||||
import java.nio.file.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static sun.nio.fs.MacOSXNativeDispatcher.*;
|
import static sun.nio.fs.MacOSXNativeDispatcher.*;
|
||||||
|
@ -47,14 +44,18 @@ class MacOSXFileSystem extends BsdFileSystem {
|
||||||
return Pattern.compile(expr, Pattern.CANON_EQ) ;
|
return Pattern.compile(expr, Pattern.CANON_EQ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
char[] normalizeNativePath(char[] path) {
|
@Override
|
||||||
for (char c : path) {
|
String normalizeNativePath(String path) {
|
||||||
|
for (int i = 0; i < path.length(); i++) {
|
||||||
|
char c = path.charAt(i);
|
||||||
if (c > 0x80)
|
if (c > 0x80)
|
||||||
return normalizepath(path, kCFStringNormalizationFormD);
|
return new String(normalizepath(path.toCharArray(),
|
||||||
|
kCFStringNormalizationFormD));
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
String normalizeJavaPath(String path) {
|
String normalizeJavaPath(String path) {
|
||||||
for (int i = 0; i < path.length(); i++) {
|
for (int i = 0; i < path.length(); i++) {
|
||||||
if (path.charAt(i) > 0x80)
|
if (path.charAt(i) > 0x80)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,9 +25,6 @@
|
||||||
|
|
||||||
package sun.nio.fs;
|
package sun.nio.fs;
|
||||||
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MacOSX specific system calls.
|
* MacOSX specific system calls.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -343,7 +343,7 @@ abstract class UnixFileSystem
|
||||||
// Override if the platform uses different Unicode normalization form
|
// Override if the platform uses different Unicode normalization form
|
||||||
// for native file path. For example on MacOSX, the native path is stored
|
// for native file path. For example on MacOSX, the native path is stored
|
||||||
// in Unicode NFD form.
|
// in Unicode NFD form.
|
||||||
char[] normalizeNativePath(char[] path) {
|
String normalizeNativePath(String path) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -25,26 +25,25 @@
|
||||||
|
|
||||||
package sun.nio.fs;
|
package sun.nio.fs;
|
||||||
|
|
||||||
import java.nio.*;
|
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.charset.*;
|
import java.nio.charset.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.lang.ref.SoftReference;
|
|
||||||
|
import jdk.internal.access.JavaLangAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
|
|
||||||
import static sun.nio.fs.UnixNativeDispatcher.*;
|
import static sun.nio.fs.UnixNativeDispatcher.*;
|
||||||
import static sun.nio.fs.UnixConstants.*;
|
import static sun.nio.fs.UnixConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Solaris/Linux implementation of java.nio.file.Path
|
* Linux/Mac implementation of java.nio.file.Path
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class UnixPath implements Path {
|
class UnixPath implements Path {
|
||||||
private static ThreadLocal<SoftReference<CharsetEncoder>> encoder =
|
|
||||||
new ThreadLocal<SoftReference<CharsetEncoder>>();
|
|
||||||
|
|
||||||
// FIXME - eliminate this reference to reduce space
|
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||||
|
|
||||||
private final UnixFileSystem fs;
|
private final UnixFileSystem fs;
|
||||||
|
|
||||||
// internal representation
|
// internal representation
|
||||||
|
@ -115,43 +114,13 @@ class UnixPath implements Path {
|
||||||
|
|
||||||
// encodes the given path-string into a sequence of bytes
|
// encodes the given path-string into a sequence of bytes
|
||||||
private static byte[] encode(UnixFileSystem fs, String input) {
|
private static byte[] encode(UnixFileSystem fs, String input) {
|
||||||
SoftReference<CharsetEncoder> ref = encoder.get();
|
input = fs.normalizeNativePath(input);
|
||||||
CharsetEncoder ce = (ref != null) ? ref.get() : null;
|
try {
|
||||||
if (ce == null) {
|
return JLA.getBytesNoRepl(input, Util.jnuEncoding());
|
||||||
ce = Util.jnuEncoding().newEncoder()
|
} catch (CharacterCodingException cce) {
|
||||||
.onMalformedInput(CodingErrorAction.REPORT)
|
|
||||||
.onUnmappableCharacter(CodingErrorAction.REPORT);
|
|
||||||
encoder.set(new SoftReference<>(ce));
|
|
||||||
}
|
|
||||||
|
|
||||||
char[] ca = fs.normalizeNativePath(input.toCharArray());
|
|
||||||
|
|
||||||
// size output buffer for worse-case size
|
|
||||||
byte[] ba = new byte[(int)(ca.length * (double)ce.maxBytesPerChar())];
|
|
||||||
|
|
||||||
// encode
|
|
||||||
ByteBuffer bb = ByteBuffer.wrap(ba);
|
|
||||||
CharBuffer cb = CharBuffer.wrap(ca);
|
|
||||||
ce.reset();
|
|
||||||
CoderResult cr = ce.encode(cb, bb, true);
|
|
||||||
boolean error;
|
|
||||||
if (!cr.isUnderflow()) {
|
|
||||||
error = true;
|
|
||||||
} else {
|
|
||||||
cr = ce.flush(bb);
|
|
||||||
error = !cr.isUnderflow();
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
throw new InvalidPathException(input,
|
throw new InvalidPathException(input,
|
||||||
"Malformed input or input contains unmappable characters");
|
"Malformed input or input contains unmappable characters");
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim result to actual length if required
|
|
||||||
int len = bb.position();
|
|
||||||
if (len != ba.length)
|
|
||||||
ba = Arrays.copyOf(ba, len);
|
|
||||||
|
|
||||||
return ba;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// package-private
|
// package-private
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -27,24 +27,24 @@ import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Path;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the overheads of I/O API.
|
* Tests the overheads of creating File objects, and converting such objects to Paths.
|
||||||
*/
|
*/
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
@State(Scope.Thread)
|
@State(Scope.Thread)
|
||||||
@Warmup(time=2, iterations=5)
|
@Warmup(time=2, iterations=5)
|
||||||
@Measurement(time=3, iterations=5)
|
@Measurement(time=3, iterations=5)
|
||||||
@Fork(value=2, jvmArgs="-Xmx1g")
|
@Fork(value=2, jvmArgs="-Xmx1g")
|
||||||
public class FileOpen {
|
public class FileOpen {
|
||||||
|
|
||||||
public String normalFile = "/test/dir/file/name.txt";
|
private String normalFile = "/test/dir/file/name.txt";
|
||||||
public String root = "/";
|
private String root = "/";
|
||||||
public String trailingSlash = "/test/dir/file/name.txt/";
|
private String trailingSlash = "/test/dir/file/name.txt/";
|
||||||
public String notNormalizedFile = "/test/dir/file//name.txt";
|
private String notNormalizedFile = "/test/dir/file//name.txt";
|
||||||
|
|
||||||
public File tmp;
|
public File tmp;
|
||||||
|
|
||||||
|
@ -68,6 +68,11 @@ public class FileOpen {
|
||||||
return new File(normalFile);
|
return new File(normalFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public File root() {
|
||||||
|
return new File(root);
|
||||||
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
public File trailingSlash() {
|
public File trailingSlash() {
|
||||||
return new File(trailingSlash);
|
return new File(trailingSlash);
|
||||||
|
@ -85,4 +90,32 @@ public class FileOpen {
|
||||||
&& tmp.isDirectory()
|
&& tmp.isDirectory()
|
||||||
&& tmp.isFile();
|
&& tmp.isFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public void mixToPath(Blackhole bh) {
|
||||||
|
bh.consume(new File(normalFile).toPath());
|
||||||
|
bh.consume(new File(root).toPath());
|
||||||
|
bh.consume(new File(trailingSlash).toPath());
|
||||||
|
bh.consume(new File(notNormalizedFile).toPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Path normalizedToPath() {
|
||||||
|
return new File(normalFile).toPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Path rootToPath() {
|
||||||
|
return new File(root).toPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Path trailingSlashToPath() {
|
||||||
|
return new File(trailingSlash).toPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Path notNormalizedToPath() {
|
||||||
|
return new File(notNormalizedFile).toPath();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue