From 12f5fa9fffe601fedf5fedd3a142e2cf4310cdf6 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 2 Aug 2012 15:44:36 +0400 Subject: [PATCH] DOM stubs: stub serialization decoupled from PSI --- .../psi/stubs/ObjectStubSerializer.java | 35 +++++++++++++++++++ .../src/com/intellij/psi/stubs/Stub.java | 30 ++++++++++++++++ .../com/intellij/psi/stubs/StubElement.java | 2 +- .../psi/stubs/StubSerializationHelper.java | 30 ++++++++-------- .../psi/stubs/StubSerializationUtil.java | 2 +- .../intellij/psi/stubs/StubSerializer.java | 2 +- .../psi/stubs/CoreStubTreeLoader.java | 2 +- .../intellij/psi/stubs/StubTreeBuilder.java | 6 ++-- .../psi/stubs/SerializationManagerEx.java | 4 +-- .../psi/stubs/SerializationManagerImpl.java | 4 +-- .../psi/stubs/SerializedStubTree.java | 8 ++--- .../psi/stubs/StubTreeLoaderImpl.java | 4 +-- .../intellij/psi/stubs/StubUpdatingIndex.java | 2 +- .../util/xml/stubs/DomStubElement.java | 23 ++++++++++++ 14 files changed, 121 insertions(+), 33 deletions(-) create mode 100644 platform/core-api/src/com/intellij/psi/stubs/ObjectStubSerializer.java create mode 100644 platform/core-api/src/com/intellij/psi/stubs/Stub.java create mode 100644 xml/dom-impl/src/com/intellij/util/xml/stubs/DomStubElement.java diff --git a/platform/core-api/src/com/intellij/psi/stubs/ObjectStubSerializer.java b/platform/core-api/src/com/intellij/psi/stubs/ObjectStubSerializer.java new file mode 100644 index 000000000000..d669cd2f2ee8 --- /dev/null +++ b/platform/core-api/src/com/intellij/psi/stubs/ObjectStubSerializer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.stubs; + +import org.jetbrains.annotations.NonNls; + +import java.io.IOException; + +/** + * @author Dmitry Avdeev + * Date: 8/2/12 + */ +public interface ObjectStubSerializer { + @NonNls + String getExternalId(); + + void serialize(T stub, StubOutputStream dataStream) throws IOException; + T deserialize(StubInputStream dataStream, final P parentStub) throws IOException; + + void indexStub(T stub, IndexSink sink); + +} diff --git a/platform/core-api/src/com/intellij/psi/stubs/Stub.java b/platform/core-api/src/com/intellij/psi/stubs/Stub.java new file mode 100644 index 000000000000..71471c4bfcd9 --- /dev/null +++ b/platform/core-api/src/com/intellij/psi/stubs/Stub.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.stubs; + +import java.util.List; + +/** + * @author Dmitry Avdeev + * Date: 8/2/12 + */ +public interface Stub { + + Stub getParentStub(); + List getChildrenStubs(); + ObjectStubSerializer getStubType(); + +} diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubElement.java b/platform/core-api/src/com/intellij/psi/stubs/StubElement.java index 04212b342f4d..69eebee1a865 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/StubElement.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubElement.java @@ -27,7 +27,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -public interface StubElement { +public interface StubElement extends Stub { IStubElementType getStubType(); StubElement getParentStub(); List getChildrenStubs(); diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java index 40782e8a0625..67ba80030965 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java @@ -42,36 +42,36 @@ import java.util.concurrent.locks.Lock; public class StubSerializationHelper { private AbstractStringEnumerator myNameStorage; - protected final TIntObjectHashMap> myIdToSerializer = new TIntObjectHashMap>(); - protected final TObjectIntHashMap> mySerializerToId = new TObjectIntHashMap>(); + protected final TIntObjectHashMap myIdToSerializer = new TIntObjectHashMap(); + protected final TObjectIntHashMap mySerializerToId = new TObjectIntHashMap(); public StubSerializationHelper(AbstractStringEnumerator nameStorage) { myNameStorage = nameStorage; } - public void assignId(@NotNull final StubSerializer serializer) throws IOException { + public void assignId(@NotNull final ObjectStubSerializer serializer) throws IOException { final int id = persistentId(serializer); - final StubSerializer old = myIdToSerializer.put(id, serializer); + final ObjectStubSerializer old = myIdToSerializer.put(id, serializer); assert old == null : "ID: " + serializer.getExternalId() + " is not unique; Already registered serializer with this ID: " + old.getClass().getName(); final int oldId = mySerializerToId.put(serializer, id); assert oldId == 0 : "Serializer " + serializer + " is already registered; Old ID:" + oldId; } - private int persistentId(@NotNull final StubSerializer serializer) throws IOException { + private int persistentId(@NotNull final ObjectStubSerializer serializer) throws IOException { if (myNameStorage == null) { throw new IOException("SerializationManager's name storage failed to initialize"); } return myNameStorage.enumerate(serializer.getExternalId()); } - private void doSerialize(final StubElement rootStub, final StubOutputStream stream) throws IOException { - final StubSerializer serializer = StubSerializationUtil.getSerializer(rootStub); + private void doSerialize(final Stub rootStub, final StubOutputStream stream) throws IOException { + final ObjectStubSerializer serializer = StubSerializationUtil.getSerializer(rootStub); DataInputOutputUtil.writeINT(stream, getClassId(serializer)); serializer.serialize(rootStub, stream); - final List children = rootStub.getChildrenStubs(); + final List children = rootStub.getChildrenStubs(); final int childrenSize = children.size(); DataInputOutputUtil.writeINT(stream, childrenSize); for (int i = 0; i < childrenSize; ++i) { @@ -79,7 +79,7 @@ public class StubSerializationHelper { } } - public void serialize(StubElement rootStub, OutputStream stream) throws IOException { + public void serialize(Stub rootStub, OutputStream stream) throws IOException { BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(); FileLocalStringEnumerator storage = new FileLocalStringEnumerator(); StubOutputStream stubOutputStream = new StubOutputStream(out, storage); @@ -94,7 +94,7 @@ public class StubSerializationHelper { resultStream.write(out.getInternalBuffer(), 0, out.size()); } - private int getClassId(final StubSerializer serializer) { + private int getClassId(final ObjectStubSerializer serializer) { final int idValue = mySerializerToId.get(serializer); assert idValue != 0: "No ID found for serializer " + LogUtil.objectAndClass(serializer); return idValue; @@ -152,7 +152,7 @@ public class StubSerializationHelper { private final RecentStringInterner myStringInterner = new RecentStringInterner(8192); - public StubElement deserialize(InputStream stream) throws IOException { + public Stub deserialize(InputStream stream) throws IOException { FileLocalStringEnumerator storage = new FileLocalStringEnumerator(); StubInputStream inputStream = new StubInputStream(stream, storage); final int size = DataInputOutputUtil.readINT(inputStream); @@ -168,13 +168,13 @@ public class StubSerializationHelper { return deserialize(inputStream, null); } - private StubElement deserialize(StubInputStream stream, StubElement parentStub) throws IOException { + private Stub deserialize(StubInputStream stream, Stub parentStub) throws IOException { final int id = DataInputOutputUtil.readINT(stream); - final StubSerializer serializer = getClassById(id); + final ObjectStubSerializer serializer = getClassById(id); assert serializer != null : "No serializer registered for stub: ID=" + id + "; parent stub class=" + (parentStub != null? parentStub.getClass().getName() : "null"); - StubElement stub = serializer.deserialize(stream, parentStub); + Stub stub = serializer.deserialize(stream, parentStub); int childCount = DataInputOutputUtil.readINT(stream); for (int i = 0; i < childCount; i++) { deserialize(stream, stub); @@ -183,7 +183,7 @@ public class StubSerializationHelper { } - private StubSerializer getClassById(int id) { + private ObjectStubSerializer getClassById(int id) { return myIdToSerializer.get(id); } diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationUtil.java b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationUtil.java index 45f610676d80..33611d9c0e3b 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationUtil.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationUtil.java @@ -21,7 +21,7 @@ package com.intellij.psi.stubs; public abstract class StubSerializationUtil { private StubSerializationUtil() {} - public static StubSerializer getSerializer(StubElement rootStub) { + public static ObjectStubSerializer getSerializer(Stub rootStub) { if (rootStub instanceof PsiFileStub) { final PsiFileStub fileStub = (PsiFileStub)rootStub; return fileStub.getType(); diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubSerializer.java b/platform/core-api/src/com/intellij/psi/stubs/StubSerializer.java index d39204ee5010..be3527808370 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/StubSerializer.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubSerializer.java @@ -22,7 +22,7 @@ import java.io.IOException; /* * @author max */ -public interface StubSerializer { +public interface StubSerializer extends ObjectStubSerializer { @NonNls String getExternalId(); diff --git a/platform/core-impl/src/com/intellij/psi/stubs/CoreStubTreeLoader.java b/platform/core-impl/src/com/intellij/psi/stubs/CoreStubTreeLoader.java index 79d9aba68ac8..970b22ae6ec2 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/CoreStubTreeLoader.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/CoreStubTreeLoader.java @@ -45,7 +45,7 @@ public class CoreStubTreeLoader extends StubTreeLoader { try { final FileContent fc = new FileContentImpl(vFile, vFile.contentsToByteArray()); fc.putUserData(IndexingDataKeys.PROJECT, project); - final StubElement element = StubTreeBuilder.buildStubTree(fc); + final Stub element = StubTreeBuilder.buildStubTree(fc); if (element instanceof PsiFileStub) { return new StubTree((PsiFileStub)element); } diff --git a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java index 87e9ac441b6d..849f4f7c5697 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java @@ -29,14 +29,14 @@ import com.intellij.util.indexing.SubstitutedFileType; import org.jetbrains.annotations.Nullable; public class StubTreeBuilder { - private static final Key stubElementKey = Key.create("stub.tree.for.file.content"); + private static final Key stubElementKey = Key.create("stub.tree.for.file.content"); private StubTreeBuilder() { } @Nullable - public static StubElement buildStubTree(final FileContent inputData) { - StubElement data = inputData.getUserData(stubElementKey); + public static Stub buildStubTree(final FileContent inputData) { + Stub data = inputData.getUserData(stubElementKey); if (data != null) return data; //noinspection SynchronizationOnLocalVariableOrMethodParameter diff --git a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java index 55f72005403d..eca9a71fe73f 100644 --- a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java +++ b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerEx.java @@ -27,9 +27,9 @@ public abstract class SerializationManagerEx extends SerializationManager { return (SerializationManagerEx) SerializationManager.getInstance(); } - public abstract void serialize(StubElement rootStub, OutputStream stream); + public abstract void serialize(Stub rootStub, OutputStream stream); - public abstract StubElement deserialize(InputStream stream); + public abstract Stub deserialize(InputStream stream); public abstract boolean isNameStorageCorrupted(); diff --git a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java index e438e9d38b59..f96ea6b32913 100644 --- a/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java +++ b/platform/lang-api/src/com/intellij/psi/stubs/SerializationManagerImpl.java @@ -146,7 +146,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements - public void serialize(StubElement rootStub, OutputStream stream) { + public void serialize(Stub rootStub, OutputStream stream) { initSerializers(); try { myStubSerializationHelper.serialize(rootStub, stream); @@ -158,7 +158,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements } - public StubElement deserialize(InputStream stream) { + public Stub deserialize(InputStream stream) { initSerializers(); try { diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java b/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java index 29e72ac38e26..8be417f457e8 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java @@ -30,9 +30,9 @@ import java.io.IOException; public class SerializedStubTree { private final byte[] myBytes; private final int myLength; - private StubElement myStubElement; + private Stub myStubElement; - public SerializedStubTree(final byte[] bytes, int length, @Nullable StubElement stubElement) { + public SerializedStubTree(final byte[] bytes, int length, @Nullable Stub stubElement) { myBytes = bytes; myLength = length; myStubElement = stubElement; @@ -48,8 +48,8 @@ public class SerializedStubTree { } // willIndexStub is one time optimization hint, once can safely pass false - public StubElement getStub(boolean willIndexStub) { - StubElement stubElement = myStubElement; + public Stub getStub(boolean willIndexStub) { + Stub stubElement = myStubElement; if (stubElement != null) { // not null myStubElement means we just built SerializedStubTree for indexing, // if we request stub for indexing we can safely use it diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java index 7be14457a75a..f08b62e5b8c0 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubTreeLoaderImpl.java @@ -60,7 +60,7 @@ public class StubTreeLoaderImpl extends StubTreeLoader { } psiFile.putUserData(PsiFileImpl.BUILDING_STUB, true); } - StubElement element; + Stub element; try { element = StubTreeBuilder.buildStubTree(fc); } @@ -94,7 +94,7 @@ public class StubTreeLoaderImpl extends StubTreeLoader { final int size = datas.size(); if (size == 1) { - StubElement stub = datas.get(0).getStub(false); + Stub stub = datas.get(0).getStub(false); return new StubTree((PsiFileStub)stub); } else if (size != 0) { diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index a784e3cb85ef..c35b1283318c 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -118,7 +118,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { - final StubElement rootStub = StubTreeBuilder.buildStubTree(inputData); + final Stub rootStub = StubTreeBuilder.buildStubTree(inputData); if (rootStub == null) return; final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream(); diff --git a/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStubElement.java b/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStubElement.java new file mode 100644 index 000000000000..16f36ad2ab33 --- /dev/null +++ b/xml/dom-impl/src/com/intellij/util/xml/stubs/DomStubElement.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.xml.stubs; + +/** + * @author Dmitry Avdeev + * Date: 8/2/12 + */ +public class DomStubElement { +}