mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8198484: URLClassPath should use an ArrayDeque instead of a Stack
Reviewed-by: alanb, mchung, plevart, psandoz
This commit is contained in:
parent
541978b4a2
commit
80e322bbcc
1 changed files with 31 additions and 29 deletions
|
@ -46,6 +46,7 @@ import java.security.Permission;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -57,7 +58,6 @@ import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
@ -101,10 +101,10 @@ public class URLClassPath {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The original search path of URLs. */
|
/* The original search path of URLs. */
|
||||||
private final List<URL> path;
|
private final ArrayList<URL> path;
|
||||||
|
|
||||||
/* The stack of unopened URLs */
|
/* The deque of unopened URLs */
|
||||||
private final Stack<URL> unopenedUrls = new Stack<>();
|
private final ArrayDeque<URL> unopenedUrls;
|
||||||
|
|
||||||
/* The resulting search path of Loaders */
|
/* The resulting search path of Loaders */
|
||||||
private final ArrayList<Loader> loaders = new ArrayList<>();
|
private final ArrayList<Loader> loaders = new ArrayList<>();
|
||||||
|
@ -138,12 +138,15 @@ public class URLClassPath {
|
||||||
public URLClassPath(URL[] urls,
|
public URLClassPath(URL[] urls,
|
||||||
URLStreamHandlerFactory factory,
|
URLStreamHandlerFactory factory,
|
||||||
AccessControlContext acc) {
|
AccessControlContext acc) {
|
||||||
List<URL> path = new ArrayList<>(urls.length);
|
ArrayList<URL> path = new ArrayList<>(urls.length);
|
||||||
|
ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(urls.length);
|
||||||
for (URL url : urls) {
|
for (URL url : urls) {
|
||||||
path.add(url);
|
path.add(url);
|
||||||
|
unopenedUrls.add(url);
|
||||||
}
|
}
|
||||||
this.path = path;
|
this.path = path;
|
||||||
push(urls);
|
this.unopenedUrls = unopenedUrls;
|
||||||
|
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
jarHandler = factory.createURLStreamHandler("jar");
|
jarHandler = factory.createURLStreamHandler("jar");
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,7 +172,7 @@ public class URLClassPath {
|
||||||
* @apiNote Used to create the application class path.
|
* @apiNote Used to create the application class path.
|
||||||
*/
|
*/
|
||||||
URLClassPath(String cp, boolean skipEmptyElements) {
|
URLClassPath(String cp, boolean skipEmptyElements) {
|
||||||
List<URL> path = new ArrayList<>();
|
ArrayList<URL> path = new ArrayList<>();
|
||||||
if (cp != null) {
|
if (cp != null) {
|
||||||
// map each element of class path to a file URL
|
// map each element of class path to a file URL
|
||||||
int off = 0;
|
int off = 0;
|
||||||
|
@ -189,13 +192,16 @@ public class URLClassPath {
|
||||||
URL url = toFileURL(element);
|
URL url = toFileURL(element);
|
||||||
if (url != null) path.add(url);
|
if (url != null) path.add(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// push the URLs
|
|
||||||
for (int i = path.size() - 1; i >= 0; --i) {
|
|
||||||
unopenedUrls.push(path.get(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// can't use ArrayDeque#addAll or new ArrayDeque(Collection);
|
||||||
|
// it's too early in the bootstrap to trigger use of lambdas
|
||||||
|
int size = path.size();
|
||||||
|
ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(size);
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
unopenedUrls.add(path.get(i));
|
||||||
|
|
||||||
|
this.unopenedUrls = unopenedUrls;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.jarHandler = null;
|
this.jarHandler = null;
|
||||||
this.acc = null;
|
this.acc = null;
|
||||||
|
@ -225,16 +231,15 @@ public class URLClassPath {
|
||||||
* URLs, then invoking this method has no effect.
|
* URLs, then invoking this method has no effect.
|
||||||
*/
|
*/
|
||||||
public synchronized void addURL(URL url) {
|
public synchronized void addURL(URL url) {
|
||||||
if (closed)
|
if (closed || url == null)
|
||||||
return;
|
return;
|
||||||
synchronized (unopenedUrls) {
|
synchronized (unopenedUrls) {
|
||||||
if (url == null || path.contains(url))
|
if (! path.contains(url)) {
|
||||||
return;
|
unopenedUrls.addLast(url);
|
||||||
|
|
||||||
unopenedUrls.add(0, url);
|
|
||||||
path.add(url);
|
path.add(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends the specified file path as a file URL to the search path.
|
* Appends the specified file path as a file URL to the search path.
|
||||||
|
@ -414,16 +419,13 @@ public class URLClassPath {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Expand URL search path until the request can be satisfied
|
// Expand URL search path until the request can be satisfied
|
||||||
// or the URL stack is empty.
|
// or unopenedUrls is exhausted.
|
||||||
while (loaders.size() < index + 1) {
|
while (loaders.size() < index + 1) {
|
||||||
// Pop the next URL from the URL stack
|
final URL url;
|
||||||
URL url;
|
|
||||||
synchronized (unopenedUrls) {
|
synchronized (unopenedUrls) {
|
||||||
if (unopenedUrls.empty()) {
|
url = unopenedUrls.pollFirst();
|
||||||
|
if (url == null)
|
||||||
return null;
|
return null;
|
||||||
} else {
|
|
||||||
url = unopenedUrls.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Skip this URL if it already has a Loader. (Loader
|
// Skip this URL if it already has a Loader. (Loader
|
||||||
// may be null in the case where URL has not been opened
|
// may be null in the case where URL has not been opened
|
||||||
|
@ -437,7 +439,7 @@ public class URLClassPath {
|
||||||
try {
|
try {
|
||||||
loader = getLoader(url);
|
loader = getLoader(url);
|
||||||
// If the loader defines a local class path then add the
|
// If the loader defines a local class path then add the
|
||||||
// URLs to the list of URLs to be opened.
|
// URLs as the next URLs to be opened.
|
||||||
URL[] urls = loader.getClassPath();
|
URL[] urls = loader.getClassPath();
|
||||||
if (urls != null) {
|
if (urls != null) {
|
||||||
push(urls);
|
push(urls);
|
||||||
|
@ -502,12 +504,12 @@ public class URLClassPath {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pushes the specified URLs onto the list of unopened URLs.
|
* Pushes the specified URLs onto the head of unopened URLs.
|
||||||
*/
|
*/
|
||||||
private void push(URL[] urls) {
|
private void push(URL[] urls) {
|
||||||
synchronized (unopenedUrls) {
|
synchronized (unopenedUrls) {
|
||||||
for (int i = urls.length - 1; i >= 0; --i) {
|
for (int i = urls.length - 1; i >= 0; --i) {
|
||||||
unopenedUrls.push(urls[i]);
|
unopenedUrls.addFirst(urls[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue