mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
proper hierarchical synchronization, till this code is rewritten
This commit is contained in:
@@ -53,21 +53,23 @@ public class CachedPersistentHashMap<Key, Value> extends PersistentHashMap<Key,
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized void put(Key key, Value value) throws IOException {
|
||||
@Override
|
||||
protected void doPut(Key key, Value value) throws IOException {
|
||||
myCache.remove(key);
|
||||
super.put(key, value);
|
||||
super.doPut(key, value);
|
||||
}
|
||||
|
||||
public synchronized void appendData(Key key, ValueDataAppender appender) throws IOException {
|
||||
@Override
|
||||
protected void doAppendData(Key key, ValueDataAppender appender) throws IOException {
|
||||
myCache.remove(key);
|
||||
super.appendData(key, appender);
|
||||
super.doAppendData(key, appender);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public synchronized Value get(Key key) throws IOException {
|
||||
protected Value doGet(Key key) throws IOException {
|
||||
Value value = myCache.get(key);
|
||||
if (value == null) {
|
||||
value = super.get(key);
|
||||
value = super.doGet(key);
|
||||
if (value != null) {
|
||||
myCache.put(key, value);
|
||||
}
|
||||
@@ -75,26 +77,30 @@ public class CachedPersistentHashMap<Key, Value> extends PersistentHashMap<Key,
|
||||
return value;
|
||||
}
|
||||
|
||||
public synchronized boolean containsMapping(Key key) throws IOException {
|
||||
@Override
|
||||
protected boolean doContainsMapping(Key key) throws IOException {
|
||||
final Value value = myCache.get(key);
|
||||
return value != null || super.containsMapping(key);
|
||||
return value != null || super.doContainsMapping(key);
|
||||
}
|
||||
|
||||
public synchronized void remove(Key key) throws IOException {
|
||||
@Override
|
||||
protected void doRemove(Key key) throws IOException {
|
||||
myCache.remove(key);
|
||||
super.remove(key);
|
||||
}
|
||||
|
||||
public synchronized void force() {
|
||||
@Override
|
||||
protected void doForce() {
|
||||
try {
|
||||
clearCache();
|
||||
}
|
||||
finally {
|
||||
super.force();
|
||||
super.doForce();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void close() throws IOException {
|
||||
@Override
|
||||
protected void doClose() throws IOException {
|
||||
try {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@@ -522,33 +522,33 @@ public class FileBasedIndex implements ApplicationComponent {
|
||||
) {
|
||||
|
||||
@Override
|
||||
public synchronized Collection<K> get(Integer integer) throws IOException {
|
||||
protected Collection<K> doGet(Integer integer) throws IOException {
|
||||
if (isBufferingMode.get()) {
|
||||
final Collection<K> collection = tempMap.get(integer);
|
||||
if (collection != null) {
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
return super.get(integer);
|
||||
return super.doGet(integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void put(Integer integer, Collection<K> ks) throws IOException {
|
||||
protected void doPut(Integer integer, Collection<K> ks) throws IOException {
|
||||
if (isBufferingMode.get()) {
|
||||
tempMap.put(integer, ks == null? Collections.<K>emptySet() : ks);
|
||||
}
|
||||
else {
|
||||
super.put(integer, ks);
|
||||
super.doPut(integer, ks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void remove(Integer integer) throws IOException {
|
||||
protected void doRemove(Integer integer) throws IOException {
|
||||
if (isBufferingMode.get()) {
|
||||
tempMap.put(integer, Collections.<K>emptySet());
|
||||
}
|
||||
else {
|
||||
super.remove(integer);
|
||||
super.doRemove(integer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,37 +27,39 @@ public class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueC
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void put(Key key, ValueContainer<Value> container) throws IOException {
|
||||
ChangeTrackingValueContainer<Value> valueContainer = (ChangeTrackingValueContainer<Value>)container;
|
||||
if (!valueContainer.needsCompacting()) {
|
||||
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
final DataOutputStream _out = new DataOutputStream(bytes);
|
||||
final TIntHashSet set = valueContainer.getInvalidated();
|
||||
if (set.size() > 0) {
|
||||
for (int inputId : set.toArray()) {
|
||||
ValueContainerExternalizer.saveInvalidateCommand(_out, inputId);
|
||||
protected void doPut(Key key, ValueContainer<Value> container) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
ChangeTrackingValueContainer<Value> valueContainer = (ChangeTrackingValueContainer<Value>)container;
|
||||
if (!valueContainer.needsCompacting()) {
|
||||
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
final DataOutputStream _out = new DataOutputStream(bytes);
|
||||
final TIntHashSet set = valueContainer.getInvalidated();
|
||||
if (set.size() > 0) {
|
||||
for (int inputId : set.toArray()) {
|
||||
ValueContainerExternalizer.saveInvalidateCommand(_out, inputId);
|
||||
}
|
||||
}
|
||||
}
|
||||
final ValueContainer<Value> toRemove = valueContainer.getRemovedDelta();
|
||||
if (toRemove.size() > 0) {
|
||||
myValueContainerExternalizer.saveAsRemoved(_out, toRemove);
|
||||
}
|
||||
|
||||
final ValueContainer<Value> toAppend = valueContainer.getAddedDelta();
|
||||
if (toAppend.size() > 0) {
|
||||
myValueContainerExternalizer.save(_out, toAppend);
|
||||
}
|
||||
|
||||
appendData(key, new PersistentHashMap.ValueDataAppender() {
|
||||
public void append(final DataOutput out) throws IOException {
|
||||
out.write(bytes.getInternalBuffer(), 0, bytes.size());
|
||||
final ValueContainer<Value> toRemove = valueContainer.getRemovedDelta();
|
||||
if (toRemove.size() > 0) {
|
||||
myValueContainerExternalizer.saveAsRemoved(_out, toRemove);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
// rewrite the value container for defragmentation
|
||||
super.put(key, valueContainer);
|
||||
|
||||
final ValueContainer<Value> toAppend = valueContainer.getAddedDelta();
|
||||
if (toAppend.size() > 0) {
|
||||
myValueContainerExternalizer.save(_out, toAppend);
|
||||
}
|
||||
|
||||
appendData(key, new PersistentHashMap.ValueDataAppender() {
|
||||
public void append(final DataOutput out) throws IOException {
|
||||
out.write(bytes.getInternalBuffer(), 0, bytes.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
// rewrite the value container for defragmentation
|
||||
super.doPut(key, valueContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
private final LowMemoryWatcher myAppendCacheFlusher = LowMemoryWatcher.register(new LowMemoryWatcher.ForceableAdapter() {
|
||||
public void force() {
|
||||
//System.out.println("Flushing caches: " + myFile.getPath());
|
||||
synchronized (PersistentHashMap.this) {
|
||||
synchronized (myEnumerator) {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
clearAppenderCaches();
|
||||
}
|
||||
@@ -253,7 +253,13 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
return new File(file.getParentFile(), file.getName() + DATA_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
public synchronized void put(Key key, Value value) throws IOException {
|
||||
public final void put(Key key, Value value) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
doPut(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doPut(Key key, Value value) throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
myEnumerator.markDirty(true);
|
||||
myAppendCache.remove(key);
|
||||
@@ -278,16 +284,24 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int enumerate(Key name) throws IOException {
|
||||
myIntAddressForNewRecord = canUseIntAddressForNewRecord(myValueStorage.getSize());
|
||||
return super.enumerate(name);
|
||||
public final int enumerate(Key name) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
myIntAddressForNewRecord = canUseIntAddressForNewRecord(myValueStorage.getSize());
|
||||
return super.enumerate(name);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ValueDataAppender {
|
||||
void append(DataOutput out) throws IOException;
|
||||
}
|
||||
|
||||
public synchronized void appendData(Key key, ValueDataAppender appender) throws IOException {
|
||||
public final void appendData(Key key, ValueDataAppender appender) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
doAppendData(key, appender);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doAppendData(Key key, ValueDataAppender appender) throws IOException {
|
||||
myEnumerator.markDirty(true);
|
||||
|
||||
final AppendStream stream = myAppendCache.get(key);
|
||||
@@ -298,9 +312,11 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
* Process all keys registered in the map. Note that keys which were removed after {@link #compact()} call will be processed as well. Use
|
||||
* {@link #processKeysWithExistingMapping(com.intellij.util.Processor)} to process only keys with existing mappings
|
||||
*/
|
||||
public synchronized boolean processKeys(Processor<Key> processor) throws IOException {
|
||||
myAppendCache.clear();
|
||||
return myEnumerator.iterateData(processor);
|
||||
public final boolean processKeys(Processor<Key> processor) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
myAppendCache.clear();
|
||||
return myEnumerator.iterateData(processor);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Key> getAllKeysWithExistingMapping() throws IOException {
|
||||
@@ -309,8 +325,8 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
return values;
|
||||
}
|
||||
|
||||
public synchronized boolean processKeysWithExistingMapping(Processor<Key> processor) throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
public final boolean processKeysWithExistingMapping(Processor<Key> processor) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
return myEnumerator.processAllDataObject(processor, new PersistentEnumerator.DataFilter() {
|
||||
public boolean accept(final int id) {
|
||||
return readValueId(id).address != NULL_ADDR;
|
||||
@@ -319,7 +335,13 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Value get(Key key) throws IOException {
|
||||
public final Value get(Key key) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
return doGet(key);
|
||||
}
|
||||
}
|
||||
|
||||
protected Value doGet(Key key) throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
myAppendCache.remove(key);
|
||||
final int id = tryEnumerate(key);
|
||||
@@ -330,7 +352,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
if (oldHeader.address == PersistentEnumerator.NULL_ID) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Pair<Long, byte[]> readResult = myValueStorage.readBytes(oldHeader.address);
|
||||
if (readResult.first != null && readResult.first != oldHeader.address) {
|
||||
myEnumerator.markDirty(true);
|
||||
@@ -351,7 +373,13 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean containsMapping(Key key) throws IOException {
|
||||
public final boolean containsMapping(Key key) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
return doContainsMapping(key);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean doContainsMapping(Key key) throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
myAppendCache.remove(key);
|
||||
final int id = tryEnumerate(key);
|
||||
@@ -362,7 +390,13 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void remove(Key key) throws IOException {
|
||||
public final void remove(Key key) throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
doRemove(key);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doRemove(Key key) throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
myAppendCache.remove(key);
|
||||
final int id = tryEnumerate(key);
|
||||
@@ -380,11 +414,19 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
}
|
||||
}
|
||||
|
||||
public final synchronized void markDirty() throws IOException {
|
||||
myEnumerator.markDirty(true);
|
||||
public final void markDirty() throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
myEnumerator.markDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void force() {
|
||||
public final void force() {
|
||||
synchronized (myEnumerator) {
|
||||
doForce();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doForce() {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
try {
|
||||
clearAppenderCaches();
|
||||
@@ -400,7 +442,13 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
myValueStorage.force();
|
||||
}
|
||||
|
||||
public synchronized void close() throws IOException {
|
||||
public final void close() throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
doClose();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doClose() throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
try {
|
||||
myAppendCacheFlusher.stop();
|
||||
@@ -412,10 +460,10 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// made public for tests
|
||||
public synchronized void compact() throws IOException {
|
||||
synchronized (PersistentEnumerator.ourLock) {
|
||||
public void compact() throws IOException {
|
||||
synchronized (myEnumerator) {
|
||||
final long now = System.currentTimeMillis();
|
||||
final String newPath = getDataFile(myEnumerator.myFile).getPath() + ".new";
|
||||
final PersistentHashMapValueStorage newStorage = PersistentHashMapValueStorage.create(newPath);
|
||||
|
||||
Reference in New Issue
Block a user