From db8aadc5e366060b285eb1000666278f71688fc1 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 7 Jun 2012 17:16:44 +0400 Subject: [PATCH] when enumerating nontrivial key, instead of valueOf / equals on existing previous key do compare serialized bytes of current key with previous one --- .../intellij/psi/search/FileTypeIndex.java | 14 +++++- .../util/io/PersistentBTreeEnumerator.java | 21 +++----- .../util/io/PersistentEnumeratorBase.java | 50 +++++++++++++++++++ 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/search/FileTypeIndex.java b/platform/lang-impl/src/com/intellij/psi/search/FileTypeIndex.java index c36d0c19eead..b81138eb54c8 100644 --- a/platform/lang-impl/src/com/intellij/psi/search/FileTypeIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/search/FileTypeIndex.java @@ -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 @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 diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java index 08ce0aa49f54..c9fe6310e96d 100644 --- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java +++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java @@ -281,24 +281,21 @@ public class PersistentBTreeEnumerator extends PersistentEnumeratorBase 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 extends PersistentEnumeratorBase extends PersistentEnumeratorBase extends PersistentEnumeratorBase 0) { btree.put(valueHC, newValueId); } else { diff --git a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java index 88e0b48ad938..23d7aa030ce8 100644 --- a/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java +++ b/platform/util/src/com/intellij/util/io/PersistentEnumeratorBase.java @@ -369,6 +369,56 @@ abstract class PersistentEnumeratorBase 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);