Skip to content

Commit 92acb20

Browse files
authored
Merge pull request #1 from cl4es/bitset_versions
Use BitSet to streamline construction
2 parents 826d78a + 34fa9ed commit 92acb20

File tree

3 files changed

+21
-39
lines changed

3 files changed

+21
-39
lines changed

src/java.base/share/classes/java/util/jar/JarFile.java

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.lang.ref.SoftReference;
4141
import java.security.CodeSigner;
4242
import java.security.cert.Certificate;
43+
import java.util.BitSet;
4344
import java.util.Enumeration;
4445
import java.util.List;
4546
import java.util.Objects;
@@ -597,26 +598,16 @@ private String getBasename(String name) {
597598
}
598599

599600
private JarEntry getVersionedEntry(String name, JarEntry defaultEntry) {
600-
if (!name.startsWith(META_INF)) {
601-
int[] versions = JUZFA.getMetaInfVersions(this, name);
602-
if (BASE_VERSION_FEATURE < versionFeature && versions.length > 0) {
603-
// search for versioned entry
604-
for (int i = versions.length - 1; i >= 0; i--) {
605-
int version = versions[i];
606-
// skip versions above versionFeature
607-
if (version > versionFeature) {
608-
continue;
609-
}
610-
// skip versions below base version
611-
if (version < BASE_VERSION_FEATURE) {
612-
break;
613-
}
614-
JarFileEntry vje = (JarFileEntry)super.getEntry(
615-
META_INF_VERSIONS + version + "/" + name);
616-
if (vje != null) {
617-
return vje.withBasename(name);
618-
}
601+
if (BASE_VERSION_FEATURE < versionFeature && !name.startsWith(META_INF)) {
602+
BitSet versions = JUZFA.getMetaInfVersions(this, name);
603+
int version = versions.previousSetBit(versionFeature);
604+
while (version >= BASE_VERSION_FEATURE) {
605+
JarFileEntry vje = (JarFileEntry)super.getEntry(
606+
META_INF_VERSIONS + version + "/" + name);
607+
if (vje != null) {
608+
return vje.withBasename(name);
619609
}
610+
version = versions.previousSetBit(version - 1);
620611
}
621612
}
622613
return defaultEntry;

src/java.base/share/classes/java/util/zip/ZipFile.java

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,13 +1081,15 @@ private String getManifestName(boolean onlyIfSignatureRelatedFiles) {
10811081
* optimization when looking up potentially versioned entries.
10821082
* Returns an empty array if no versioned entries exist.
10831083
*/
1084-
private int[] getMetaInfVersions(String name) {
1084+
private BitSet getMetaInfVersions(String name) {
10851085
synchronized (this) {
10861086
ensureOpen();
1087-
return res.zsrc.metaVersions.getOrDefault(name, Source.EMPTY_META_VERSIONS);
1087+
return res.zsrc.metaVersions.getOrDefault(name, EMPTY_VERSIONS);
10881088
}
10891089
}
10901090

1091+
private static final BitSet EMPTY_VERSIONS = new BitSet();
1092+
10911093
/**
10921094
* Returns the value of the System property which indicates whether the
10931095
* Extra ZIP64 validation should be disabled.
@@ -1124,7 +1126,7 @@ public String getManifestName(JarFile jar, boolean onlyIfHasSignatureRelatedFile
11241126
return ((ZipFile)jar).getManifestName(onlyIfHasSignatureRelatedFiles);
11251127
}
11261128
@Override
1127-
public int[] getMetaInfVersions(JarFile jar, String name) {
1129+
public BitSet getMetaInfVersions(JarFile jar, String name) {
11281130
return ((ZipFile)jar).getMetaInfVersions(name);
11291131
}
11301132
@Override
@@ -1162,7 +1164,6 @@ private static class Source {
11621164
private static final int META_INF_LEN = 9;
11631165
// "META-INF/versions//".length()
11641166
private static final int META_INF_VERSIONS_LEN = 19;
1165-
private static final int[] EMPTY_META_VERSIONS = new int[0];
11661167
// CEN size is limited to the maximum array size in the JDK
11671168
private static final int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH;
11681169

@@ -1179,7 +1180,7 @@ private static class Source {
11791180
private int manifestPos = -1; // position of the META-INF/MANIFEST.MF, if exists
11801181
private int manifestNum = 0; // number of META-INF/MANIFEST.MF, case insensitive
11811182
private int[] signatureMetaNames; // positions of signature related entries, if such exist
1182-
private Map<String, int[]> metaVersions; // Set of versions found in META-INF/versions/, by entry name
1183+
private Map<String, BitSet> metaVersions; // Set of versions found in META-INF/versions/, by entry name
11831184
private final boolean startsWithLoc; // true, if ZIP file starts with LOCSIG (usually true)
11841185

11851186
// A Hashmap for all entries.
@@ -1745,7 +1746,7 @@ private void initCEN(int knownTotal) throws IOException {
17451746
ArrayList<Integer> signatureNames = null;
17461747
// Map entry name to the set of versions seen in
17471748
// META-INF/versions/{version}/{name}
1748-
Map<String, Set<Integer>> metaVersionsMap = null;
1749+
Map<String, BitSet> metaVersionsMap = null;
17491750

17501751
// Iterate through the entries in the central directory
17511752
int idx = 0; // Index into the entries array
@@ -1790,7 +1791,7 @@ private void initCEN(int knownTotal) throws IOException {
17901791
// Add version for name
17911792
if (metaVersionsMap == null)
17921793
metaVersionsMap = new HashMap<>();
1793-
metaVersionsMap.computeIfAbsent(name, n -> new HashSet<>()).add(version);
1794+
metaVersionsMap.computeIfAbsent(name, _ -> new BitSet()).set(version);
17941795
}
17951796
}
17961797
}
@@ -1809,18 +1810,7 @@ private void initCEN(int knownTotal) throws IOException {
18091810
}
18101811
}
18111812
if (metaVersionsMap != null) {
1812-
metaVersions = new HashMap<>();
1813-
for (var entry : metaVersionsMap.entrySet()) {
1814-
// Convert Set<Integer> to int[] for performance
1815-
int[] versions = new int[entry.getValue().size()];
1816-
int c = 0;
1817-
for (Integer i : entry.getValue()) {
1818-
versions[c++] = i.intValue();
1819-
}
1820-
// JarFile::getVersionedEntry expects sorted versions
1821-
Arrays.sort(versions);
1822-
metaVersions.put(entry.getKey(), versions);
1823-
}
1813+
metaVersions = metaVersionsMap;
18241814
} else {
18251815
metaVersions = Map.of();
18261816
}

src/java.base/share/classes/jdk/internal/access/JavaUtilZipFileAccess.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
package jdk.internal.access;
2727

28+
import java.util.BitSet;
2829
import java.util.Enumeration;
2930
import java.util.List;
3031
import java.util.jar.JarEntry;
@@ -38,7 +39,7 @@ public interface JavaUtilZipFileAccess {
3839
public List<String> getManifestAndSignatureRelatedFiles(JarFile zip);
3940
public String getManifestName(JarFile zip, boolean onlyIfSignatureRelatedFiles);
4041
public int getManifestNum(JarFile zip);
41-
public int[] getMetaInfVersions(JarFile zip, String name);
42+
public BitSet getMetaInfVersions(JarFile zip, String name);
4243
public Enumeration<JarEntry> entries(ZipFile zip);
4344
public Stream<JarEntry> stream(ZipFile zip);
4445
public Stream<String> entryNameStream(ZipFile zip);

0 commit comments

Comments
 (0)