diff options
Diffstat (limited to 'platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java')
-rw-r--r-- | platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java | 131 |
1 files changed, 15 insertions, 116 deletions
diff --git a/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java index 19755778f2ec..996798734253 100644 --- a/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java +++ b/platform/util/src/com/intellij/util/io/PersistentStringEnumerator.java @@ -15,22 +15,14 @@ */ package com.intellij.util.io; -import com.intellij.util.containers.SLRUMap; -import jsr166e.extra.SequenceLock; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; -import java.util.concurrent.locks.Lock; public class PersistentStringEnumerator extends PersistentEnumeratorDelegate<String> implements AbstractStringEnumerator { - private static final int STRIPE_POWER = 4; - private static final int STRIPE_COUNT = 1 << STRIPE_POWER; - private static final int STRIPE_MASK = STRIPE_COUNT - 1; - @Nullable private final SLRUMap<Integer, Integer>[] myHashcodeToIdCache; - @Nullable private final SLRUMap<Integer, String>[] myIdToStringCache; - @Nullable private final Lock[] myStripeLocks; + @Nullable private final CachingEnumerator<String> myCache; public PersistentStringEnumerator(@NotNull final File file) throws IOException { this(file, null); @@ -58,129 +50,36 @@ public class PersistentStringEnumerator extends PersistentEnumeratorDelegate<Str final int initialSize, boolean cacheLastMappings, @Nullable PagedFileStorage.StorageLockContext lockContext) throws IOException { - super(file, new EnumeratorStringDescriptor(), initialSize, lockContext); - if (cacheLastMappings) { - myIdToStringCache = new SLRUMap[STRIPE_COUNT]; - myHashcodeToIdCache = new SLRUMap[STRIPE_COUNT]; - myStripeLocks = new Lock[STRIPE_COUNT]; - int protectedSize = 8192; - int probationalSize = 8192; + super(file, EnumeratorStringDescriptor.INSTANCE, initialSize, lockContext); + myCache = cacheLastMappings ? new CachingEnumerator<String>(new DataEnumerator<String>() { + @Override + public int enumerate(@Nullable String value) throws IOException { + return PersistentStringEnumerator.super.enumerate(value); + } - for(int i = 0; i < STRIPE_COUNT; ++i) { - myHashcodeToIdCache[i] = new SLRUMap<Integer, Integer>(protectedSize / STRIPE_COUNT, probationalSize / STRIPE_COUNT); - myIdToStringCache[i] = new SLRUMap<Integer, String>(protectedSize / STRIPE_COUNT, probationalSize / STRIPE_COUNT); - myStripeLocks[i] = new SequenceLock(); + @Nullable + @Override + public String valueOf(int idx) throws IOException { + return PersistentStringEnumerator.super.valueOf(idx); } - } else { - myIdToStringCache = null; - myHashcodeToIdCache = null; - myStripeLocks = null; - } + }, EnumeratorStringDescriptor.INSTANCE) : null; } @Override public int enumerate(@Nullable String value) throws IOException { - int valueHashCode =-1; - int stripe = -1; - - if (myHashcodeToIdCache != null && value != null) { - valueHashCode = value.hashCode(); - stripe = Math.abs(valueHashCode) & STRIPE_MASK; - - Integer cachedId; - - myStripeLocks[stripe].lock(); - try { - cachedId = myHashcodeToIdCache[stripe].get(valueHashCode); - } - finally { - myStripeLocks[stripe].unlock(); - } - - if (cachedId != null) { - int stripe2 = idStripe(cachedId.intValue()); - myStripeLocks[stripe2].lock(); - try { - String s = myIdToStringCache[stripe2].get(cachedId); - if (s != null && value.equals(s)) return cachedId.intValue(); - } - finally { - myStripeLocks[stripe2].unlock(); - } - } - } - - int enumerate = super.enumerate(value); - - if (stripe != -1) { - Integer enumeratedInteger; - - myStripeLocks[stripe].lock(); - try { - enumeratedInteger = enumerate; - myHashcodeToIdCache[stripe].put(valueHashCode, enumeratedInteger); - } finally { - myStripeLocks[stripe].unlock(); - } - - int stripe2 = idStripe(enumerate); - myStripeLocks[stripe2].lock(); - try { - myIdToStringCache[stripe2].put(enumeratedInteger, value); - } finally { - myStripeLocks[stripe2].unlock(); - } - } - - return enumerate; - } - - private int idStripe(int h) { - h ^= (h >>> 20) ^ (h >>> 12); - return Math.abs(h ^ (h >>> 7) ^ (h >>> 4)) & STRIPE_MASK; + return myCache != null ? myCache.enumerate(value) : super.enumerate(value); } @Nullable @Override public String valueOf(int idx) throws IOException { - int stripe = -1; - if (myIdToStringCache != null) { - stripe = idStripe(idx); - myStripeLocks[stripe].lock(); - try { - String s = myIdToStringCache[stripe].get(idx); - if (s != null) return s; - } - finally { - myStripeLocks[stripe].unlock(); - } - } - String s = super.valueOf(idx); - - if (stripe != -1 && s != null) { - myStripeLocks[stripe].lock(); - try { - myIdToStringCache[stripe].put(idx, s); - } - finally { - myStripeLocks[stripe].unlock(); - } - } - return s; + return myCache != null ? myCache.valueOf(idx) : super.valueOf(idx); } @Override public void close() throws IOException { super.close(); - - if (myIdToStringCache != null) { - for(int i = 0; i < myIdToStringCache.length; ++i) { - myStripeLocks[i].lock(); - myIdToStringCache[i].clear(); - myHashcodeToIdCache[i].clear(); - myStripeLocks[i].unlock(); - } - } + if (myCache != null) myCache.close(); } @Override |