mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
more optimal storage for mostly used single stub id + StubIdList used instead of raw int[] to avoid Value mapping problems, take 2
This commit is contained in:
@@ -65,12 +65,12 @@ final class StubIdList {
|
||||
}
|
||||
|
||||
int size() {
|
||||
return myArray == null ? myData > 0 ? 1 : 0: myData;
|
||||
return myArray == null ? myData >= 0 ? 1 : 0: myData;
|
||||
}
|
||||
|
||||
int get(int i) {
|
||||
if (myArray == null) {
|
||||
assert myData > 0;
|
||||
assert myData >= 0;
|
||||
if (i == 0) return myData;
|
||||
throw new IncorrectOperationException();
|
||||
} else {
|
||||
|
||||
@@ -127,14 +127,14 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
try {
|
||||
final MapIndexStorage<K, int[]> storage = new MapIndexStorage<K, int[]>(
|
||||
final MapIndexStorage<K, StubIdList> storage = new MapIndexStorage<K, StubIdList>(
|
||||
IndexInfrastructure.getStorageFile(indexKey),
|
||||
extension.getKeyDescriptor(),
|
||||
new StubIdExternalizer(),
|
||||
extension.getCacheSize(),
|
||||
extension.isKeyHighlySelective()
|
||||
);
|
||||
final MemoryIndexStorage<K, int[]> memStorage = new MemoryIndexStorage<K, int[]>(storage);
|
||||
final MemoryIndexStorage<K, StubIdList> memStorage = new MemoryIndexStorage<K, StubIdList>(storage);
|
||||
myIndices.put(indexKey, new MyIndex<K>(memStorage));
|
||||
break;
|
||||
}
|
||||
@@ -148,40 +148,41 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
return needRebuild;
|
||||
}
|
||||
|
||||
private static class StubIdExternalizer implements DataExternalizer<int[]> {
|
||||
private static class StubIdExternalizer implements DataExternalizer<StubIdList> {
|
||||
@Override
|
||||
public void save(final DataOutput out, @NotNull final int[] value) throws IOException {
|
||||
int size = value.length;
|
||||
public void save(final DataOutput out, @NotNull final StubIdList value) throws IOException {
|
||||
int size = value.size();
|
||||
if (size == 0) {
|
||||
DataInputOutputUtil.writeSINT(out, Integer.MAX_VALUE);
|
||||
DataInputOutputUtil.writeINT(out, Integer.MAX_VALUE);
|
||||
}
|
||||
else if (size == 1) {
|
||||
DataInputOutputUtil.writeSINT(out, -value[0]);
|
||||
DataInputOutputUtil.writeINT(out, value.get(0)); // most often case
|
||||
}
|
||||
else {
|
||||
DataInputOutputUtil.writeSINT(out, size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
DataInputOutputUtil.writeINT(out, value[i]);
|
||||
DataInputOutputUtil.writeINT(out, -size);
|
||||
for(int i = 0; i < size; ++i) {
|
||||
DataInputOutputUtil.writeINT(out, value.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public int[] read(final DataInput in) throws IOException {
|
||||
int size = DataInputOutputUtil.readSINT(in);
|
||||
public StubIdList read(final DataInput in) throws IOException {
|
||||
int size = DataInputOutputUtil.readINT(in);
|
||||
if (size == Integer.MAX_VALUE) {
|
||||
return new int[0];
|
||||
return new StubIdList();
|
||||
}
|
||||
else if (size <= 0) {
|
||||
return new int[] {-size};
|
||||
else if (size >= 0) {
|
||||
return new StubIdList(size);
|
||||
}
|
||||
else {
|
||||
size = -size;
|
||||
int[] result = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
for(int i = 0; i < size; ++i) {
|
||||
result[i] = DataInputOutputUtil.readINT(in);
|
||||
}
|
||||
return result;
|
||||
return new StubIdList(result, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,13 +217,13 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
// disable up-to-date check to avoid locks on attempt to acquire index write lock while holding at the same time the readLock for this index
|
||||
FileBasedIndexImpl.disableUpToDateCheckForCurrentThread();
|
||||
index.getReadLock().lock();
|
||||
final ValueContainer<int[]> container = index.getData(key);
|
||||
final ValueContainer<StubIdList> container = index.getData(key);
|
||||
|
||||
final FileBasedIndexImpl.ProjectIndexableFilesFilter projectFilesFilter = fileBasedIndex.projectIndexableFiles(project);
|
||||
|
||||
return container.forEach(new ValueContainer.ContainerAction<int[]>() {
|
||||
return container.forEach(new ValueContainer.ContainerAction<StubIdList>() {
|
||||
@Override
|
||||
public boolean perform(final int id, @NotNull final int[] value) {
|
||||
public boolean perform(final int id, @NotNull final StubIdList value) {
|
||||
if (projectFilesFilter != null && !projectFilesFilter.contains(id)) return true;
|
||||
final VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id);
|
||||
if (file == null || scope != null && !scope.contains(file)) {
|
||||
@@ -252,8 +253,8 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
return true;
|
||||
}
|
||||
final List<StubElement<?>> plained = stubTree.getPlainList();
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
final StubElement<?> stub = plained.get(value[i]);
|
||||
for (int i = 0, size = value.size(); i < size; i++) {
|
||||
final StubElement<?> stub = plained.get(value.get(i));
|
||||
final ASTNode tree = psiFile.findTreeForStub(stubTree, stub);
|
||||
|
||||
if (tree != null) {
|
||||
@@ -293,8 +294,8 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
}
|
||||
else {
|
||||
final List<StubElement<?>> plained = stubTree.getPlainList();
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
final int stubTreeIndex = value[i];
|
||||
for (int i = 0, size = value.size(); i < size; i++) {
|
||||
final int stubTreeIndex = value.get(i);
|
||||
if (stubTreeIndex >= plained.size()) {
|
||||
final VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||
StubTree stubTreeFromIndex = StubTreeLoader.getInstance().readFromVFile(project, file);
|
||||
@@ -473,7 +474,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
index.flush();
|
||||
}
|
||||
|
||||
public <K> void updateIndex(@NotNull StubIndexKey key, int fileId, @NotNull final Map<K, int[]> oldValues, @NotNull Map<K, int[]> newValues) {
|
||||
public <K> void updateIndex(@NotNull StubIndexKey key, int fileId, @NotNull final Map<K, StubIdList> oldValues, @NotNull Map<K, StubIdList> newValues) {
|
||||
try {
|
||||
final MyIndex<K> index = (MyIndex<K>)myIndices.get(key);
|
||||
index.updateWithMap(fileId, newValues, new Callable<Collection<K>>() {
|
||||
@@ -489,13 +490,13 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyIndex<K> extends MapReduceIndex<K, int[], Void> {
|
||||
public MyIndex(final IndexStorage<K, int[]> storage) {
|
||||
private static class MyIndex<K> extends MapReduceIndex<K, StubIdList, Void> {
|
||||
public MyIndex(final IndexStorage<K, StubIdList> storage) {
|
||||
super(null, null, storage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateWithMap(final int inputId, @NotNull final Map<K, int[]> newData, @NotNull Callable<Collection<K>> oldKeysGetter) throws StorageException {
|
||||
public void updateWithMap(final int inputId, @NotNull final Map<K, StubIdList> newData, @NotNull Callable<Collection<K>> oldKeysGetter) throws StorageException {
|
||||
super.updateWithMap(inputId, newData, oldKeysGetter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
|
||||
public static final ID<Integer, SerializedStubTree> INDEX_ID = ID.create("Stubs");
|
||||
|
||||
private static final int VERSION = 20;
|
||||
private static final int VERSION = 21;
|
||||
|
||||
private static final DataExternalizer<SerializedStubTree> KEY_EXTERNALIZER = new DataExternalizer<SerializedStubTree>() {
|
||||
@Override
|
||||
@@ -206,21 +206,25 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
return new MyIndex(indexId, storage, getIndexer());
|
||||
}
|
||||
|
||||
private static void updateStubIndices(@NotNull final Collection<StubIndexKey> indexKeys, final int inputId, @NotNull final Map<StubIndexKey, Map<Object, int[]>> oldStubTree, @NotNull final Map<StubIndexKey, Map<Object, int[]>> newStubTree) {
|
||||
private static void updateStubIndices(@NotNull final Collection<StubIndexKey> indexKeys,
|
||||
final int inputId,
|
||||
@NotNull final Map<StubIndexKey, Map<Object, StubIdList>> oldStubTree,
|
||||
@NotNull final Map<StubIndexKey, Map<Object, StubIdList>> newStubTree) {
|
||||
final StubIndexImpl stubIndex = (StubIndexImpl)StubIndex.getInstance();
|
||||
for (StubIndexKey key : indexKeys) {
|
||||
final Map<Object, int[]> oldMap = oldStubTree.get(key);
|
||||
final Map<Object, int[]> newMap = newStubTree.get(key);
|
||||
final Map<Object, StubIdList> oldMap = oldStubTree.get(key);
|
||||
final Map<Object, StubIdList> newMap = newStubTree.get(key);
|
||||
|
||||
final Map<Object, int[]> _oldMap = oldMap != null ? oldMap : Collections.<Object, int[]>emptyMap();
|
||||
final Map<Object, int[]> _newMap = newMap != null ? newMap : Collections.<Object, int[]>emptyMap();
|
||||
final Map<Object, StubIdList> _oldMap = oldMap != null ? oldMap : Collections.<Object, StubIdList>emptyMap();
|
||||
final Map<Object, StubIdList> _newMap = newMap != null ? newMap : Collections.<Object, StubIdList>emptyMap();
|
||||
|
||||
stubIndex.updateIndex(key, inputId, _oldMap, _newMap);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<StubIndexKey> getAffectedIndices(@NotNull final Map<StubIndexKey, Map<Object, int[]>> oldStubTree, @NotNull final Map<StubIndexKey, Map<Object, int[]>> newStubTree) {
|
||||
private static Collection<StubIndexKey> getAffectedIndices(@NotNull final Map<StubIndexKey, Map<Object, StubIdList>> oldStubTree,
|
||||
@NotNull final Map<StubIndexKey, Map<Object, StubIdList>> newStubTree) {
|
||||
Set<StubIndexKey> allIndices = new HashSet<StubIndexKey>();
|
||||
allIndices.addAll(oldStubTree.keySet());
|
||||
allIndices.addAll(newStubTree.keySet());
|
||||
@@ -253,7 +257,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
throws StorageException {
|
||||
|
||||
checkNameStorage();
|
||||
final Map<StubIndexKey, Map<Object, int[]>> newStubTree = getStubTree(newData);
|
||||
final Map<StubIndexKey, Map<Object, StubIdList>> newStubTree = getStubTree(newData);
|
||||
|
||||
final StubIndexImpl stubIndex = getStubIndex();
|
||||
final Collection<StubIndexKey> allStubIndices = stubIndex.getAllStubIndexKeys();
|
||||
@@ -267,7 +271,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
getWriteLock().lock();
|
||||
|
||||
final Map<Integer, SerializedStubTree> oldData = readOldData(inputId);
|
||||
final Map<StubIndexKey, Map<Object, int[]>> oldStubTree = getStubTree(oldData);
|
||||
final Map<StubIndexKey, Map<Object, StubIdList>> oldStubTree = getStubTree(oldData);
|
||||
|
||||
super.updateWithMap(inputId, newData, oldKeysGetter);
|
||||
|
||||
@@ -301,11 +305,22 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<StubIndexKey, Map<Object, int[]>> getStubTree(@NotNull final Map<Integer, SerializedStubTree> data) {
|
||||
final Map<StubIndexKey, Map<Object, int[]>> stubTree;
|
||||
private static Map<StubIndexKey, Map<Object, StubIdList>> getStubTree(@NotNull final Map<Integer, SerializedStubTree> data) {
|
||||
final Map<StubIndexKey, Map<Object, StubIdList>> stubTree;
|
||||
if (!data.isEmpty()) {
|
||||
final SerializedStubTree stub = data.values().iterator().next();
|
||||
stubTree = new StubTree((PsiFileStub)stub.getStub(true), false).indexStubTree();
|
||||
Map<StubIndexKey, Map<Object, int[]>> map = new StubTree((PsiFileStub)stub.getStub(true), false).indexStubTree();
|
||||
|
||||
// xxx:fix refs inplace
|
||||
stubTree = (Map)map;
|
||||
for(StubIndexKey key:map.keySet()) {
|
||||
Map<Object, int[]> value = map.get(key);
|
||||
for(Object k: value.keySet()) {
|
||||
int[] ints = value.get(k);
|
||||
StubIdList stubList = ints.length == 1 ? new StubIdList(ints[0]) : new StubIdList(ints, ints.length);
|
||||
((Map<Object, StubIdList>)(Map)value).put(k, stubList);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
stubTree = Collections.emptyMap();
|
||||
|
||||
Reference in New Issue
Block a user