10000 introduce a cache for container compiling · Koc/idea-php-symfony2-plugin@52ee131 · GitHub
[go: up one dir, main page]

Skip to content

Commit 52ee131

Browse files
committed
introduce a cache for container compiling
1 parent e158e49 commit 52ee131

File tree

1 file changed

+97
-41
lines changed

1 file changed

+97
-41
lines changed

src/fr/adrienbrault/idea/symfony2plugin/stubs/ContainerCollectionResolver.java

Lines changed: 97 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import com.intellij.openapi.util.Key;
66
import com.intellij.psi.search.GlobalSearchScope;
77
import com.intellij.psi.util.CachedValue;
8+
import com.intellij.psi.util.CachedValueProvider;
9+
import com.intellij.psi.util.CachedValuesManager;
10+
import com.intellij.psi.util.PsiModificationTracker;
811
import com.intellij.util.indexing.FileBasedIndexImpl;
912
import fr.adrienbrault.idea.symfony2plugin.config.component.parser.ParameterServiceParser;
1013
import fr.adrienbrault.idea.symfony2plugin.dic.ContainerParameter;
@@ -33,6 +36,12 @@ public class ContainerCollectionResolver {
3336
private static final Key<CachedValue<Set<String>>> SERVICE_CONTAINER_INDEX_NAMES = new Key<>("SYMFONY_SERVICE_CONTAINER_INDEX_NAMES");
3437
private static final Key<CachedValue<Set<String>>> SERVICE_PARAMETER_INDEX_NAMES = new Key<>("SERVICE_PARAMETER_INDEX_NAMES");
3538

39+
private static final Key<CachedValue<Map<String, ContainerService>>> CONTAINER_SERVICES = new Key<>("CONTAINER_SERVICES");
40+
private static final Key<CachedValue<Set<String>>> CONTAINER_SERVICE_NAMES = new Key<>("CONTAINER_SERVICE_NAMES");
41+
42+
private static final Key<CachedValue<Map<String, ContainerParameter>>> CONTAINER_PARAMETERS = new Key<>("CONTAINER_PARAMETERS");
43+
private static final Key<CachedValue<Set<String>>> CONTAINER_PARAMETER_NAMES = new Key<>("CONTAINER_PARAMETER_NAMES");
44+
3645
private static final ExtensionPointName<fr.adrienbrault.idea.symfony2plugin.extension.ServiceCollector> EXTENSIONS = new ExtensionPointName<>(
3746
"fr.adrienbrault.idea.symfony2plugin.extension.ServiceCollector"
3847
);
@@ -155,17 +164,34 @@ public String resolve(String serviceName) {
155164
return null;
156165
}
157166

167+
/**
168+
* Main container is stateless so cache possible
169+
*/
170+
@NotNull
158171
public Map<String, ContainerService> getServices() {
159-
160172
if(this.services != null) {
161173
return this.services;
162174
}
163175

164-
this.services = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
176+
CachedValue<Map<String, ContainerService>> cache = project.getUserData(CONTAINER_SERVICES);
177+
if (cache == null) {
178+
cache = CachedValuesManager.getManager(project).createCachedValue(() ->
179+
CachedValueProvider.Result.create(getServicesDecorated(), PsiModificationTracker.MODIFICATION_COUNT),
180+
false
181+
);
182+
project.putUserData(CONTAINER_SERVICES, cache);
183+
}
184+
185+
return this.services = cache.getValue();
186+
}
187+
188+
@NotNull
189+
private Map<String, ContainerService> getServicesDecorated() {
190+
Map<String, ContainerService> serviceMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
165191

166192
// file system
167193
for(Map.Entry<String, String> entry: ServiceXmlParserFactory.getInstance(project, XmlServiceParser.class).getServiceMap().getMap().entrySet()) {
168-
services.put(entry.getKey(), new ContainerService(entry.getKey(), entry.getValue()));
194+
serviceMap.put(entry.getKey(), new ContainerService(entry.getKey(), entry.getValue()));
169195
}
170196

171197
Collection<ServiceInterface> aliases = new ArrayList<>();
@@ -183,7 +209,7 @@ public Map<String, ContainerService> getServices() {
183209
}
184210

185211
if(exps.size() > 0) {
186-
exps.forEach(service -> services.put(service.getId(), new ContainerService(service, null)));
212+
exps.forEach(service -> serviceMap.put(service.getId(), new ContainerService(service, null)));
187213
}
188214

189215
for (Map.Entry<String, List<ServiceSerializable>> entry : FileIndexCaches.getSetDataCache(project, SERVICE_CONTAINER_INDEX, SERVICE_CONTAINER_INDEX_NAMES, ServicesDefinitionStubIndex.KEY, ServiceIndexUtil.getRestrictedFileTypesScope(project)).entrySet()) {
@@ -195,27 +221,27 @@ public Map<String, ContainerService> getServices() {
195221
// fake empty service, case which is not allowed by catch it
196222
List<ServiceSerializable> services = entry.getValue();
197223
if(services.size() == 0) {
F438 198-
this.services.put(serviceName, new ContainerService(serviceName, null, true));
224+
serviceMap.put(serviceName, new ContainerService(serviceName, null, true));
199225
continue;
200226
}
201227

202228
for(ServiceInterface service: services) {
203229
String classValue = service.getClassName();
204230

205231
// duplicate services
206-
if(this.services.containsKey(serviceName)) {
232+
if(serviceMap.containsKey(serviceName)) {
207233
if(classValue == null) {
208234
continue;
209235
}
210236

211-
String compiledClassName = this.services.get(serviceName).getClassName();
237+
String compiledClassName = serviceMap.get(serviceName).getClassName();
212238
if(classValue.equalsIgnoreCase(compiledClassName)) {
213239
continue;
214240
}
215241

216242
String resolvedClassValue = getParameterCollector().resolve(classValue);
217243
if(resolvedClassValue != null && !StringUtils.isBlank(classValue) && !resolvedClassValue.equalsIgnoreCase(compiledClassName)) {
218-
this.services.get(serviceName).addClassName(resolvedClassValue);
244+
serviceMap.get(serviceName).addClassName(resolvedClassValue);
219245
}
220246

221247
continue;
@@ -236,43 +262,43 @@ public Map<String, ContainerService> getServices() {
236262
}
237263

238264
// @TODO: legacy bridge; replace this with ServiceInterface
239-
this.services.put(serviceName, new ContainerService(service, classValue));
265+
serviceMap.put(serviceName, new ContainerService(service, classValue));
240266
}
241267
}
242268

243269
// replace alias with main service
244270
if(aliases.size() > 0) {
245-
collectAliases(aliases);
271+
collectAliases(serviceMap, aliases);
246272
}
247273

248274
if(decorated.size() > 0) {
249-
collectDecorated(decorated);
275+
collectDecorated(serviceMap, decorated);
250276
}
251277

252-
return this.services;
278+
return serviceMap;
253279
}
254280

255-
private void collectAliases(@NotNull Collection<ServiceInterface> aliases) {
281+
private void collectAliases(@NotNull Map<String, ContainerService> services, @NotNull Collection<ServiceInterface> aliases) {
256282
for (ServiceInterface service : aliases) {
257283

258284
// double check alias name
259285
String alias = service.getAlias();
260-
if(alias == null || StringUtils.isBlank(alias) || !this.services.containsKey(alias)) {
286+
if(alias == null || StringUtils.isBlank(alias) || !services.containsKey(alias)) {
261287
continue;
262288
}
263289

264-
this.services.put(service.getId(), this.services.get(alias));
290+
services.put(service.getId(), services.get(alias));
265291
}
266292
}
267293

268-
private void collectDecorated(@NotNull Collection<ServiceInterface> decorated) {
294+
private void collectDecorated(@NotNull Map<String, ContainerService> services, @NotNull Collection<ServiceInterface> decorated) {
269295
for (ServiceInterface service : decorated) {
270296
String decorationInnerName = service.getDecorationInnerName();
271297
if(StringUtils.isBlank(decorationInnerName)) {
272298
decorationInnerName = service.getId() + ".inner";
273299
}
274300

275-
ContainerService origin = this.services.get(service.getDecorates());
301+
ContainerService origin = services.get(service.getDecorates());
276302
if(origin == null) {
277303
continue;
278304
}
@@ -281,7 +307,7 @@ private void collectDecorated(@NotNull Collection<ServiceInterface> decorated) {
281307
ContainerService value = new ContainerService(decorationInnerName, origin.getClassName(), origin.isWeak(), origin.isPrivate());
282308
origin.getClassNames().forEach(value::addClassName);
283309

284-
this.services.put(decorationInnerName, value);
310+
services.put(decorationInnerName, value);
285311
}
286312
}
287313

@@ -305,8 +331,22 @@ public Set<String> convertClassNameToServices(@NotNull String fqnClassName) {
305331
return serviceNames;
306332
}
307333

334+
@NotNull
308335
private Set<String> getNames() {
336+
CachedValue<Set<String>> cache = project.getUserData(CONTAINER_SERVICE_NAMES);
337+
if (cache == null) {
338+
cache = CachedValuesManager.getManager(project).createCachedValue(() ->
339+
CachedValueProvider.Result.create(getNamesDecorated(), PsiModificationTracker.MODIFICATION_COUNT),
340+
false
341+
);
342+
project.putUserData(CONTAINER_SERVICE_NAMES, cache);
343+
}
344+
345+
return cache.getValue();
346+
}
309347

348+
@NotNull
349+
private Set<String> getNamesDecorated() {
310350
Set<String> serviceNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
311351

312352
// local filesystem
@@ -328,10 +368,8 @@ private Set<String> getNames() {
328368
);
329369

330370
return serviceNames;
331-
332371
}
333372

334-
335373
private ParameterCollector getParameterCollector() {
336374
return (this.parameterCollector != null) ? this.parameterCollector : (this.parameterCollector = ParameterCollector.create(this.project));
337375
}
@@ -364,14 +402,12 @@ public static ParameterCollector create(@NotNull Project project) {
364402
*/
365403
@Nullable
366404
private String resolve(@Nullable String paramOrClassName) {
367-
368405
if(paramOrClassName == null) {
369406
return null;
370407
}
371408

372409
// strip "%" to get the parameter name
373410
if(paramOrClassName.length() > 1 && paramOrClassName.startsWith("%") && paramOrClassName.endsWith("%")) {
374-
375411
paramOrClassName = paramOrClassName.substring(1, paramOrClassName.length() - 1);
376412

377413
// parameter is always lower see #179
@@ -387,38 +423,50 @@ private String resolve(@Nullable String paramOrClassName) {
387423
return paramOrClassName;
388424
}
389425

390-
426+
@NotNull
391427
private Map<String, ContainerParameter> getParameters() {
392-
393428
if(this.containerParameterMap != null) {
394429
return this.containerParameterMap;
395430
}
396431

397-
this.containerParameterMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
432+
CachedValue<Map<String, ContainerParameter>> cache = project.getUserData(CONTAINER_PARAMETERS);
433+
if (cache == null) {
434+
cache = CachedValuesManager.getManager(project).createCachedValue(() ->
435+
CachedValueProvider.Result.create(getParametersDecorated(), PsiModificationTracker.MODIFICATION_COUNT),
436+
false
437+
);
438+
project.putUserData(CONTAINER_PARAMETERS, cache);
439+
}
440+
441+
return this.containerParameterMap = cache.getValue();
442+
}
398443

444+
@NotNull
445+
private Map<String, ContainerParameter> getParametersDecorated() {
446+
Map<String, ContainerParameter> parametersTree = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
399447

400448
// local filesystem
401449
for(Map.Entry<String, String> Entry: ServiceXmlParserFactory.getInstance(project, ParameterServiceParser.class).getParameterMap().entrySet()) {
402-
403450
// user input here; secure nullable values
404451
String key = Entry.getKey();
452+
405453
if(key != null) {
406-
this.containerParameterMap.put(key, new ContainerParameter(key, Entry.getValue()));
454+
parametersTree.put(key, new ContainerParameter(key, Entry.getValue()));
407455
}
408-
409456
}
410457

411458
// index
412459
for (Map.Entry<String, List<String>> entry : FileIndexCaches.getStringDataCache(project, SERVICE_PARAMETER_INDEX, SERVICE_PARAMETER_INDEX_NAMES, ContainerParameterStubIndex.KEY, ServiceIndexUtil.getRestrictedFileTypesScope(project)).entrySet()) {
413460
String parameterName = entry.getKey();
461+
414462
// just for secure
415463
if(parameterName == null) {
416464
continue;
417465
}
418466

419467
// indexes is weak stuff, dont overwrite compiled ones
420-
if(!this.containerParameterMap.containsKey(parameterName)) {
421-
this.containerParameterMap.put(parameterName, new ContainerParameter(parameterName, entry.getValue(), true));
468+
if(!parametersTree.containsKey(parameterName)) {
469+
parametersTree.put(parameterName, new ContainerParameter(parameterName, entry.getValue(), true));
422470
}
423471
}
424472

@@ -430,28 +478,39 @@ private Map<String, ContainerParameter> getParameters() {
430478
}
431479

432480
for (String parameter : parameters) {
433-
if(this.containerParameterMap.containsKey(parameter)) {
481+
if(parametersTree.containsKey(parameter)) {
434482
continue;
435483
}
436484

437-
this.containerParameterMap.put(parameter, new ContainerParameter(parameter, true));
485+
parametersTree.put(parameter, new ContainerParameter(parameter, true));
438486
}
439-
440487
}
441488

442-
443-
444-
return this.containerParameterMap;
445-
489+
return parametersTree;
446490
}
447491

492+
@NotNull
448493
private Set<String> getNames() {
449-
450494
// use overall map if already generated
451495
if(this.containerParameterMap != null) {
452496
return this.containerParameterMap.keySet();
453497
}
454498

499+
CachedValue<Set<String>> cache = project.getUserData(CONTAINER_PARAMETER_NAMES);
500+
if (cache == null) {
501+
cache = CachedValuesManager.getManager(project).createCachedValue(() ->
502+
CachedValueProvider.Result.create(getNamesDecorated(), PsiModificationTracker.MODIFICATION_COUNT),
503+
false
504+
);
505+
506+
project.putUserData(CONTAINER_PARAMETER_NAMES, cache);
507+
}
508+
509+
return cache.getValue();
510+
}
511+
512+
@NotNull
513+
private Set<String> getNamesDecorated() {
455514
Set<String> parameterNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
456515

457516
// local filesystem
@@ -470,10 +529,7 @@ private Set<String> getNames() {
470529
}
471530
}
472531

473-
474532
return parameterNames;
475533
}
476-
477534
}
478-
479535
}

0 commit comments

Comments
 (0)
0