55
55
import java .util .Set ;
56
56
import java .util .Map ;
57
57
import java .util .concurrent .ConcurrentHashMap ;
58
- import java .util .concurrent .ConcurrentLinkedQueue ;
59
58
import java .util .concurrent .ConcurrentSkipListMap ;
59
+ import java .util .concurrent .ConcurrentSkipListSet ;
60
60
import java .util .stream .Collectors ;
61
61
import java .util .stream .Stream ;
62
62
71
71
@ AutomaticallyRegisteredFeature
72
72
public final class DynamicAccessDetectionFeature implements InternalFeature {
73
73
74
+ // We use a ConcurrentSkipListMap, as opposed to a ConcurrentHashMap, to maintain
75
+ // order of methods by access kind.
74
76
public record MethodsByAccessKind (Map <DynamicAccessDetectionPhase .DynamicAccessKind , CallLocationsByMethod > methodsByAccessKind ) {
75
77
MethodsByAccessKind () {
76
78
this (new ConcurrentSkipListMap <>());
@@ -85,7 +87,9 @@ public CallLocationsByMethod getCallLocationsByMethod(DynamicAccessDetectionPhas
85
87
}
86
88
}
87
89
88
- public record CallLocationsByMethod (Map <String , ConcurrentLinkedQueue <String >> callLocationsByMethod ) {
90
+ // We use a ConcurrentSkipListSet, as opposed to a wrapped ConcurrentHashMap, to maintain
91
+ // order of call locations by method.
92
+ public record CallLocationsByMethod (Map <String , ConcurrentSkipListSet <String >> callLocationsByMethod ) {
89
93
CallLocationsByMethod () {
90
94
this (new ConcurrentSkipListMap <>());
91
95
}
@@ -94,8 +98,8 @@ public Set<String> getMethods() {
94
98
return callLocationsByMethod .keySet ();
95
99
}
96
100
97
- public ConcurrentLinkedQueue <String > getMethodCallLocations (String methodName ) {
98
- return callLocationsByMethod .getOrDefault (methodName , new ConcurrentLinkedQueue <>());
101
+ public ConcurrentSkipListSet <String > getMethodCallLocations (String methodName ) {
102
+ return callLocationsByMethod .getOrDefault (methodName , new ConcurrentSkipListSet <>());
99
103
}
100
104
}
101
105
@@ -136,7 +140,7 @@ public static DynamicAccessDetectionFeature instance() {
136
140
public void addCall (String entry , DynamicAccessDetectionPhase .DynamicAccessKind accessKind , String call , String callLocation ) {
137
141
MethodsByAccessKind entryContent = callsBySourceEntry .computeIfAbsent (entry , k -> new MethodsByAccessKind ());
138
142
CallLocationsByMethod methodCallLocations = entryContent .methodsByAccessKind ().computeIfAbsent (accessKind , k -> new CallLocationsByMethod ());
139
- ConcurrentLinkedQueue <String > callLocations = methodCallLocations .callLocationsByMethod ().computeIfAbsent (call , k -> new ConcurrentLinkedQueue <>());
143
+ ConcurrentSkipListSet <String > callLocations = methodCallLocations .callLocationsByMethod ().computeIfAbsent (call , k -> new ConcurrentSkipListSet <>());
140
144
callLocations .add (callLocation );
141
145
}
142
146
0 commit comments