From 4a78c031e8465448cdc7098a892ff51543b88eb5 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 27 Oct 2009 23:43:06 +0300 Subject: [PATCH] read/write lock instead of synchronized --- .../util/indexing/MemoryIndexStorage.java | 147 ++++++++++++------ 1 file changed, 97 insertions(+), 50 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java index f14fb5e29b82..1c67305f22bd 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java @@ -18,12 +18,14 @@ package com.intellij.util.indexing; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; +import com.intellij.util.concurrency.JBLock; +import com.intellij.util.concurrency.JBReentrantReadWriteLock; +import com.intellij.util.concurrency.LockFactory; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; /** * This storage is needed for indexing yet unsaved data without saving those changes to 'main' backend storage @@ -34,10 +36,13 @@ import java.util.concurrent.atomic.AtomicBoolean; public class MemoryIndexStorage implements IndexStorage { private final Map> myMap = new HashMap>(); private final IndexStorage myBackendStorage; - private final AtomicBoolean myBufferingEnabled = new AtomicBoolean(false); + private boolean myBufferingEnabled = false; private final List myListeners = ContainerUtil.createEmptyCOWList(); + private final JBReentrantReadWriteLock myLock = LockFactory.createReadWriteLock(); + private final JBLock r = myLock.readLock(); + private final JBLock w = myLock.writeLock(); - public static interface BufferingStateListener { + public interface BufferingStateListener { void bufferingStateChanged(boolean newState); } @@ -53,15 +58,22 @@ public class MemoryIndexStorage implements IndexStorage myListeners.remove(listener); } - public synchronized void setBufferingEnabled(boolean enabled) { - final boolean wasEnabled = myBufferingEnabled.getAndSet(enabled); - if (wasEnabled && !enabled) { - myMap.clear(); - } - if (wasEnabled != enabled) { - for (BufferingStateListener listener : myListeners) { - listener.bufferingStateChanged(enabled); + public void setBufferingEnabled(boolean enabled) { + w.lock(); + try { + final boolean wasEnabled = myBufferingEnabled; + myBufferingEnabled = enabled; + if (wasEnabled && !enabled) { + myMap.clear(); } + if (wasEnabled != enabled) { + for (BufferingStateListener listener : myListeners) { + listener.bufferingStateChanged(enabled); + } + } + } + finally { + w.unlock(); } } @@ -69,9 +81,15 @@ public class MemoryIndexStorage implements IndexStorage myBackendStorage.close(); } - public synchronized void clear() throws StorageException { - myMap.clear(); - myBackendStorage.clear(); + public void clear() throws StorageException { + w.lock(); + try { + myMap.clear(); + myBackendStorage.clear(); + } + finally { + w.unlock(); + } } public void flush() throws IOException { @@ -84,58 +102,80 @@ public class MemoryIndexStorage implements IndexStorage return keys; } - public synchronized boolean processKeys(final Processor processor) throws StorageException { - if (myBufferingEnabled.get()) { - final Set stopList = new HashSet(); + public boolean processKeys(final Processor processor) throws StorageException { + r.lock(); + try { + if (myBufferingEnabled) { + final Set stopList = new HashSet(); - Processor decoratingProcessor = new Processor() { - public boolean process(final Key key) { - if (stopList.contains(key)) return true; + Processor decoratingProcessor = new Processor() { + public boolean process(final Key key) { + if (stopList.contains(key)) return true; - final UpdatableValueContainer container = myMap.get(key); - if (container != null && container.size() == 0) return true; - return processor.process(key); + final UpdatableValueContainer container = myMap.get(key); + if (container != null && container.size() == 0) return true; + return processor.process(key); + } + }; + + for (Key key : myMap.keySet()) { + if (!decoratingProcessor.process(key)) return false; + stopList.add(key); } - }; - - for (Key key : myMap.keySet()) { - if (!decoratingProcessor.process(key)) return false; - stopList.add(key); + return myBackendStorage.processKeys(decoratingProcessor); } - return myBackendStorage.processKeys(decoratingProcessor); } - else { - return myBackendStorage.processKeys(processor); + finally { + r.unlock(); } + + return myBackendStorage.processKeys(processor); } public void addValue(final Key key, final int inputId, final Value value) throws StorageException { - if (!myBufferingEnabled.get()) { - myBackendStorage.addValue(key, inputId, value); - return; + w.lock(); + try { + if (myBufferingEnabled) { + getMemValueContainer(key).addValue(inputId, value); + return; + } } - getMemValueContainer(key).addValue(inputId, value); + finally { + w.unlock(); + } + + myBackendStorage.addValue(key, inputId, value); } public void removeValue(final Key key, final int inputId, final Value value) throws StorageException { - if (myBufferingEnabled.get()) { - getMemValueContainer(key).removeValue(inputId, value); + w.lock(); + try { + if (myBufferingEnabled) { + getMemValueContainer(key).removeValue(inputId, value); + return; + } } - else { - myBackendStorage.removeValue(key, inputId, value); + finally { + w.unlock(); } + myBackendStorage.removeValue(key, inputId, value); } public void removeAllValues(Key key, int inputId) throws StorageException { - if (myBufferingEnabled.get()) { - getMemValueContainer(key).removeAllValues(inputId); + w.lock(); + try { + if (myBufferingEnabled) { + getMemValueContainer(key).removeAllValues(inputId); + return; + } } - else { - myBackendStorage.removeAllValues(key, inputId); + finally { + w.unlock(); } + myBackendStorage.removeAllValues(key, inputId); } - private synchronized UpdatableValueContainer getMemValueContainer(final Key key) { + private UpdatableValueContainer getMemValueContainer(final Key key) { UpdatableValueContainer valueContainer = myMap.get(key); if (valueContainer == null) { valueContainer = new ChangeTrackingValueContainer(new ChangeTrackingValueContainer.Initializer() { @@ -158,14 +198,21 @@ public class MemoryIndexStorage implements IndexStorage } @NotNull - public synchronized ValueContainer read(final Key key) throws StorageException { - if (!myBufferingEnabled.get()) { - return myBackendStorage.read(key); + public ValueContainer read(final Key key) throws StorageException { + r.lock(); + try { + if (myBufferingEnabled) { + final ValueContainer valueContainer = myMap.get(key); + if (valueContainer != null) { + return valueContainer; + } + return myBackendStorage.read(key); + } } - final ValueContainer valueContainer = myMap.get(key); - if (valueContainer != null) { - return valueContainer; + finally { + r.unlock(); } + return myBackendStorage.read(key); }