From 1d11180d63e927edcd3b7b7834e8bd50f1174e6e Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 23 Mar 2011 15:18:00 +0100 Subject: [PATCH] simpler mayCacheNoew implementation --- .../openapi/util/RecursionManager.java | 70 ++++++++----------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/util/RecursionManager.java b/platform/platform-api/src/com/intellij/openapi/util/RecursionManager.java index d7bcb4ab7039..ceb38c14b88f 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/RecursionManager.java +++ b/platform/platform-api/src/com/intellij/openapi/util/RecursionManager.java @@ -15,81 +15,71 @@ */ package com.intellij.openapi.util; -import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.Set; +import java.util.Map; /** * @author peter */ @SuppressWarnings({"UtilityClassWithoutPrivateConstructor"}) public class RecursionManager { - private static final ThreadLocal ourRecursionsMet = new ThreadLocal(); - private static final ThreadLocal>> ourProgress = new ThreadLocal>>(); - private static final ThreadLocal> ourNoCache = new ThreadLocal>(); + private static final ThreadLocal ourStamp = new ThreadLocal() { + @Override + protected Integer initialValue() { + return 0; + } + }; + private static final ThreadLocal> ourProgress = new ThreadLocal>() { + @Override + protected LinkedHashMap initialValue() { + return new LinkedHashMap(); + } + }; public static RecursionGuard createGuard(final String id) { return new RecursionGuard() { @Override public T doPreventingRecursion(Object key, Computable computation) { Object realKey = Pair.create(id, key); - LinkedHashMap> progressMap = ourProgress.get(); - if (progressMap == null) { - ourProgress.set(progressMap = new LinkedHashMap>()); - } - else if (progressMap.containsKey(realKey)) { - disableCachingForStackLoop(realKey, progressMap); + LinkedHashMap progressMap = ourProgress.get(); + if (progressMap.containsKey(realKey)) { + int stamp = ourStamp.get() + 1; + ourStamp.set(stamp); - ourRecursionsMet.set((ourRecursionsMet.get() != null ? ourRecursionsMet.get() : 0) + 1); + boolean inLoop = false; + for (Map.Entry entry: progressMap.entrySet()) { + if (inLoop) { + entry.setValue(stamp); + } + else if (entry.getKey().equals(realKey)) { + inLoop = true; + } + } return null; } - progressMap.put(realKey, null); + progressMap.put(realKey, ourStamp.get()); try { return computation.compute(); } finally { - Set deps = progressMap.remove(realKey); - Set noCache = ourNoCache.get(); - if (noCache != null && deps != null) { - noCache.removeAll(deps); - } + ourStamp.set(progressMap.remove(realKey)); } } @Override public StackStamp markStack() { - final Integer stamp = ourRecursionsMet.get(); + final Integer stamp = ourStamp.get(); return new StackStamp() { @Override public boolean mayCacheNow() { - return Comparing.equal(stamp, ourRecursionsMet.get()); + return Comparing.equal(stamp, ourStamp.get()); } }; } }; } - private static void disableCachingForStackLoop(Object realKey, LinkedHashMap> progressMap) { - Set noCache = ourNoCache.get(); - if (noCache == null) { - ourNoCache.set(noCache = new HashSet()); - } - - Set deps = progressMap.get(realKey); - if (deps == null) { - progressMap.put(realKey, deps = new HashSet()); - } - - boolean inCycle = false; - for (Object o : progressMap.keySet()) { - if (inCycle || o.equals(realKey)) { - inCycle = true; - deps.add(o); - noCache.add(o); - } - } - } }