mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SerializationManager refactored
This commit is contained in:
Generated
-3
@@ -90,9 +90,6 @@
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="haml">
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
</ADDITIONAL_INDENT_OPTIONS>
|
||||
<ADDITIONAL_INDENT_OPTIONS fileType="html">
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
|
||||
@@ -32,15 +32,6 @@ public abstract class SerializationManager {
|
||||
|
||||
public abstract void registerSerializer(StubSerializer<? extends StubElement> serializer);
|
||||
|
||||
public abstract void serialize(StubElement rootStub, OutputStream stream);
|
||||
|
||||
public abstract StubElement deserialize(InputStream stream);
|
||||
|
||||
public abstract StubSerializer getSerializer(StubElement rootStub);
|
||||
|
||||
public abstract boolean isNameStorageCorrupted();
|
||||
|
||||
public abstract void repairNameStorage();
|
||||
|
||||
public abstract void flushNameStorage();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Author: dmitrylomov
|
||||
*/
|
||||
public abstract class SerializationManagerEx extends SerializationManager {
|
||||
|
||||
public static SerializationManagerEx getInstanceEx() {
|
||||
return (SerializationManagerEx) SerializationManager.getInstance();
|
||||
}
|
||||
|
||||
public abstract void serialize(StubElement rootStub, OutputStream stream);
|
||||
|
||||
public abstract StubElement deserialize(InputStream stream);
|
||||
|
||||
public abstract boolean isNameStorageCorrupted();
|
||||
|
||||
public abstract void repairNameStorage();
|
||||
|
||||
public abstract void flushNameStorage();
|
||||
}
|
||||
+23
-88
@@ -17,9 +17,6 @@ package com.intellij.psi.stubs;
|
||||
|
||||
import com.intellij.openapi.diagnostic.LogUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
import com.intellij.util.io.AbstractStringEnumerator;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
@@ -29,37 +26,23 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author: dmitrylomov
|
||||
*/
|
||||
public abstract class SerializationManagerBase extends SerializationManager {
|
||||
public class StubSerializationHelper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.SerializationManagerBase");
|
||||
|
||||
protected AbstractStringEnumerator myNameStorage;
|
||||
private AbstractStringEnumerator myNameStorage;
|
||||
|
||||
protected final TIntObjectHashMap<StubSerializer<? extends StubElement>> myIdToSerializer = new TIntObjectHashMap<StubSerializer<? extends StubElement>>();
|
||||
protected final TObjectIntHashMap<StubSerializer<? extends StubElement>> mySerializerToId = new TObjectIntHashMap<StubSerializer<? extends StubElement>>();
|
||||
protected final List<StubSerializer<? extends StubElement>> myAllSerializers = new ArrayList<StubSerializer<? extends StubElement>>();
|
||||
private volatile boolean mySerializersLoaded = false;
|
||||
|
||||
public abstract boolean isNameStorageCorrupted();
|
||||
|
||||
public abstract void repairNameStorage();
|
||||
|
||||
public void registerSerializer(@NotNull StubSerializer<? extends StubElement> serializer) {
|
||||
myAllSerializers.add(serializer);
|
||||
try {
|
||||
assignId(serializer);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
nameStorageCrashed();
|
||||
}
|
||||
protected StubSerializationHelper(AbstractStringEnumerator nameStorage) {
|
||||
myNameStorage = nameStorage;
|
||||
}
|
||||
|
||||
protected void assignId(@NotNull final StubSerializer<? extends StubElement> serializer) throws IOException {
|
||||
public void assignId(@NotNull final StubSerializer<? extends StubElement> serializer) throws IOException {
|
||||
final int id = persistentId(serializer);
|
||||
final StubSerializer old = myIdToSerializer.put(id, serializer);
|
||||
assert old == null : "ID: " + serializer.getExternalId() + " is not unique; Already registered serializer with this ID: " + old.getClass().getName();
|
||||
@@ -75,79 +58,36 @@ public abstract class SerializationManagerBase extends SerializationManager {
|
||||
return myNameStorage.enumerate(serializer.getExternalId());
|
||||
}
|
||||
|
||||
private synchronized void initSerializers() {
|
||||
if (mySerializersLoaded) return;
|
||||
for(StubElementTypeHolderEP holderEP: Extensions.getExtensions(StubElementTypeHolderEP.EP_NAME)) {
|
||||
holderEP.initialize();
|
||||
}
|
||||
final IElementType[] stubElementTypes = IElementType.enumerate(new IElementType.Predicate() {
|
||||
public boolean matches(final IElementType type) {
|
||||
return type instanceof StubSerializer;
|
||||
}
|
||||
});
|
||||
for(IElementType type: stubElementTypes) {
|
||||
if (type instanceof IStubFileElementType && ((IStubFileElementType) type).getExternalId().equals(PsiFileStubImpl.TYPE.getExternalId())) {
|
||||
continue;
|
||||
}
|
||||
StubSerializer stubSerializer = (StubSerializer) type;
|
||||
private void doSerialize(final StubElement rootStub, final StubOutputStream stream) throws IOException {
|
||||
final StubSerializer serializer = SerializationManager.getInstance().getSerializer(rootStub);
|
||||
|
||||
if (!myAllSerializers.contains(stubSerializer)) {
|
||||
registerSerializer(stubSerializer);
|
||||
}
|
||||
DataInputOutputUtil.writeINT(stream, getClassId(serializer));
|
||||
serializer.serialize(rootStub, stream);
|
||||
|
||||
final List<StubElement> children = rootStub.getChildrenStubs();
|
||||
final int childrenSize = children.size();
|
||||
DataInputOutputUtil.writeINT(stream, childrenSize);
|
||||
for (int i = 0; i < childrenSize; ++i) {
|
||||
doSerialize(children.get(i), stream);
|
||||
}
|
||||
mySerializersLoaded = true;
|
||||
}
|
||||
|
||||
public void serialize(StubElement rootStub, OutputStream stream) {
|
||||
if (!mySerializersLoaded) initSerializers();
|
||||
public void serialize(StubElement rootStub, OutputStream stream) throws IOException {
|
||||
StubOutputStream stubOutputStream = new StubOutputStream(stream, myNameStorage);
|
||||
doSerialize(rootStub, stubOutputStream);
|
||||
}
|
||||
|
||||
private void doSerialize(final StubElement rootStub, final StubOutputStream stream) {
|
||||
try {
|
||||
final StubSerializer serializer = getSerializer(rootStub);
|
||||
|
||||
DataInputOutputUtil.writeINT(stream, getClassId(serializer));
|
||||
serializer.serialize(rootStub, stream);
|
||||
|
||||
final List<StubElement> children = rootStub.getChildrenStubs();
|
||||
final int childrenSize = children.size();
|
||||
DataInputOutputUtil.writeINT(stream, childrenSize);
|
||||
for (int i = 0; i < childrenSize; ++i) {
|
||||
doSerialize(children.get(i), stream);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
nameStorageCrashed();
|
||||
}
|
||||
private int getClassId(final StubSerializer serializer) {
|
||||
final int idValue = mySerializerToId.get(serializer);
|
||||
assert idValue != 0: "No ID found for serializer " + LogUtil.objectAndClass(serializer);
|
||||
return idValue;
|
||||
}
|
||||
|
||||
public StubSerializer getSerializer(final StubElement rootStub) {
|
||||
if (rootStub instanceof PsiFileStub) {
|
||||
final PsiFileStub fileStub = (PsiFileStub)rootStub;
|
||||
return fileStub.getType();
|
||||
}
|
||||
|
||||
return rootStub.getStubType();
|
||||
}
|
||||
|
||||
public StubElement deserialize(InputStream stream) {
|
||||
public StubElement deserialize(InputStream stream) throws IOException {
|
||||
StubInputStream inputStream = new StubInputStream(stream, myNameStorage);
|
||||
if (!mySerializersLoaded) initSerializers();
|
||||
try {
|
||||
return deserialize(inputStream, null);
|
||||
}
|
||||
catch (IOException e) {
|
||||
nameStorageCrashed();
|
||||
LOG.info(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return deserialize(inputStream, null);
|
||||
}
|
||||
|
||||
protected abstract void nameStorageCrashed();
|
||||
|
||||
private StubElement deserialize(StubInputStream stream, StubElement parentStub) throws IOException {
|
||||
final int id = DataInputOutputUtil.readINT(stream);
|
||||
final StubSerializer serializer = getClassById(id);
|
||||
@@ -162,11 +102,6 @@ public abstract class SerializationManagerBase extends SerializationManager {
|
||||
return stub;
|
||||
}
|
||||
|
||||
private int getClassId(final StubSerializer serializer) {
|
||||
final int idValue = mySerializerToId.get(serializer);
|
||||
assert idValue != 0: "No ID found for serializer " + LogUtil.objectAndClass(serializer);
|
||||
return idValue;
|
||||
}
|
||||
|
||||
private StubSerializer getClassById(int id) {
|
||||
return myIdToSerializer.get(id);
|
||||
@@ -58,7 +58,7 @@ public class SerializedStubTree {
|
||||
myStubElement = null;
|
||||
if (willIndexStub) return stubElement;
|
||||
}
|
||||
return SerializationManager.getInstance().deserialize(new UnsyncByteArrayInputStream(myBytes));
|
||||
return SerializationManagerEx.getInstanceEx().deserialize(new UnsyncByteArrayInputStream(myBytes));
|
||||
}
|
||||
|
||||
public boolean equals(final Object that) {
|
||||
|
||||
@@ -17,25 +17,41 @@ package com.intellij.psi.stubs;
|
||||
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.diagnostic.LogUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.ShutDownTracker;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
import com.intellij.util.io.AbstractStringEnumerator;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import com.intellij.util.io.PersistentStringEnumerator;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
public class SerializationManagerImpl extends SerializationManagerBase implements ApplicationComponent {
|
||||
public class SerializationManagerImpl extends SerializationManagerEx implements ApplicationComponent {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.SerializationManagerImpl");
|
||||
|
||||
private final AtomicBoolean myNameStorageCrashed = new AtomicBoolean(false);
|
||||
private final File myFile = new File(PathManager.getIndexRoot(), "rep.names");
|
||||
private final AtomicBoolean myShutdownPerformed = new AtomicBoolean(false);
|
||||
private AbstractStringEnumerator myNameStorage;
|
||||
private final List<StubSerializer<? extends StubElement>> myAllSerializers = new ArrayList<StubSerializer<? extends StubElement>>();
|
||||
private StubSerializationHelper myStubSerializationHelper;
|
||||
private volatile boolean mySerializersLoaded = false;
|
||||
|
||||
public SerializationManagerImpl() {
|
||||
myFile.getParentFile().mkdirs();
|
||||
@@ -43,6 +59,7 @@ public class SerializationManagerImpl extends SerializationManagerBase implement
|
||||
// we need to cache last id -> String mappings due to StringRefs and stubs indexing that initially creates stubs (doing enumerate on String)
|
||||
// and then index them (valueOf), also similar string items are expected to be enumerated during stubs processing
|
||||
myNameStorage = new PersistentStringEnumerator(myFile, true);
|
||||
myStubSerializationHelper = new StubSerializationHelper(myNameStorage);
|
||||
}
|
||||
catch (IOException e) {
|
||||
nameStorageCrashed();
|
||||
@@ -60,12 +77,10 @@ public class SerializationManagerImpl extends SerializationManagerBase implement
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNameStorageCorrupted() {
|
||||
return myNameStorageCrashed.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repairNameStorage() {
|
||||
if (myNameStorageCrashed.getAndSet(false)) {
|
||||
try {
|
||||
@@ -82,10 +97,9 @@ public class SerializationManagerImpl extends SerializationManagerBase implement
|
||||
}
|
||||
}
|
||||
myNameStorage = new PersistentStringEnumerator(myFile, true);
|
||||
mySerializerToId.clear();
|
||||
myIdToSerializer.clear();
|
||||
myStubSerializationHelper = new StubSerializationHelper(myNameStorage);
|
||||
for (StubSerializer<? extends StubElement> serializer : myAllSerializers) {
|
||||
assignId(serializer);
|
||||
myStubSerializationHelper.assignId(serializer);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -100,7 +114,6 @@ public class SerializationManagerImpl extends SerializationManagerBase implement
|
||||
myNameStorage.force();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void nameStorageCrashed() {
|
||||
myNameStorageCrashed.set(true);
|
||||
}
|
||||
@@ -130,4 +143,72 @@ public class SerializationManagerImpl extends SerializationManagerBase implement
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerSerializer(@NotNull StubSerializer<? extends StubElement> serializer) {
|
||||
myAllSerializers.add(serializer);
|
||||
try {
|
||||
myStubSerializationHelper.assignId(serializer);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
nameStorageCrashed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void initSerializers() {
|
||||
if (mySerializersLoaded) return;
|
||||
for(StubElementTypeHolderEP holderEP: Extensions.getExtensions(StubElementTypeHolderEP.EP_NAME)) {
|
||||
holderEP.initialize();
|
||||
}
|
||||
final IElementType[] stubElementTypes = IElementType.enumerate(new IElementType.Predicate() {
|
||||
public boolean matches(final IElementType type) {
|
||||
return type instanceof StubSerializer;
|
||||
}
|
||||
});
|
||||
for(IElementType type: stubElementTypes) {
|
||||
if (type instanceof IStubFileElementType && ((IStubFileElementType) type).getExternalId().equals(PsiFileStubImpl.TYPE.getExternalId())) {
|
||||
continue;
|
||||
}
|
||||
StubSerializer stubSerializer = (StubSerializer) type;
|
||||
|
||||
if (!myAllSerializers.contains(stubSerializer)) {
|
||||
registerSerializer(stubSerializer);
|
||||
}
|
||||
}
|
||||
mySerializersLoaded = true;
|
||||
}
|
||||
|
||||
public void serialize(StubElement rootStub, OutputStream stream) {
|
||||
if (!mySerializersLoaded) initSerializers();
|
||||
try {
|
||||
myStubSerializationHelper.serialize(rootStub, stream);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
nameStorageCrashed();
|
||||
}
|
||||
}
|
||||
|
||||
public StubSerializer getSerializer(final StubElement rootStub) {
|
||||
if (rootStub instanceof PsiFileStub) {
|
||||
final PsiFileStub fileStub = (PsiFileStub)rootStub;
|
||||
return fileStub.getType();
|
||||
}
|
||||
|
||||
return rootStub.getStubType();
|
||||
}
|
||||
|
||||
public StubElement deserialize(InputStream stream) {
|
||||
if (!mySerializersLoaded) initSerializers();
|
||||
|
||||
try {
|
||||
return myStubSerializationHelper.deserialize(stream);
|
||||
}
|
||||
catch (IOException e) {
|
||||
nameStorageCrashed();
|
||||
LOG.info(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class SerializedStubTree {
|
||||
myStubElement = null;
|
||||
if (willIndexStub) return stubElement;
|
||||
}
|
||||
return SerializationManager.getInstance().deserialize(new UnsyncByteArrayInputStream(myBytes));
|
||||
return SerializationManagerEx.getInstanceEx().deserialize(new UnsyncByteArrayInputStream(myBytes));
|
||||
}
|
||||
|
||||
public boolean equals(final Object that) {
|
||||
|
||||
@@ -118,7 +118,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
if (rootStub == null) return;
|
||||
|
||||
final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream();
|
||||
SerializationManager.getInstance().serialize(rootStub, bytes);
|
||||
SerializationManagerEx.getInstanceEx().serialize(rootStub, bytes);
|
||||
|
||||
final int key = Math.abs(FileBasedIndex.getFileId(inputData.getFile()));
|
||||
result.put(key, new SerializedStubTree(bytes.getInternalBuffer(), bytes.size(), rootStub));
|
||||
@@ -294,7 +294,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
|
||||
}
|
||||
|
||||
private static void checkNameStorage() throws StorageException {
|
||||
final SerializationManager serializationManager = SerializationManager.getInstance();
|
||||
final SerializationManagerEx serializationManager = SerializationManagerEx.getInstanceEx();
|
||||
if (serializationManager.isNameStorageCorrupted()) {
|
||||
serializationManager.repairNameStorage();
|
||||
//noinspection ThrowFromFinallyBlock
|
||||
|
||||
@@ -58,6 +58,7 @@ import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.search.EverythingGlobalScope;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubs.SerializationManager;
|
||||
import com.intellij.psi.stubs.SerializationManagerEx;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.containers.ConcurrentHashSet;
|
||||
@@ -657,7 +658,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
}
|
||||
|
||||
if (!HeavyProcessLatch.INSTANCE.isRunning() && modCount == myLocalModCount) { // do not interfere with 'main' jobs
|
||||
SerializationManager.getInstance().flushNameStorage();
|
||||
SerializationManagerEx.getInstanceEx().flushNameStorage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user