1616import java .nio .file .Files ;
1717import java .nio .file .Path ;
1818import java .util .*;
19+ import java .util .concurrent .ConcurrentHashMap ;
1920import java .util .function .Function ;
2021import java .util .stream .Stream ;
2122
2425 */
2526public class PackResourcesCacheEngine {
2627 private static final Joiner SLASH_JOINER = Joiner .on ('/' );
28+ private static final ConcurrentHashMap <String , String > PATH_COMPONENT_INTERNER = new ConcurrentHashMap <>();
29+ private static final ConcurrentHashMap <String , String []> CACHED_SPLIT_PATHS = new ConcurrentHashMap <>();
2730
2831 static class Node {
2932 Map <String , Node > children ;
@@ -100,7 +103,6 @@ public PackResourcesCacheEngine(Function<PackType, Path> basePathRetriever) {
100103 // used for log message
101104 this .debugPath = basePathRetriever .apply (PackType .CLIENT_RESOURCES ).toAbsolutePath ();
102105 this .root .children = new Object2ObjectOpenHashMap <>();
103- ObjectOpenHashSet <String > pathKeys = new ObjectOpenHashSet <>();
104106 for (PackType type : PackType .values ()) {
105107 var typeRoot = new Node ();
106108 this .root .children .put (type .getDirectory (), typeRoot );
@@ -114,8 +116,12 @@ public PackResourcesCacheEngine(Function<PackType, Path> basePathRetriever) {
114116 .filter (PackResourcesCacheEngine ::isValidCachedResourcePath )
115117 .forEach (path -> {
116118 var node = typeRoot ;
117- for (Path component : path ) {
118- String key = pathKeys .addOrGet (component .toString ());
119+ int nameCount = path .getNameCount ();
120+ for (int i = 0 ; i < nameCount ; i ++) {
121+ String key = path .getName (i ).toString ();
122+ if (i < (nameCount - 1 )) {
123+ key = PATH_COMPONENT_INTERNER .computeIfAbsent (key , Function .identity ());
124+ }
119125 if (node .children == null ) {
120126 node .children = new Object2ObjectOpenHashMap <>();
121127 }
@@ -205,4 +211,16 @@ public void collectResources(PackType type, String resourceNamespace, String[] c
205211 }
206212 node .collectResources (resourceNamespace , this .rootPathsByType .get (type ).resolve (resourceNamespace ), components , 0 , maxDepth , output );
207213 }
214+
215+ private static String [] decompose (String path ) {
216+ String [] components = path .split ("/" );
217+ for (int i = 0 ; i < components .length ; i ++) {
218+ components [i ] = PATH_COMPONENT_INTERNER .computeIfAbsent (components [i ], Function .identity ());
219+ }
220+ return components ;
221+ }
222+
223+ public static String [] decomposeCached (String path ) {
224+ return CACHED_SPLIT_PATHS .computeIfAbsent (path , PackResourcesCacheEngine ::decompose );
225+ }
208226}
0 commit comments