Skip to content

Commit e8b5734

Browse files
committed
* Speed up Loader on Windows when there are no symbolic links or library versions (pull #512)
1 parent 2616b0b commit e8b5734

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
* Speed up `Loader` on Windows when there are no symbolic links or library versions ([pull #512](https://github.com/bytedeco/javacpp/pull/512))
23
* Enhance `Pointer.physicalBytes()` by excluding shared pages from memory-mapped files, etc ([issue #468](https://github.com/bytedeco/javacpp/issues/468))
34
* Fix `Parser` not correctly encoding files of top-level classes produced with `@Properties(target=..., global=...)`
45
* Add `Pointer.interruptDeallocatorThread()` method to make JavaCPP classes eligible for GC ([discussion bytedeco/javacpp-presets#1115](https://github.com/bytedeco/javacpp-presets/discussions/1115))

src/main/java/org/bytedeco/javacpp/Loader.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2011-2020 Samuel Audet
2+
* Copyright (C) 2011-2022 Samuel Audet
33
*
44
* Licensed either under the Apache License, Version 2.0, or (at your option)
55
* under the terms of the GNU General Public License as published by
@@ -500,7 +500,7 @@ public static File cacheResource(URL resourceURL, String target) throws IOExcept
500500
boolean reference = false;
501501
long size = 0, timestamp = 0;
502502
File cacheDir = getCacheDir();
503-
File cacheSubdir = Loader.getCanonicalFile(cacheDir);
503+
File cacheSubdir = cacheDir;
504504
String s = System.getProperty("org.bytedeco.javacpp.cachedir.nosubdir", "false").toLowerCase();
505505
boolean noSubdir = s.equals("true") || s.equals("t") || s.equals("");
506506
URLConnection urlConnection = resourceURL.openConnection();
@@ -661,7 +661,7 @@ public static File cacheResource(URL resourceURL, String target) throws IOExcept
661661
}
662662
// ... check if it has not already been extracted, and if not ...
663663
if (!file.exists() || file.length() != size || file.lastModified() != timestamp
664-
|| !cacheSubdir.equals(Loader.getCanonicalFile(file).getParentFile())) {
664+
|| (canCreateSymbolicLink && !cacheSubdir.equals(Loader.getCanonicalFile(file).getParentFile()))) {
665665
// ... add lock to avoid two JVMs access cacheDir simultaneously and ...
666666
synchronized (Runtime.getRuntime()) {
667667
try {
@@ -672,7 +672,7 @@ public static File cacheResource(URL resourceURL, String target) throws IOExcept
672672
lock = lockChannel.lock();
673673
// ... check if other JVM has extracted it before this JVM get the lock ...
674674
if (!file.exists() || file.length() != size || file.lastModified() != timestamp
675-
|| !cacheSubdir.equals(Loader.getCanonicalFile(file).getParentFile())) {
675+
|| (canCreateSymbolicLink && !cacheSubdir.equals(Loader.getCanonicalFile(file).getParentFile()))) {
676676
// ... extract it from our resources ...
677677
if (logger.isDebugEnabled()) {
678678
logger.debug("Extracting " + resourceURL);
@@ -790,7 +790,8 @@ public static File extractResource(URL resourceURL, File directoryOrFile,
790790
if (entry.isDirectory()) {
791791
file.mkdirs();
792792
} else if (!cacheDirectory || !file.exists() || file.length() != entrySize
793-
|| file.lastModified() != entryTimestamp || !file.equals(Loader.getCanonicalFile(file))) {
793+
|| file.lastModified() != entryTimestamp
794+
|| (canCreateSymbolicLink && !file.equals(Loader.getCanonicalFile(file)))) {
794795
// ... extract it from our resources ...
795796
file.delete();
796797
String s = resourceURL.toString();
@@ -937,14 +938,19 @@ public static URL[] findResources(Class cls, String name, int maxLength) throws
937938
static Map<String,URL[]> foundLibraries = new HashMap<String,URL[]>();
938939
/** Contains all the native libraries that we have loaded to avoid reloading them. */
939940
static Map<String,String> loadedLibraries = new HashMap<String,String>();
940-
/** Will be set to false when symbolic link creation fails, such as on Windows. */
941-
static boolean canCreateSymbolicLink = true;
942-
941+
/** Will be set to false when symbolic link creation fails, such as on Windows.
942+
* Set via "org.bytedeco.javacpp.canCreateSymbolicLink" system property, defaults to false on Windows only. */
943+
static boolean canCreateSymbolicLink = !WINDOWS;
944+
/** Default value for {@code load(..., pathsFirst)} set via "org.bytedeco.javacpp.pathsFirst" system property. */
943945
static boolean pathsFirst = false;
944946
static {
945947
String s = System.getProperty("org.bytedeco.javacpp.pathsfirst", "false").toLowerCase();
946948
s = System.getProperty("org.bytedeco.javacpp.pathsFirst", s).toLowerCase();
947949
pathsFirst = s.equals("true") || s.equals("t") || s.equals("");
950+
951+
s = System.getProperty("org.bytedeco.javacpp.cancreatesymboliclink", WINDOWS ? "false" : "true").toLowerCase();
952+
s = System.getProperty("org.bytedeco.javacpp.canCreateSymbolicLink", s).toLowerCase();
953+
canCreateSymbolicLink = s.equals("true") || s.equals("t") || s.equals("");
948954
}
949955

950956
/** Creates and returns {@code System.getProperty("org.bytedeco.javacpp.cachedir")} or {@code ~/.javacpp/cache/} when not set. */
@@ -959,7 +965,7 @@ public static File getCacheDir() throws IOException {
959965
File f = new File(dirName);
960966
try {
961967
if ((f.exists() || f.mkdirs()) && f.canRead() && f.canWrite() && f.canExecute()) {
962-
cacheDir = f;
968+
cacheDir = getCanonicalFile(f);
963969
break;
964970
}
965971
} catch (SecurityException e) {
@@ -1246,7 +1252,7 @@ public static String load(Class cls, Properties properties, boolean pathsFirst,
12461252

12471253
String cacheDir = null;
12481254
try {
1249-
cacheDir = Loader.getCanonicalPath(getCacheDir());
1255+
cacheDir = getCacheDir().toString();
12501256
} catch (IOException e) {
12511257
// no cache dir, no worries
12521258
}
@@ -1457,6 +1463,11 @@ public static URL[] findLibrary(Class cls, ClassProperties properties, String li
14571463
prefix + libname2 + version2 + suffix, // Mac OS X style
14581464
prefix + libname2 + suffix // without version
14591465
};
1466+
if (version.length() == 0 && version2.length() == 0) {
1467+
// optimize a bit for this case in particular on Windows
1468+
styles = new String[] { prefix + libname + suffix };
1469+
styles2 = new String[] { prefix + libname2 + suffix };
1470+
}
14601471

14611472
String[] suffixes = properties.get("platform.library.suffix").toArray(new String[0]);
14621473
if (suffixes.length > 1) {

0 commit comments

Comments
 (0)