From 076de9ccba70d1e83c31c927ecb09cef86ef44ed Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 6 May 2020 08:55:17 +0300 Subject: [PATCH] indexes: refactor key storage into 2 implementations GitOrigin-RevId: 9920bfedef81d3a44864beaa4dfc0d665aceff81 --- .../indexing/VfsAwareMapIndexStorage.java | 35 ++-- .../intellij/util/io/PagedFileStorage.java | 8 +- .../util/io/PersistentBTreeEnumerator.java | 8 +- .../util/io/PersistentEnumeratorBase.java | 54 +++--- .../keyStorage/AppendableObjectStorage.java | 25 +++ ...bleStorageBackedByResizableMappedFile.java | 166 +++++------------- .../util/io/keyStorage/InlinedKeyStorage.java | 67 +++++++ .../io/{ => keyStorage}/NoDataException.java | 6 +- .../util/io/keyStorage/package-info.java | 5 + 9 files changed, 195 insertions(+), 179 deletions(-) create mode 100644 platform/util/src/com/intellij/util/io/keyStorage/AppendableObjectStorage.java rename platform/util/src/com/intellij/util/io/{ => keyStorage}/AppendableStorageBackedByResizableMappedFile.java (54%) create mode 100644 platform/util/src/com/intellij/util/io/keyStorage/InlinedKeyStorage.java rename platform/util/src/com/intellij/util/io/{ => keyStorage}/NoDataException.java (67%) create mode 100644 platform/util/src/com/intellij/util/io/keyStorage/package-info.java diff --git a/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapIndexStorage.java index 92de63d3438a..9a85d554f3ff 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapIndexStorage.java @@ -32,6 +32,8 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.impl.MapIndexStorage; import com.intellij.util.io.DataOutputStream; import com.intellij.util.io.*; +import com.intellij.util.io.keyStorage.AppendableObjectStorage; +import com.intellij.util.io.keyStorage.AppendableStorageBackedByResizableMappedFile; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,7 +50,7 @@ public final class VfsAwareMapIndexStorage extends MapIndexStorage myKeyHashToVirtualFileMapping; private volatile int myLastScannedId; private static final ConcurrentIntObjectMap ourInvalidatedSessionIds = ContainerUtil.createConcurrentIntObjectMap(); @@ -82,7 +84,7 @@ public final class VfsAwareMapIndexStorage extends MapIndexStorage(getProjectFile(), 4096, null, PagedFileStorage.MB, true, IntPairInArrayKeyDescriptor.INSTANCE); } else { myKeyHashToVirtualFileMapping = null; @@ -100,11 +102,11 @@ public final class VfsAwareMapIndexStorage extends MapIndexStorage void withLock(ThrowableRunnable r) throws T { - myKeyHashToVirtualFileMapping.getPagedFileStorage().lock(); + myKeyHashToVirtualFileMapping.lock(); try { r.run(); } finally { - myKeyHashToVirtualFileMapping.getPagedFileStorage().unlock(); + myKeyHashToVirtualFileMapping.unlock(); } } @@ -126,21 +128,30 @@ public final class VfsAwareMapIndexStorage extends MapIndexStorage myKeyHashToVirtualFileMapping.close()); - } + closeKeyHashToFileMapping(); } catch (RuntimeException e) { unwrapCauseAndRethrow(e); } } + private void closeKeyHashToFileMapping() throws StorageException { + if (myKeyHashToVirtualFileMapping != null) { + try { + withLock(() -> { + myKeyHashToVirtualFileMapping.close(); + }); + } + catch (IOException e) { + throw new StorageException(e); + } + } + } + @Override public void clear() throws StorageException{ try { - if (myKeyHashToVirtualFileMapping != null) { - withLock(() -> myKeyHashToVirtualFileMapping.close()); - } + closeKeyHashToFileMapping(); } catch (RuntimeException e) { LOG.info(e); @@ -198,7 +209,7 @@ public final class VfsAwareMapIndexStorage extends MapIndexStorage extends MapIndexStorage myKeyHashToVirtualFileMapping.append(new int[] { myKeyDescriptor.getHashCode(key), inputId }, IntPairInArrayKeyDescriptor.INSTANCE)); + withLock(() -> myKeyHashToVirtualFileMapping.append(new int[] { myKeyDescriptor.getHashCode(key), inputId })); int lastScannedId = myLastScannedId; if (lastScannedId != 0) { // we have write lock ourInvalidatedSessionIds.cacheOrGet(lastScannedId, Boolean.TRUE); diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java index 7b0d8e8c055a..8fa66e9d4e4a 100644 --- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java +++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java @@ -108,6 +108,10 @@ public class PagedFileStorage implements Forceable { myNativeBytesOrder = nativeBytesOrder; } + public int getPageSize() { + return myPageSize; + } + public void lock() { myStorageLockContext.lock(); } @@ -157,11 +161,11 @@ public class PagedFileStorage implements Forceable { } } - int getOffsetInPage(long addr) { + public int getOffsetInPage(long addr) { return (int)(addr % myPageSize); } - ByteBufferWrapper getByteBuffer(long address, boolean modify) { + public ByteBufferWrapper getByteBuffer(long address, boolean modify) { long page = address / myPageSize; assert page >= 0 && page <= MAX_PAGES_COUNT:address + " in " + myFile; return getBufferWrapper(page, modify); diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java index f7bff9f32e18..1893526b7cc8 100644 --- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java +++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java @@ -86,8 +86,8 @@ public class PersistentBTreeEnumerator extends PersistentEnumeratorBase extends PersistentEnumeratorBase implements DataEnumeratorEx private static final CacheKey ourFlyweight = new FlyweightKey(); protected final ResizeableMappedFile myStorage; - private final boolean myAssumeDifferentSerializedBytesMeansObjectsInequality; - private final AppendableStorageBackedByResizableMappedFile myKeyStorage; + @NotNull + private final AppendableObjectStorage myKeyStorage; final KeyDescriptor myDataDescriptor; protected final Path myFile; private final Version myVersion; @@ -90,10 +93,10 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx } private static class CacheKey implements ShareableKey { - public PersistentEnumeratorBase owner; + public PersistentEnumeratorBase owner; public Object key; - private CacheKey(Object key, PersistentEnumeratorBase owner) { + private CacheKey(Object key, PersistentEnumeratorBase owner) { this.key = key; this.owner = owner; } @@ -231,11 +234,16 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx } if (dataDescriptor instanceof InlineKeyDescriptor) { - myKeyStorage = null; + myKeyStorage = new InlinedKeyStorage<>((InlineKeyDescriptor)dataDescriptor); } else { try { - myKeyStorage = new AppendableStorageBackedByResizableMappedFile(keyStreamFile(), initialSize, myStorage.getPagedFileStorage().getStorageLockContext(), PagedFileStorage.MB, false); + myKeyStorage = new AppendableStorageBackedByResizableMappedFile<>(keyStreamFile(), + initialSize, + myStorage.getPagedFileStorage().getStorageLockContext(), + PagedFileStorage.MB, + false, + dataDescriptor); } catch (Throwable e) { LOG.info(e); @@ -243,7 +251,6 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx throw new CorruptedException(file); } } - myAssumeDifferentSerializedBytesMeansObjectsInequality = myDataDescriptor instanceof DifferentSerializableBytesImplyNonEqualityPolicy; } void lockStorage() { @@ -396,15 +403,16 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx protected abstract int enumerateImpl(final Data value, final boolean onlyCheckForExisting, boolean saveNewValue) throws IOException; protected boolean isKeyAtIndex(final Data value, final int idx) throws IOException { - if (myKeyStorage == null) return false; + if (myKeyStorage instanceof InlinedKeyStorage) return false; // check if previous serialized state is the same as for value // this is much faster than myDataDescriptor.isEqualTo(valueOf(idx), value) for identical objects // TODO: key storage lock final int addr = indexToAddr(idx); - if (myKeyStorage.checkBytesAreTheSame(addr, value, myDataDescriptor)) return true; - if (myAssumeDifferentSerializedBytesMeansObjectsInequality) return false; + if (myKeyStorage.checkBytesAreTheSame(addr, value)) return true; + + if (myDataDescriptor instanceof DifferentSerializableBytesImplyNonEqualityPolicy) return false; return myDataDescriptor.isEqual(valueOf(idx), value); } @@ -422,16 +430,11 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx } public int getLargestId() { - assert myKeyStorage != null; return myKeyStorage.getCurrentLength(); } protected int doWriteData(Data value) throws IOException { - if (myKeyStorage != null) { - return myKeyStorage.append(value, myDataDescriptor); - - } - return ((InlineKeyDescriptor)myDataDescriptor).toInt(value); + return myKeyStorage.append(value); } protected int setupValueId(int hashCode, int dataOff) { @@ -444,10 +447,6 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx } public boolean iterateData(@NotNull Processor processor) throws IOException { - if (myKeyStorage == null) { - throw new UnsupportedOperationException("Iteration over InlineIntegerKeyDescriptors is not supported"); - } - lockStorage(); // todo locking in key storage try { myKeyStorage.force(); @@ -456,7 +455,7 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx unlockStorage(); } - return myKeyStorage.processAll(processor, myDataDescriptor); + return myKeyStorage.processAll(processor); } private Path keyStreamFile() { @@ -472,8 +471,7 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx try { int addr = indexToAddr(idx); - if (myKeyStorage == null) return ((InlineKeyDescriptor)myDataDescriptor).fromInt(addr); - return myKeyStorage.read(addr, myDataDescriptor); + return myKeyStorage.read(addr); } finally { unlockStorage(); @@ -520,9 +518,7 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx protected void doClose() throws IOException { try { - if (myKeyStorage != null) { - myKeyStorage.close(); - } + myKeyStorage.close(); flush(); } finally { @@ -565,9 +561,7 @@ public abstract class PersistentEnumeratorBase implements DataEnumeratorEx lockStorage(); try { - if (myKeyStorage != null) { - myKeyStorage.force(); - } + myKeyStorage.force(); flush(); } catch (IOException e) { diff --git a/platform/util/src/com/intellij/util/io/keyStorage/AppendableObjectStorage.java b/platform/util/src/com/intellij/util/io/keyStorage/AppendableObjectStorage.java new file mode 100644 index 000000000000..bf5f192668fb --- /dev/null +++ b/platform/util/src/com/intellij/util/io/keyStorage/AppendableObjectStorage.java @@ -0,0 +1,25 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.util.io.keyStorage; + +import com.intellij.openapi.Forceable; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; + +import java.io.Closeable; +import java.io.IOException; + +public interface AppendableObjectStorage extends Forceable, Closeable { + Data read(int addr) throws IOException; + + boolean processAll(@NotNull Processor processor) throws IOException; + + int append(Data value) throws IOException; + + boolean checkBytesAreTheSame(int addr, Data value) throws IOException; + + void lock(); + + void unlock(); + + int getCurrentLength(); +} diff --git a/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java b/platform/util/src/com/intellij/util/io/keyStorage/AppendableStorageBackedByResizableMappedFile.java similarity index 54% rename from platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java rename to platform/util/src/com/intellij/util/io/keyStorage/AppendableStorageBackedByResizableMappedFile.java index 20ef8d8d3261..94b619a77d4f 100644 --- a/platform/util/src/com/intellij/util/io/AppendableStorageBackedByResizableMappedFile.java +++ b/platform/util/src/com/intellij/util/io/keyStorage/AppendableStorageBackedByResizableMappedFile.java @@ -1,22 +1,10 @@ -/* - * Copyright 2000-2014 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.io; +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.util.io.keyStorage; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.util.Processor; +import com.intellij.util.io.DataOutputStream; +import com.intellij.util.io.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,22 +13,25 @@ import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; -public class AppendableStorageBackedByResizableMappedFile extends ResizeableMappedFile { +public class AppendableStorageBackedByResizableMappedFile extends ResizeableMappedFile implements AppendableObjectStorage { private final MyDataIS myReadStream; private byte[] myAppendBuffer; private volatile int myFileLength; private volatile int myBufferPosition; private static final int ourAppendBufferLength = 4096; + @NotNull + private final KeyDescriptor myDataDescriptor; public AppendableStorageBackedByResizableMappedFile(final Path file, int initialSize, @Nullable PagedFileStorage.StorageLockContext lockContext, int pageSize, - boolean valuesAreBufferAligned) { + boolean valuesAreBufferAligned, + @NotNull KeyDescriptor dataDescriptor) { super(file, initialSize, lockContext, pageSize, valuesAreBufferAligned); + myDataDescriptor = dataDescriptor; myReadStream = new MyDataIS(this); myFileLength = (int)length(); - myCompressedAppendableFile = /*CompressedAppendableFile.ENABLED &&*/ null; } private void flushKeyStoreBuffer() { @@ -54,28 +45,17 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp @Override public void force() { flushKeyStoreBuffer(); - if (myCompressedAppendableFile != null) myCompressedAppendableFile.force(); super.force(); } @Override public void close() { flushKeyStoreBuffer(); - if (myCompressedAppendableFile != null) myCompressedAppendableFile.dispose(); super.close(); } - private final CompressedAppendableFile myCompressedAppendableFile; - private static final boolean testMode = false; - - public Data read(final int addr, KeyDescriptor descriptor) throws IOException { - Data tempData = null; - - if (myCompressedAppendableFile != null) { - tempData = myCompressedAppendableFile.read(addr, descriptor); - if (!testMode) return tempData; - } - + @Override + public Data read(final int addr) throws IOException { if (myFileLength <= addr) { // addr points to un-existed data if (myAppendBuffer == null) { @@ -88,40 +68,16 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp throw new NoDataException("requested address points to un-existed data"); } - Data data = - descriptor.read(new DataInputStream(new UnsyncByteArrayInputStream(myAppendBuffer, bufferOffset, myBufferPosition))); - assert tempData == null || descriptor.isEqual(data, tempData); - return data; + return myDataDescriptor.read(new DataInputStream(new UnsyncByteArrayInputStream(myAppendBuffer, bufferOffset, myBufferPosition))); } // we do not need to flushKeyBuffer since we store complete records myReadStream.setup(addr, myFileLength); - Data data = descriptor.read(myReadStream); - assert tempData == null || descriptor.isEqual(data, tempData); - return data; + return myDataDescriptor.read(myReadStream); } - public boolean processAll(@NotNull Processor processor, @NotNull KeyDescriptor descriptor) throws IOException { + @Override + public boolean processAll(@NotNull Processor processor) throws IOException { assert !isDirty(); - DataInputStream keysStream2 = myCompressedAppendableFile != null ?myCompressedAppendableFile.getStream(0) : null; - if (!testMode && keysStream2 != null) { - getPagedFileStorage().lock(); // todo support it inside myCompressedAppendableFile to avoid filling the cache - try { - try { - while (true) { - Data key = descriptor.read(keysStream2); - if (!processor.process(key)) return false; - } - } - catch (EOFException e) { - // Done - } - return true; - } - finally { - getPagedFileStorage().unlock(); - keysStream2.close(); - } - } if (myFileLength == 0) return true; @@ -135,11 +91,7 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp }, 32768))) { try { while (true) { - Data key = descriptor.read(keysStream); - if (keysStream2 != null) { - Data tempKey = descriptor.read(keysStream2); - assert descriptor.isEqual(key, tempKey); - } + Data key = myDataDescriptor.read(keysStream); if (!processor.process(key)) return false; } } @@ -150,36 +102,21 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp } } + @Override public int getCurrentLength() { - int currentLength; - if (myCompressedAppendableFile != null) { - currentLength = (int)myCompressedAppendableFile.length(); - if (testMode) { - assert currentLength == myBufferPosition + myFileLength; - } - } - else { - currentLength = myBufferPosition + myFileLength; - } - - return currentLength; + return myBufferPosition + myFileLength; } - public int append(Data value, KeyDescriptor descriptor) throws IOException { + @Override + public int append(Data value) throws IOException { final BufferExposingByteArrayOutputStream bos = new BufferExposingByteArrayOutputStream(); - DataOutput out = new DataOutputStream(bos); - descriptor.save(out, value); + DataOutput out = new com.intellij.util.io.DataOutputStream(bos); + myDataDescriptor.save(out, value); final int size = bos.size(); final byte[] buffer = bos.getInternalBuffer(); int currentLength = getCurrentLength(); - if (myCompressedAppendableFile != null) { - //myCompressedAppendableFile.append(value, descriptor); - myCompressedAppendableFile.append(buffer, size); - if (!testMode) return currentLength; - } - if (size > ourAppendBufferLength) { flushKeyStoreBuffer(); put(currentLength, buffer, 0, size); @@ -199,47 +136,26 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp return currentLength; } - boolean checkBytesAreTheSame(final int addr, Data value, KeyDescriptor descriptor) throws IOException { + @Override + public boolean checkBytesAreTheSame(final int addr, Data value) throws IOException { final boolean[] sameValue = new boolean[1]; - OutputStream comparer; - - if (myCompressedAppendableFile != null) { - final DataInputStream compressedStream = myCompressedAppendableFile.getStream(addr); - - comparer = new OutputStream() { - boolean same = true; - - @Override - public void write(int b) throws IOException { - if (same) { - same = compressedStream.readByte() == (byte)b; - } - } - - @Override - public void close() { - sameValue[0] = same; - } - }; - } else { - comparer = buildOldComparerStream(addr, sameValue); - } - + OutputStream comparer = buildOldComparerStream(addr, sameValue); DataOutput out = new DataOutputStream(comparer); - descriptor.save(out, value); + myDataDescriptor.save(out, value); comparer.close(); - - if (testMode) { - final boolean[] sameValue2 = new boolean[1]; - OutputStream comparer2 = buildOldComparerStream(addr, sameValue2); - out = new DataOutputStream(comparer2); - descriptor.save(out, value); - comparer2.close(); - assert sameValue[0] == sameValue2[0]; - } return sameValue[0]; } + @Override + public void lock() { + getPagedFileStorage().lock(); + } + + @Override + public void unlock() { + getPagedFileStorage().unlock(); + } + @NotNull private OutputStream buildOldComparerStream(final int addr, final boolean[] sameValue) { OutputStream comparer; @@ -269,7 +185,7 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp int address = storage.getOffsetInPage(addr); boolean same = true; ByteBuffer buffer = storage.getByteBuffer(addr, false).getCachedBuffer(); - final int myPageSize = storage.myPageSize; + final int myPageSize = storage.getPageSize(); @Override public void write(int b) { @@ -298,7 +214,7 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp super(new MyBufferedIS(new MappedFileInputStream(raf, 0, 0))); } - public void setup(long pos, long limit) { + void setup(long pos, long limit) { ((MyBufferedIS)in).setup(pos, limit); } } @@ -308,9 +224,9 @@ public class AppendableStorageBackedByResizableMappedFile extends ResizeableMapp super(in, 512); } - public void setup(long pos, long limit) { + void setup(long pos, long limit) { this.pos = 0; - count = 0; + this.count = 0; ((MappedFileInputStream)in).setup(pos, limit); } } diff --git a/platform/util/src/com/intellij/util/io/keyStorage/InlinedKeyStorage.java b/platform/util/src/com/intellij/util/io/keyStorage/InlinedKeyStorage.java new file mode 100644 index 000000000000..4c8a2ff00d94 --- /dev/null +++ b/platform/util/src/com/intellij/util/io/keyStorage/InlinedKeyStorage.java @@ -0,0 +1,67 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.util.io.keyStorage; + +import com.intellij.util.Processor; +import com.intellij.util.io.InlineKeyDescriptor; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class InlinedKeyStorage implements AppendableObjectStorage { + + private final InlineKeyDescriptor myDescriptor; + + public InlinedKeyStorage(@NotNull InlineKeyDescriptor descriptor) { + myDescriptor = descriptor; + } + + @Override + public Data read(int addr) throws IOException { + return myDescriptor.fromInt(addr); + } + + @Override + public boolean processAll(@NotNull Processor processor) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public int append(Data value) throws IOException { + return myDescriptor.toInt(value); + } + + @Override + public boolean checkBytesAreTheSame(int addr, Data value) throws IOException { + return false; + } + + @Override + public void lock() { + throw new UnsupportedOperationException(); + } + + @Override + public void unlock() { + throw new UnsupportedOperationException(); + } + + @Override + public int getCurrentLength() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isDirty() { + return false; + } + + @Override + public void force() { + + } + + @Override + public void close() throws IOException { + + } +} diff --git a/platform/util/src/com/intellij/util/io/NoDataException.java b/platform/util/src/com/intellij/util/io/keyStorage/NoDataException.java similarity index 67% rename from platform/util/src/com/intellij/util/io/NoDataException.java rename to platform/util/src/com/intellij/util/io/keyStorage/NoDataException.java index 77c083a2b7b9..dd3c86e81adf 100644 --- a/platform/util/src/com/intellij/util/io/NoDataException.java +++ b/platform/util/src/com/intellij/util/io/keyStorage/NoDataException.java @@ -1,13 +1,11 @@ // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.util.io; +package com.intellij.util.io.keyStorage; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.io.IOException; -@ApiStatus.Internal -class NoDataException extends IOException { +public class NoDataException extends IOException { NoDataException(@NotNull String message) { super(message); } diff --git a/platform/util/src/com/intellij/util/io/keyStorage/package-info.java b/platform/util/src/com/intellij/util/io/keyStorage/package-info.java new file mode 100644 index 000000000000..9c0db228c8fa --- /dev/null +++ b/platform/util/src/com/intellij/util/io/keyStorage/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +@ApiStatus.Internal +package com.intellij.util.io.keyStorage; + +import org.jetbrains.annotations.ApiStatus; \ No newline at end of file