Skip to content

Commit

Permalink
improve AnnotationInstance.hashCode()
Browse files Browse the repository at this point in the history
The `AnnotationInstance.equals()` method considers two annotations that are
basically the same as distinct if they don't have the same `target`. However,
the `AnnotationInstance.hashCode()` method does not take the `target` into
account at all, which leads to hash table collisions. This commit uses
the `AnnotationTarget` information to spread out the `AnnotationInstance`
hash code to make collisions less likely.
  • Loading branch information
Ladicek committed Sep 21, 2023
1 parent 171f61d commit 30be95d
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions core/src/main/java/org/jboss/jandex/AnnotationInstance.java
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,7 @@ public String toString() {
/**
* Returns whether this annotation instance is equal to another instance.
* Two annotation instances are equal if their names and values of their members are equal,
* and they share the exact same {@code AnnotationTarget} instance. The latter restriction
* may be softened in future versions.
* and they share the exact same {@code AnnotationTarget} instance.
*
* @param o the annotation instance to compare to
* @return {@code true} if equal, {@code false} if not
Expand Down Expand Up @@ -463,6 +462,36 @@ public int hashCode() {
int result = name.hashCode();
result = 31 * result + Arrays.hashCode(values);

if (target != null) {
switch (target.kind()) {
case CLASS:
result = 31 * result + target.asClass().name().hashCode();
break;
case METHOD:
result = 31 * result + target.asMethod().declaringClass().name().hashCode();
result = 31 * result + target.asMethod().name().hashCode();
break;
case FIELD:
result = 31 * result + target.asField().declaringClass().name().hashCode();
result = 31 * result + target.asField().name().hashCode();
break;
case METHOD_PARAMETER:
result = 31 * result + target.asMethodParameter().method().declaringClass().name().hashCode();
result = 31 * result + target.asMethodParameter().method().name().hashCode();
result = 31 * result + target.asMethodParameter().position();
break;
case RECORD_COMPONENT:
result = 31 * result + target.asRecordComponent().declaringClass().name().hashCode();
result = 31 * result + target.asRecordComponent().name().hashCode();
break;
case TYPE:
if (target.asType().target() != null) {
result = 31 * result + target.asType().target().name().hashCode();
}
break;
}
}

return result;
}

Expand Down

0 comments on commit 30be95d

Please sign in to comment.