mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
memory backed, limited recent strings interner for stubs
This commit is contained in:
@@ -16,13 +16,15 @@
|
||||
package com.intellij.psi.stubs;
|
||||
|
||||
import com.intellij.openapi.diagnostic.LogUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.LowMemoryWatcher;
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.util.containers.SLRUCache;
|
||||
import com.intellij.util.io.AbstractStringEnumerator;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import com.intellij.util.io.IOUtil;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import jsr166e.SequenceLock;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -32,13 +34,12 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
/**
|
||||
* Author: dmitrylomov
|
||||
*/
|
||||
public class StubSerializationHelper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.StubSerializationHelper");
|
||||
|
||||
private AbstractStringEnumerator myNameStorage;
|
||||
|
||||
protected final TIntObjectHashMap<StubSerializer<? extends StubElement>> myIdToSerializer = new TIntObjectHashMap<StubSerializer<? extends StubElement>>();
|
||||
@@ -47,6 +48,7 @@ public class StubSerializationHelper {
|
||||
public StubSerializationHelper(AbstractStringEnumerator nameStorage) {
|
||||
myNameStorage = nameStorage;
|
||||
}
|
||||
|
||||
public void assignId(@NotNull final StubSerializer<? extends StubElement> serializer) throws IOException {
|
||||
final int id = persistentId(serializer);
|
||||
final StubSerializer old = myIdToSerializer.put(id, serializer);
|
||||
@@ -98,6 +100,58 @@ public class StubSerializationHelper {
|
||||
return idValue;
|
||||
}
|
||||
|
||||
private static class RecentStringInterner {
|
||||
private final int myStripeMask;
|
||||
private final SLRUCache<String, String>[] myInterns;
|
||||
private final Lock[] myStripeLocks;
|
||||
private final LowMemoryWatcher myClearingCallback;
|
||||
|
||||
private RecentStringInterner(int capacity) {
|
||||
final int stripes = 16;
|
||||
myInterns = new SLRUCache[stripes];
|
||||
myStripeLocks = new Lock[myInterns.length];
|
||||
for(int i = 0; i < myInterns.length; ++i) {
|
||||
myInterns[i] = new SLRUCache<String, String>(capacity / stripes, capacity / stripes) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String createValue(String key) {
|
||||
return key;
|
||||
}
|
||||
};
|
||||
myStripeLocks[i] = new SequenceLock();
|
||||
}
|
||||
|
||||
assert Integer.highestOneBit(stripes) == stripes;
|
||||
myStripeMask = stripes - 1;
|
||||
myClearingCallback = LowMemoryWatcher.register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clear();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
String get(String s) {
|
||||
final int stripe = Math.abs(s.hashCode()) & myStripeMask;
|
||||
try {
|
||||
myStripeLocks[stripe].lock();
|
||||
return myInterns[stripe].get(s);
|
||||
} finally {
|
||||
myStripeLocks[stripe].unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for(int i = 0; i < myInterns.length; ++i) {
|
||||
myStripeLocks[i].lock();
|
||||
myInterns[i].clear();
|
||||
myStripeLocks[i].unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final RecentStringInterner myStringInterner = new RecentStringInterner(8192);
|
||||
|
||||
public StubElement deserialize(InputStream stream) throws IOException {
|
||||
FileLocalStringEnumerator storage = new FileLocalStringEnumerator();
|
||||
StubInputStream inputStream = new StubInputStream(stream, storage);
|
||||
@@ -106,7 +160,7 @@ public class StubSerializationHelper {
|
||||
|
||||
int i = 1;
|
||||
while(i <= size) {
|
||||
String s = IOUtil.readUTFFast(buffer, inputStream);
|
||||
String s = myStringInterner.get(IOUtil.readUTFFast(buffer, inputStream));
|
||||
storage.myStrings.add(s);
|
||||
storage.myEnumerates.put(s, i);
|
||||
++i;
|
||||
|
||||
Reference in New Issue
Block a user