package org.jetbrains.plugins.textmate.language.syntax.selector;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ExecutionException;

public class TextMateSelectorCachingWeigher implements TextMateSelectorWeigher {
  @NotNull private final TextMateSelectorWeigher myOriginalWeigher;
  @NotNull private final Cache<String, TextMateWeigh> myCache = CacheBuilder.newBuilder()
    .initialCapacity(100).maximumSize(200).build();

  private static final Logger LOG = Logger.getInstance(TextMateSelectorCachingWeigher.class);

  public TextMateSelectorCachingWeigher(@NotNull TextMateSelectorWeigher originalWeigher) {
    myOriginalWeigher = originalWeigher;
  }

  @Override
  public TextMateWeigh weigh(@NotNull final CharSequence scopeSelector, @NotNull final CharSequence scope) {
    try {
      return myCache.get(createCacheKey(scopeSelector, scope), () -> myOriginalWeigher.weigh(scopeSelector, scope));
    }
    catch (ExecutionException e) {
      LOG.error("Can't perform lazy weigh for textmate selectors", e);
      return myOriginalWeigher.weigh(scopeSelector, scope);
    }
  }

  private static String createCacheKey(CharSequence highlightingRule, CharSequence targetSelector) {
    return highlightingRule + ";" + targetSelector;
  }
}

@@ -95,16 +95,23 @@
 he.Cache
+Builder
 ;%0Aimport
@@ -132,39 +132,83 @@
 mmon.cache.Cache
-Builder
+Loader;%0Aimport com.google.common.cache.LoadingCache
 ;%0Aimport com.int
@@ -236,24 +236,63 @@
 tic.Logger;%0A
+import com.intellij.openapi.util.Pair;%0A
 import org.j
@@ -369,16 +369,54 @@
 ception;
+%0Aimport java.util.concurrent.TimeUnit;
 %0A%0Apublic
@@ -496,73 +496,100 @@
 %7B%0A  
-@NotNull private final TextMateSelectorWeigher myOriginalWeigher;
+private static final Logger LOG = Logger.getInstance(TextMateSelectorCachingWeigher.class);%0A
 %0A  @
@@ -614,30 +614,16 @@
 nal 
-Cache%3CString, 
 TextMate
 Weig
@@ -622,105 +622,53 @@
 Mate
+Selector
 Weigh
-%3E myCache = CacheBuilder.newBuilder()%0A    .initialCapacity(100).maximumSize(200).build();%0A%0A 
+er myOriginalWeigher;%0A  @NotNull
  pri
@@ -668,39 +668,32 @@
 ull private 
-static 
 final Lo
 gger LOG = L
@@ -684,75 +684,75 @@
 l Lo
-gger LOG = Logger.getInstance(TextMateSelectorCachingWeigher.class)
+adingCache%3CPair%3CCharSequence, CharSequence%3E, TextMateWeigh%3E myCache
 ;%0A%0A 
@@ -883,16 +883,252 @@
 eigher;%0A
+    myCache = CacheBuilder.newBuilder().maximumSize(200).expireAfterWrite(1, TimeUnit.MINUTES).build(CacheLoader.from(pair -%3E %7B%0A      return pair != null ? myOriginalWeigher.weigh(pair.first, pair.second) : TextMateWeigh.ZERO;%0A    %7D));%0A
   %7D%0A%0A  @
@@ -1284,75 +1284,19 @@
 get(
+Pair.
 create
-CacheKey(scopeSelector, scope), () -%3E myOriginalWeigher.weigh
 (sco
@@ -1501,165 +1501,7 @@
 %0A  %7D
-%0A%0A  private static String createCacheKey(CharSequence highlightingRule, CharSequence targetSelector) %7B%0A    return highlightingRule + %22;%22 + targetSelector;%0A  %7D
 %0A%7D%0A

use loading cache to avoid creating many lambdas