Skip to content

Commit

Permalink
replace lists with arrays in Index
Browse files Browse the repository at this point in the history
  • Loading branch information
Ladicek committed Mar 27, 2024
1 parent f42f4a6 commit 6a416c4
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 54 deletions.
98 changes: 66 additions & 32 deletions src/main/java/org/jboss/jandex/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.jboss.jandex;

import static org.jboss.jandex.Utils.unfold;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
Expand Down Expand Up @@ -54,22 +56,22 @@ public final class Index implements IndexView {

static final DotName REPEATABLE = DotName.createSimple("java.lang.annotation.Repeatable");

final Map<DotName, List<AnnotationInstance>> annotations;
final Map<DotName, List<ClassInfo>> subclasses;
final Map<DotName, List<ClassInfo>> implementors;
final Map<DotName, AnnotationInstance[]> annotations;
final Map<DotName, ClassInfo[]> subclasses;
final Map<DotName, ClassInfo[]> implementors;
final Map<DotName, ClassInfo> classes;
final Map<DotName, ModuleInfo> modules;
final Map<DotName, List<ClassInfo>> users;

Index(Map<DotName, List<AnnotationInstance>> annotations, Map<DotName, List<ClassInfo>> subclasses,
Map<DotName, List<ClassInfo>> implementors, Map<DotName, ClassInfo> classes, Map<DotName, ModuleInfo> modules,
Map<DotName, List<ClassInfo>> users) {
this.annotations = Collections.unmodifiableMap(annotations);
this.classes = Collections.unmodifiableMap(classes);
this.subclasses = Collections.unmodifiableMap(subclasses);
this.implementors = Collections.unmodifiableMap(implementors);
this.modules = Collections.unmodifiableMap(modules);
this.users = Collections.unmodifiableMap(users);
final Map<DotName, ClassInfo[]> users;

Index(Map<DotName, AnnotationInstance[]> annotations, Map<DotName, ClassInfo[]> subclasses,
Map<DotName, ClassInfo[]> implementors, Map<DotName, ClassInfo> classes, Map<DotName, ModuleInfo> modules,
Map<DotName, ClassInfo[]> users) {
this.annotations = annotations;
this.classes = classes;
this.subclasses = subclasses;
this.implementors = implementors;
this.modules = modules;
this.users = users;
}


Expand All @@ -86,8 +88,37 @@ public final class Index implements IndexView {
* @return the index
*/
public static Index create(Map<DotName, List<AnnotationInstance>> annotations, Map<DotName, List<ClassInfo>> subclasses,
Map<DotName, List<ClassInfo>> implementors, Map<DotName, ClassInfo> classes) {
return new Index(annotations, subclasses, implementors, classes, Collections.<DotName, ModuleInfo>emptyMap(), Collections.<DotName, List<ClassInfo>>emptyMap());
Map<DotName, List<ClassInfo>> implementors, Map<DotName, ClassInfo> classes) {
return new Index(unfold(annotations, AnnotationInstance.class),
unfold(subclasses, ClassInfo.class),
unfold(implementors, ClassInfo.class),
classes,
Collections.<DotName, ModuleInfo>emptyMap(),
Collections.<DotName, ClassInfo[]>emptyMap());
}

/**
* Constructs a "mock" Index using the passed values. All passed values MUST NOT BE MODIFIED AFTER THIS CALL.
* Otherwise the resulting object would not conform to the contract outlined above. Also, to conform to the
* memory efficiency contract this method should be passed componentized DotNames, which all share common root
* instances. Of course for testing code this doesn't really matter.
*
* @param annotations A map to lookup annotation instances by class name
* @param subclasses A map to lookup subclasses by super class name
* @param implementors A map to lookup implementing classes by interface name
* @param classes A map to lookup classes by class name
* @param users A map to lookup class users
* @return the index
*/
public static Index create(Map<DotName, List<AnnotationInstance>> annotations, Map<DotName, List<ClassInfo>> subclasses,
Map<DotName, List<ClassInfo>> implementors, Map<DotName, ClassInfo> classes,
Map<DotName, List<ClassInfo>> users) {
return new Index(unfold(annotations, AnnotationInstance.class),
unfold(subclasses, ClassInfo.class),
unfold(implementors, ClassInfo.class),
classes,
Collections.<DotName, ModuleInfo>emptyMap(),
unfold(users, ClassInfo.class));
}

/**
Expand All @@ -100,13 +131,19 @@ public static Index create(Map<DotName, List<AnnotationInstance>> annotations, M
* @param subclasses A map to lookup subclasses by super class name
* @param implementors A map to lookup implementing classes by interface name
* @param classes A map to lookup classes by class name
* @param modules A map to lookup modules by name
* @param users A map to lookup class users
* @return the index
*/
public static Index create(Map<DotName, List<AnnotationInstance>> annotations, Map<DotName, List<ClassInfo>> subclasses,
Map<DotName, List<ClassInfo>> implementors, Map<DotName, ClassInfo> classes,
Map<DotName, List<ClassInfo>> users) {
return new Index(annotations, subclasses, implementors, classes, Collections.<DotName, ModuleInfo>emptyMap(), users);
Map<DotName, List<ClassInfo>> implementors, Map<DotName, ClassInfo> classes,
Map<DotName, ModuleInfo> modules, Map<DotName, List<ClassInfo>> users) {
return new Index(unfold(annotations, AnnotationInstance.class),
unfold(subclasses, ClassInfo.class),
unfold(implementors, ClassInfo.class),
classes,
modules,
unfold(users, ClassInfo.class));
}

/**
Expand Down Expand Up @@ -170,8 +207,8 @@ public boolean accept(File pathname) {
* {@inheritDoc}
*/
public List<AnnotationInstance> getAnnotations(DotName annotationName) {
List<AnnotationInstance> list = annotations.get(annotationName);
return list == null ? EMPTY_ANNOTATION_LIST: Collections.unmodifiableList(list);
AnnotationInstance[] list = annotations.get(annotationName);
return list == null ? EMPTY_ANNOTATION_LIST : new ImmutableArrayList<AnnotationInstance>(list);
}

/**
Expand Down Expand Up @@ -211,8 +248,8 @@ private Collection<AnnotationInstance> getRepeatableAnnotations(DotName annotati
* {@inheritDoc}
*/
public List<ClassInfo> getKnownDirectSubclasses(DotName className) {
List<ClassInfo> list = subclasses.get(className);
return list == null ? EMPTY_CLASSINFO_LIST : Collections.unmodifiableList(list);
ClassInfo[] list = subclasses.get(className);
return list == null ? EMPTY_CLASSINFO_LIST : new ImmutableArrayList<ClassInfo>(list);
}

@Override
Expand Down Expand Up @@ -253,8 +290,8 @@ private void getAllKnownSubClasses(DotName name, Set<ClassInfo> allKnown, Set<Do
* {@inheritDoc}
*/
public List<ClassInfo> getKnownDirectImplementors(DotName className) {
List<ClassInfo> list = implementors.get(className);
return list == null ? EMPTY_CLASSINFO_LIST : Collections.unmodifiableList(list);
ClassInfo[] list = implementors.get(className);
return list == null ? EMPTY_CLASSINFO_LIST : new ImmutableArrayList<ClassInfo>(list);
}

@Override
Expand Down Expand Up @@ -330,7 +367,7 @@ public ModuleInfo getModuleByName(DotName moduleName) {
public void printAnnotations()
{
System.out.println("Annotations:");
for (Map.Entry<DotName, List<AnnotationInstance>> e : annotations.entrySet()) {
for (Map.Entry<DotName, AnnotationInstance[]> e : annotations.entrySet()) {
System.out.println(e.getKey() + ":");
for (AnnotationInstance instance : e.getValue()) {
AnnotationTarget target = instance.target();
Expand Down Expand Up @@ -369,7 +406,7 @@ public void printAnnotations()
public void printSubclasses()
{
System.out.println("Subclasses:");
for (Map.Entry<DotName, List<ClassInfo>> entry : subclasses.entrySet()) {
for (Map.Entry<DotName, ClassInfo[]> entry : subclasses.entrySet()) {
System.out.println(entry.getKey() + ":");
for (ClassInfo clazz : entry.getValue())
System.out.println(" " + clazz.name());
Expand All @@ -381,10 +418,7 @@ public void printSubclasses()
*/
@Override
public List<ClassInfo> getKnownUsers(DotName className) {
List<ClassInfo> ret = users.get(className);
if (ret == null) {
return EMPTY_CLASSINFO_LIST;
}
return Collections.unmodifiableList(ret);
ClassInfo[] result = users.get(className);
return result != null ? new ImmutableArrayList<ClassInfo>(result) : EMPTY_CLASSINFO_LIST;
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/jboss/jandex/IndexReaderV2.java
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ private Index readClasses(PackedDataInputStream stream,
Map<DotName, ModuleInfo> modules = (version >= 10) ?
readModules(stream, masterAnnotations, version) : Collections.<DotName, ModuleInfo>emptyMap();

return new Index(masterAnnotations, subclasses, implementors, classes, modules, users);
return Index.create(masterAnnotations, subclasses, implementors, classes, modules, users);
}

private Map<DotName, ModuleInfo> readModules(PackedDataInputStream stream,
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/org/jboss/jandex/IndexWriterV2.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,16 +228,15 @@ int write(Index index, int version) throws IOException {
return stream.size();
}

private void writeUsersTable(PackedDataOutputStream stream, Map<DotName, List<ClassInfo>> users) throws IOException {
for (Entry<DotName, List<ClassInfo>> entry : users.entrySet()) {
private void writeUsersTable(PackedDataOutputStream stream, Map<DotName, ClassInfo[]> users) throws IOException {
for (Entry<DotName, ClassInfo[]> entry : users.entrySet()) {
writeUsersSet(stream, entry.getKey(), entry.getValue());
}
}


private void writeUsersSet(PackedDataOutputStream stream, DotName user, List<ClassInfo> uses) throws IOException {
private void writeUsersSet(PackedDataOutputStream stream, DotName user, ClassInfo[] uses) throws IOException {
stream.writePackedU32(positionOf(user));
stream.writePackedU32(uses.size());
stream.writePackedU32(uses.length);
for (ClassInfo use : uses) {
stream.writePackedU32(positionOf(use.name()));
}
Expand Down Expand Up @@ -848,7 +847,7 @@ private void buildTables(Index index, int version) {
}

if (index.users != null) {
for (Entry<DotName, List<ClassInfo>> entry : index.users.entrySet()) {
for (Entry<DotName, ClassInfo[]> entry : index.users.entrySet()) {
addClassName(entry.getKey());
for (ClassInfo classInfo : entry.getValue()) {
addClassName(classInfo.name());
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jboss/jandex/Indexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2029,7 +2029,7 @@ public ClassInfo index(InputStream stream) throws IOException {
public Index complete() {
initIndexMaps();
try {
return new Index(masterAnnotations, subclasses, implementors, classes, modules, users);
return Index.create(masterAnnotations, subclasses, implementors, classes, modules, users);
} finally {
masterAnnotations = null;
subclasses = null;
Expand Down
9 changes: 4 additions & 5 deletions src/main/java/org/jboss/jandex/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package org.jboss.jandex;

import java.io.File;
import java.util.List;

/**
* The result from a jar indexing operation.
Expand All @@ -44,8 +43,8 @@ public final class Result {
instances = countInstances(index);
classes = index.classes.size();
int usages = 0;
for (List<ClassInfo> usagesForOneClass : index.users.values()) {
usages += usagesForOneClass.size();
for (ClassInfo[] usagesForOneClass : index.users.values()) {
usages += usagesForOneClass.length;
}
this.usages = usages;
this.bytes = bytes;
Expand All @@ -55,8 +54,8 @@ public final class Result {

private int countInstances(Index index) {
int c = 0;
for (List<AnnotationInstance> list : index.annotations.values())
c += list.size();
for (AnnotationInstance[] list : index.annotations.values())
c += list.length;

return c;
}
Expand Down
24 changes: 15 additions & 9 deletions src/main/java/org/jboss/jandex/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@

package org.jboss.jandex;

import java.lang.reflect.Array;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand All @@ -41,16 +43,20 @@ static String fromUTF8(byte[] bytes) {
return new String(bytes, UTF8);
}

static <T> List<T> emptyOrWrap(List<T> list) {
return list.size() == 0 ? Collections.<T>emptyList() : Collections.unmodifiableList(list);
}

static <T> Collection<T> emptyOrWrap(Collection<T> list) {
return list.size() == 0 ? Collections.<T>emptyList() : Collections.unmodifiableCollection(list);
}
static <K, V> Map<K, V[]> unfold(Map<K, List<V>> map, Class<V> listElementType) {
if (map == null) {
return null;
}
if (map.isEmpty()) {
return Collections.emptyMap();
}

static <K, V> Map<K, V> emptyOrWrap(Map<K, V> map) {
return map.size() == 0 ? Collections.<K, V>emptyMap() : Collections.unmodifiableMap(map);
Map<K, V[]> result = new HashMap<K, V[]>();
for (Map.Entry<K, List<V>> entry : map.entrySet()) {
V[] array = (V[]) Array.newInstance(listElementType, entry.getValue().size());
result.put(entry.getKey(), entry.getValue().toArray(array));
}
return result;
}

static <T> List<T> listOfCapacity(int capacity) {
Expand Down

0 comments on commit 6a416c4

Please sign in to comment.