mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
when enumerating nontrivial key, instead of valueOf / equals on existing previous key do compare serialized bytes of current key with previous one
This commit is contained in:
@@ -2,6 +2,7 @@ package com.intellij.psi.search;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.indexing.*;
|
||||
@@ -79,7 +80,18 @@ public class FileTypeIndex extends ScalarIndexExtension<FileType>
|
||||
|
||||
@Override
|
||||
public FileType read(DataInput in) throws IOException {
|
||||
return myFileTypeManager.getStdFileType(myEnumeratorStringDescriptor.read(in));
|
||||
String read = myEnumeratorStringDescriptor.read(in);
|
||||
FileType type = myFileTypeManager.getStdFileType(read);
|
||||
// TODO: Abstract file types are not std one, so need to be restored specially,
|
||||
// currently there are 6 of them and restoration does not happen very often so just iteration is enough
|
||||
if (type == PlainTextFileType.INSTANCE && !read.equals(type.getName())) {
|
||||
for(FileType fileType:myFileTypeManager.getRegisteredFileTypes()) {
|
||||
if (read.equals(fileType.getName())) {
|
||||
return fileType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -281,24 +281,21 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
|
||||
return NULL_ID;
|
||||
}
|
||||
|
||||
int indexNodeValueAddress = hasMapping ? myResultBuf[0]:0;
|
||||
final int indexNodeValueAddress = hasMapping ? myResultBuf[0]:0;
|
||||
int collisionAddress = NULL_ID;
|
||||
Data existingData = null;
|
||||
boolean hasExistingData = false;
|
||||
|
||||
if (!myInlineKeysNoMapping) {
|
||||
collisionAddress = NULL_ID;
|
||||
|
||||
if (indexNodeValueAddress > 0) {
|
||||
// we found reference to no dupe key
|
||||
Data candidate = valueOf(indexNodeValueAddress);
|
||||
if (IntToIntBtree.doSanityCheck) IntToIntBtree.myAssert(myDataDescriptor.getHashCode(candidate) == valueHC);
|
||||
|
||||
if (myDataDescriptor.isEqual(value, candidate)) {
|
||||
if (isKeyAtIndex(value, indexNodeValueAddress)) {
|
||||
if (!saveNewValue) {
|
||||
++myExistingKeysEnumerated;
|
||||
return indexNodeValueAddress;
|
||||
}
|
||||
existingData = candidate;
|
||||
hasExistingData = true;
|
||||
}
|
||||
|
||||
collisionAddress = indexNodeValueAddress;
|
||||
@@ -307,13 +304,11 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
|
||||
|
||||
while (true) {
|
||||
final int address = myStorage.getInt(collisionAddress);
|
||||
Data candidate = valueOf(address);
|
||||
if (myDataDescriptor.isEqual(value, candidate)) {
|
||||
if (isKeyAtIndex(value, address)) {
|
||||
if (!saveNewValue) return address;
|
||||
existingData = candidate;
|
||||
hasExistingData = true;
|
||||
break;
|
||||
}
|
||||
if (IntToIntBtree.doSanityCheck) IntToIntBtree.myAssert(myDataDescriptor.getHashCode(candidate) == valueHC);
|
||||
|
||||
int newCollisionAddress = myStorage.getInt(collisionAddress + COLLISION_OFFSET);
|
||||
if (newCollisionAddress == 0) break;
|
||||
@@ -325,7 +320,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
|
||||
} else {
|
||||
if (hasMapping) {
|
||||
if(!saveNewValue) return indexNodeValueAddress;
|
||||
existingData = value;
|
||||
hasExistingData = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +339,7 @@ public class PersistentBTreeEnumerator<Data> extends PersistentEnumeratorBase<Da
|
||||
}
|
||||
|
||||
if (collisionAddress != NULL_ID) {
|
||||
if (existingData != null) {
|
||||
if (hasExistingData) {
|
||||
if (indexNodeValueAddress > 0) {
|
||||
btree.put(valueHC, newValueId);
|
||||
} else {
|
||||
|
||||
@@ -369,6 +369,56 @@ abstract class PersistentEnumeratorBase<Data> implements Forceable, Closeable {
|
||||
|
||||
protected abstract int enumerateImpl(final Data value, final boolean onlyCheckForExisting, boolean saveNewValue) throws IOException;
|
||||
|
||||
protected boolean isKeyAtIndex(Data value, int idx) throws IOException {
|
||||
if (myKeyStorage == null) return false;
|
||||
|
||||
// check if previous serialized state is the same as for value
|
||||
// this is much faster than myDataDescriptor.isEqualTo(valueOf(idx), value)
|
||||
final boolean sameValue[] = new boolean[1]; // TODO: key storage lock
|
||||
final int addr = indexToAddr(idx);
|
||||
OutputStream comparer;
|
||||
|
||||
if (myKeyStoreFileLength <= addr) {
|
||||
comparer = new OutputStream() {
|
||||
int address = addr - myKeyStoreFileLength;
|
||||
boolean same = true;
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
if (same) {
|
||||
same = address < myKeyStoreBufferPosition && myKeyStoreFileBuffer[address++] == (byte)b;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
sameValue[0] = same;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
comparer = new OutputStream() {
|
||||
int address = addr;
|
||||
boolean same = true;
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
if (same) {
|
||||
same = address < myKeyStoreFileLength && myKeyStorage.get(address++) == (byte)b;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
sameValue[0] = same;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
DataOutput out = new DataOutputStream(comparer);
|
||||
myDataDescriptor.save(out, value);
|
||||
comparer.close();
|
||||
|
||||
return sameValue[0];
|
||||
}
|
||||
|
||||
protected int writeData(final Data value, int hashCode) {
|
||||
try {
|
||||
markDirty(true);
|
||||
|
||||
Reference in New Issue
Block a user