diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java index ee02365fd6e9..a564e553fa17 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2019 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.openapi.vfs.impl.jar; import com.intellij.notification.NotificationGroup; @@ -119,7 +105,7 @@ public class JarHandler extends ZipHandler { return originalFile; } - if (FSRecords.weHaveContentHashes) { + if (FSRecords.WE_HAVE_CONTENT_HASHES) { return getMirrorWithContentHash(originalFile, originalAttributes); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index f009f9835ad5..35e7ee9105d7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -44,26 +44,30 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author max */ -@SuppressWarnings("HardCodedStringLiteral") public class FSRecords { private static final Logger LOG = Logger.getInstance("#com.intellij.vfs.persistent.FSRecords"); - public static final boolean weHaveContentHashes = SystemProperties.getBooleanProperty("idea.share.contents", true); + public static final boolean WE_HAVE_CONTENT_HASHES = SystemProperties.getBooleanProperty("idea.share.contents", true); + static final String VFS_FILES_EXTENSION = System.getProperty("idea.vfs.files.extension", ".dat"); + private static final boolean lazyVfsDataCleaning = SystemProperties.getBooleanProperty("idea.lazy.vfs.data.cleaning", true); private static final boolean backgroundVfsFlush = SystemProperties.getBooleanProperty("idea.background.vfs.flush", true); private static final boolean inlineAttributes = SystemProperties.getBooleanProperty("idea.inline.vfs.attributes", true); private static final boolean bulkAttrReadSupport = SystemProperties.getBooleanProperty("idea.bulk.attr.read", false); private static final boolean useCompressionUtil = SystemProperties.getBooleanProperty("idea.use.lightweight.compression.for.vfs", false); private static final boolean useSmallAttrTable = SystemProperties.getBooleanProperty("idea.use.small.attr.table.for.vfs", true); - static final String VFS_FILES_EXTENSION = System.getProperty("idea.vfs.files.extension", ".dat"); private static final boolean ourStoreRootsSeparately = SystemProperties.getBooleanProperty("idea.store.roots.separately", false); //TODO[anyone] when bumping the version, please delete `ourSymlinkTargetAttr_old` and use it's value for `ourSymlinkTargetAttr` - private static final int VERSION = 22 + (weHaveContentHashes ? 0x10:0) + (IOUtil.ourByteBuffersUseNativeByteOrder ? 0x37:0) + - 31 + (bulkAttrReadSupport ? 0x27:0) + (inlineAttributes ? 0x31 : 0) + + private static final int VERSION = 53 + + (WE_HAVE_CONTENT_HASHES ? 0x10 : 0) + + (IOUtil.BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER ? 0x37 : 0) + + (bulkAttrReadSupport ? 0x27 : 0) + + (inlineAttributes ? 0x31 : 0) + (ourStoreRootsSeparately ? 0x63 : 0) + - (useCompressionUtil ? 0x7f : 0) + (useSmallAttrTable ? 0x31 : 0) + - (PersistentHashMapValueStorage.COMPRESSION_ENABLED ? 21:0); + (useCompressionUtil ? 0x7f : 0) + + (useSmallAttrTable ? 0x31 : 0) + + (PersistentHashMapValueStorage.COMPRESSION_ENABLED ? 0x15 : 0); private static final int PARENT_OFFSET = 0; private static final int PARENT_SIZE = 4; @@ -121,17 +125,17 @@ public class FSRecords { } static void writeAttributesToRecord(int id, int parentId, @NotNull FileAttributes attributes, @NotNull String name) { - writeAndHandleErrors(()->{ + writeAndHandleErrors(() -> { setName(id, name); setTimestamp(id, attributes.lastModified); setLength(id, attributes.isDirectory() ? -1L : attributes.length); setFlags(id, (attributes.isDirectory() ? PersistentFS.IS_DIRECTORY_FLAG : 0) | - (attributes.isWritable() ? 0 : PersistentFS.IS_READ_ONLY) | - (attributes.isSymLink() ? PersistentFS.IS_SYMLINK : 0) | - (attributes.isSpecial() ? PersistentFS.IS_SPECIAL : 0) | - (attributes.isHidden() ? PersistentFS.IS_HIDDEN : 0), true); + (attributes.isWritable() ? 0 : PersistentFS.IS_READ_ONLY) | + (attributes.isSymLink() ? PersistentFS.IS_SYMLINK : 0) | + (attributes.isSpecial() ? PersistentFS.IS_SPECIAL : 0) | + (attributes.isHidden() ? PersistentFS.IS_HIDDEN : 0), true); setParent(id, parentId); }); } @@ -166,9 +170,8 @@ public class FSRecords { private static final AttrPageAwareCapacityAllocationPolicy REASONABLY_SMALL = new AttrPageAwareCapacityAllocationPolicy(); - public static void connect() { - writeAndHandleErrors(()->{ + writeAndHandleErrors(() -> { if (!ourInitialized) { init(); setupFlushing(); @@ -190,15 +193,14 @@ public class FSRecords { } static int getFreeRecord() { - if (myFreeRecords.isEmpty()) return 0; - return myFreeRecords.remove(myFreeRecords.size() - 1); + return myFreeRecords.isEmpty() ? 0 : myFreeRecords.remove(myFreeRecords.size() - 1); } private static void createBrokenMarkerFile(@Nullable Throwable reason) { final File brokenMarker = getCorruptionMarkerFile(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - try (PrintStream stream = new PrintStream(out)) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") PrintStream stream = new PrintStream(out)) { new Exception().printStackTrace(stream); if (reason != null) { stream.print("\nReason:\n"); @@ -207,12 +209,10 @@ public class FSRecords { } LOG.info("Creating VFS corruption marker; Trace=\n" + out); - try (FileWriter writer = new FileWriter(brokenMarker)) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") FileWriter writer = new FileWriter(brokenMarker)) { writer.write("These files are corrupted and must be rebuilt from the scratch on next startup"); } - catch (IOException e) { - // No luck. - } + catch (IOException ignored) { } // No luck. } private static File getCorruptionMarkerFile() { @@ -221,7 +221,9 @@ public class FSRecords { private static void init() { final File basePath = basePath().getAbsoluteFile(); - basePath.mkdirs(); + if (!(basePath.isDirectory() || basePath.mkdirs())) { + throw new RuntimeException("Cannot create storage directory: " + basePath); + } final File namesFile = new File(basePath, "names" + VFS_FILES_EXTENSION); final File attributesFile = new File(basePath, "attrib" + VFS_FILES_EXTENSION); @@ -251,19 +253,22 @@ public class FSRecords { return inlineAttributes && useSmallAttrTable ? new CompactRecordsTable(recordsFile, pool, false) : super.createRecordsTable(pool, recordsFile); } }; - myContents = new RefCountingStorage(contentsFile.getPath(), CapacityAllocationPolicy.FIVE_PERCENT_FOR_GROWTH, - useCompressionUtil) { + + myContents = new RefCountingStorage(contentsFile.getPath(), CapacityAllocationPolicy.FIVE_PERCENT_FOR_GROWTH, useCompressionUtil) { @NotNull @Override protected ExecutorService createExecutor() { return SequentialTaskExecutor.createSequentialApplicationPoolExecutor("FSRecords Pool"); } - }; // sources usually zipped with 4x ratio - myContentHashesEnumerator = weHaveContentHashes ? new ContentHashesUtil.HashEnumerator(contentsHashesFile, storageLockContext): null; + }; + + // sources usually zipped with 4x ratio + myContentHashesEnumerator = WE_HAVE_CONTENT_HASHES ? new ContentHashesUtil.HashEnumerator(contentsHashesFile, storageLockContext) : null; + boolean aligned = PagedFileStorage.BUFFER_SIZE % RECORD_SIZE == 0; - assert aligned; // for performance + if (!aligned) LOG.error("Buffer size " + PagedFileStorage.BUFFER_SIZE + " is not aligned for record size " + RECORD_SIZE); myRecords = new ResizeableMappedFile(recordsFile, 20 * 1024, storageLockContext, - PagedFileStorage.BUFFER_SIZE, aligned, IOUtil.ourByteBuffersUseNativeByteOrder); + PagedFileStorage.BUFFER_SIZE, aligned, IOUtil.BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER); boolean initial = myRecords.length() == 0; @@ -273,8 +278,9 @@ public class FSRecords { setCurrentVersion(); } - if (getVersion() != VERSION) { - throw new IOException("FS repository version mismatch"); + int version = getVersion(); + if (version != VERSION) { + throw new IOException("FS repository version mismatch: actual=" + version + " expected=" + VERSION); } if (myRecords.getInt(HEADER_CONNECTION_STATUS_OFFSET) != SAFELY_CLOSED_MAGIC) { @@ -431,7 +437,7 @@ public class FSRecords { } static void cleanRecord(int id) { - myRecords.put(id * RECORD_SIZE, ZEROES, 0, RECORD_SIZE); + myRecords.put(((long)id) * RECORD_SIZE, ZEROES, 0, RECORD_SIZE); } private static PersistentStringEnumerator getNames() { @@ -554,7 +560,7 @@ public class FSRecords { // todo: Address / capacity store in records table, size store with payload public static int createRecord() { - return writeAndHandleErrors(()->{ + return writeAndHandleErrors(() -> { DbConnection.markDirty(); final int free = DbConnection.getFreeRecord(); @@ -578,7 +584,7 @@ public class FSRecords { return (int)getRecords().length(); } public static int getMaxId() { - return readAndHandleErrors(()->length()/RECORD_SIZE); + return readAndHandleErrors(() -> length() / RECORD_SIZE); } static void deleteRecordRecursively(int id) { @@ -629,7 +635,7 @@ public class FSRecords { private static void deleteContentAndAttributes(int id) throws IOException { int content_page = getContentRecordId(id); if (content_page != 0) { - if (weHaveContentHashes) { + if (WE_HAVE_CONTENT_HASHES) { getContentStorage().releaseRecord(content_page, false); } else { @@ -674,8 +680,8 @@ public class FSRecords { if (ourStoreRootsSeparately) { TIntArrayList result = new TIntArrayList(); - try (LineNumberReader stream = new LineNumberReader( - new BufferedReader(new InputStreamReader(new FileInputStream(DbConnection.myRootsFile))))) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") LineNumberReader stream = + new LineNumberReader(new BufferedReader(new InputStreamReader(new FileInputStream(DbConnection.myRootsFile))))) { String str; while ((str = stream.readLine()) != null) { int index = str.indexOf(' '); @@ -683,8 +689,7 @@ public class FSRecords { result.add(id); } } - catch (FileNotFoundException ignored) { - } + catch (FileNotFoundException ignored) { } return result.toNativeArray(); } @@ -728,7 +733,8 @@ public class FSRecords { static int findRootRecord(@NotNull String rootUrl) { return writeAndHandleErrors(() -> { if (ourStoreRootsSeparately) { - try (LineNumberReader stream = new LineNumberReader(new BufferedReader(new InputStreamReader(new FileInputStream(DbConnection.myRootsFile))))) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") LineNumberReader stream = + new LineNumberReader(new BufferedReader(new InputStreamReader(new FileInputStream(DbConnection.myRootsFile))))) { String str; while((str = stream.readLine()) != null) { int index = str.indexOf(' '); @@ -741,7 +747,8 @@ public class FSRecords { catch (FileNotFoundException ignored) {} DbConnection.markDirty(); - try (Writer stream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DbConnection.myRootsFile, true)))) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") Writer stream = + new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DbConnection.myRootsFile, true)))) { int id = createRecord(); stream.write(id + " " + rootUrl + "\n"); return id; @@ -796,7 +803,8 @@ public class FSRecords { DbConnection.markDirty(); if (ourStoreRootsSeparately) { List rootsThatLeft = new ArrayList<>(); - try (LineNumberReader stream = new LineNumberReader(new BufferedReader(new InputStreamReader(new FileInputStream(DbConnection.myRootsFile))))) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") LineNumberReader stream = + new LineNumberReader(new BufferedReader(new InputStreamReader(new FileInputStream(DbConnection.myRootsFile))))) { String str; while((str = stream.readLine()) != null) { int index = str.indexOf(' '); @@ -808,8 +816,9 @@ public class FSRecords { } catch (FileNotFoundException ignored) {} - try (Writer stream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DbConnection.myRootsFile)))) { - for(String line:rootsThatLeft) { + try (@SuppressWarnings("ImplicitDefaultCharsetUsage") Writer stream = + new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DbConnection.myRootsFile)))) { + for (String line:rootsThatLeft) { stream.write(line); stream.write("\n"); } @@ -874,8 +883,8 @@ public class FSRecords { } public static class NameId { - @NotNull public static final NameId[] EMPTY_ARRAY = new NameId[0]; + public final int id; public final CharSequence name; public final int nameId; @@ -894,7 +903,7 @@ public class FSRecords { @NotNull public static NameId[] listAll(int parentId) { - return readAndHandleErrors(()->{ + return readAndHandleErrors(() -> { try (final DataInputStream input = readAttribute(parentId, ourChildrenAttr)) { if (input == null) return NameId.EMPTY_ARRAY; @@ -913,7 +922,7 @@ public class FSRecords { } static boolean wereChildrenAccessed(int id) { - return readAndHandleErrors(()-> findAttributePage(id, ourChildrenAttr, false) != 0); + return readAndHandleErrors(() -> findAttributePage(id, ourChildrenAttr, false) != 0); } private static T readAndHandleErrors(@NotNull ThrowableComputable action) { @@ -1014,6 +1023,7 @@ public class FSRecords { private static void incLocalModCount() { DbConnection.markDirty(); + //noinspection NonAtomicOperationOnVolatileField ourLocalModificationCount++; } @@ -1030,7 +1040,7 @@ public class FSRecords { } public static int getParent(int id) { - return readAndHandleErrors(()->{ + return readAndHandleErrors(() -> { final int parentId = getRecordInt(id, PARENT_OFFSET); if (parentId == id) { LOG.error("Cyclic parent child relations in the database. id = " + id); @@ -1113,7 +1123,7 @@ public class FSRecords { } static int getNameId(int id) { - return readAndHandleErrors(()-> doGetNameId(id)); + return readAndHandleErrors(() -> doGetNameId(id)); } private static int doGetNameId(int id) { @@ -1121,7 +1131,7 @@ public class FSRecords { } public static int getNameId(String name) { - return readAndHandleErrors(()->getNames().enumerate(name)); + return readAndHandleErrors(() -> getNames().enumerate(name)); } public static String getName(int id) { @@ -1130,7 +1140,7 @@ public class FSRecords { @NotNull static CharSequence getNameSequence(int id) { - return readAndHandleErrors(()->doGetNameSequence(id)); + return readAndHandleErrors(() -> doGetNameSequence(id)); } @NotNull @@ -1140,7 +1150,7 @@ public class FSRecords { } public static String getNameByNameId(int nameId) { - return readAndHandleErrors(()-> doGetNameByNameId(nameId)); + return readAndHandleErrors(() -> doGetNameByNameId(nameId)); } private static String doGetNameByNameId(int nameId) throws IOException { @@ -1173,7 +1183,7 @@ public class FSRecords { } static long getLength(int id) { - return readAndHandleErrors(()->getRecords().getLong(getOffset(id, LENGTH_OFFSET))); + return readAndHandleErrors(() -> getRecords().getLong(getOffset(id, LENGTH_OFFSET))); } static void setLength(int id, long len) { @@ -1281,7 +1291,7 @@ public class FSRecords { @Nullable public static DataInputStream readAttributeWithLock(int fileId, FileAttribute att) { - return readAndHandleErrors(()->{ + return readAndHandleErrors(() -> { try (DataInputStream stream = readAttribute(fileId, att)) { if (stream != null && att.isVersioned()) { try { @@ -1427,7 +1437,6 @@ public class FSRecords { private static void checkFileIsValid(int fileId) throws IOException { assert fileId > 0 : fileId; - // TODO: This assertion is a bit timey, will remove when bug is caught. if (!lazyVfsDataCleaning) { assert !BitUtil.isSet(doGetFlags(fileId), FREE_RECORD_FLAG) : "Accessing attribute of a deleted page: " + fileId + ":" + doGetNameSequence(fileId); } @@ -1442,11 +1451,11 @@ public class FSRecords { } static void releaseContent(int contentId) { - writeAndHandleErrors(() -> getContentStorage().releaseRecord(contentId, !weHaveContentHashes)); + writeAndHandleErrors(() -> getContentStorage().releaseRecord(contentId, !WE_HAVE_CONTENT_HASHES)); } static int getContentId(int fileId) { - return readAndHandleErrors(()->getContentRecordId(fileId)); + return readAndHandleErrors(() -> getContentRecordId(fileId)); } @NotNull @@ -1464,7 +1473,7 @@ public class FSRecords { static int storeUnlinkedContent(byte[] bytes) { return writeAndHandleErrors(() -> { int recordId; - if (weHaveContentHashes) { + if (WE_HAVE_CONTENT_HASHES) { recordId = findOrCreateContentRecord(bytes, 0, bytes.length); if (recordId > 0) return recordId; recordId = -recordId; @@ -1518,7 +1527,7 @@ public class FSRecords { int page; final boolean fixedSize; - if (weHaveContentHashes) { + if (WE_HAVE_CONTENT_HASHES) { page = findOrCreateContentRecord(bytes.getBytes(), bytes.getOffset(), bytes.getLength()); if (page < 0 || getContentId(myFileId) != page) { @@ -1558,7 +1567,7 @@ public class FSRecords { } } - private static final boolean DUMP_STATISTICS = weHaveContentHashes; // TODO: remove once not needed + private static final boolean DUMP_STATISTICS = WE_HAVE_CONTENT_HASHES; // TODO: remove once not needed private static long totalContents; private static long totalReuses; private static long time; @@ -1566,7 +1575,7 @@ public class FSRecords { private static int reuses; private static int findOrCreateContentRecord(byte[] bytes, int offset, int length) throws IOException { - assert weHaveContentHashes; + assert WE_HAVE_CONTENT_HASHES; long started = DUMP_STATISTICS ? System.nanoTime():0; myDigest.reset(); @@ -1751,7 +1760,7 @@ public class FSRecords { long t = System.currentTimeMillis(); int recordCount= - readAndHandleErrors(()->{ + readAndHandleErrors(() -> { final int fileLength = length(); assert fileLength % RECORD_SIZE == 0; return fileLength / RECORD_SIZE; @@ -1763,7 +1772,7 @@ public class FSRecords { int flags = getFlags(id); LOG.assertTrue((flags & ~ALL_VALID_FLAGS) == 0, "Invalid flags: 0x" + Integer.toHexString(flags) + ", id: " + id); int currentId = id; - boolean isFreeRecord = readAndHandleErrors(()->DbConnection.myFreeRecords.contains(currentId)); + boolean isFreeRecord = readAndHandleErrors(() -> DbConnection.myFreeRecords.contains(currentId)); if (BitUtil.isSet(flags, FREE_RECORD_FLAG)) { LOG.assertTrue(isFreeRecord, "Record, marked free, not in free list: " + id); } @@ -1790,7 +1799,7 @@ public class FSRecords { CharSequence name = getNameSequence(id); LOG.assertTrue(parentId == 0 || name.length()!=0, "File with empty name found under " + getNameSequence(parentId) + ", id=" + id); - writeAndHandleErrors(()->{ + writeAndHandleErrors(() -> { checkContentsStorageSanity(id); checkAttributesStorageSanity(id, usedAttributeRecordIds, validAttributeIds); }); @@ -1821,8 +1830,7 @@ public class FSRecords { } } - private static void checkAttributesSanity(final int attributeRecordId, final IntArrayList usedAttributeRecordIds, - final IntArrayList validAttributeIds) throws IOException { + private static void checkAttributesSanity(int attributeRecordId, IntArrayList usedAttributeRecordIds, IntArrayList validAttributeIds) throws IOException { assert !usedAttributeRecordIds.contains(attributeRecordId); usedAttributeRecordIds.add(attributeRecordId); @@ -1844,7 +1852,9 @@ public class FSRecords { dataInputStream.skipBytes(attDataRecordIdOrSize); continue; } - else attDataRecordIdOrSize -= MAX_SMALL_ATTR_SIZE; + else { + attDataRecordIdOrSize -= MAX_SMALL_ATTR_SIZE; + } } assert !usedAttributeRecordIds.contains(attDataRecordIdOrSize); usedAttributeRecordIds.add(attDataRecordIdOrSize); @@ -1858,4 +1868,4 @@ public class FSRecords { public static void handleError(Throwable e) throws RuntimeException, Error { DbConnection.handleError(e); } -} +} \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java index 95cad6a2713d..82f03acfbcce 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFsTest.java @@ -194,20 +194,20 @@ public class PersistentFsTest extends PlatformTestCase { VirtualFile projectStructure = createTestProjectStructure(); String testName = getTestName(false); - // wrt persistence subDir becomes partially loaded and subsubDir becomes fully loaded + // wrt persistence subDir becomes partially loaded and subSubDir becomes fully loaded File nestedDirOutsideTheProject = new File(projectStructure.getPath() + "../../../"+testName + "/subDir", "subSubDir").getCanonicalFile(); Disposable disposable = null; try { - boolean atleastSecondRun = nestedDirOutsideTheProject.getParentFile().getParentFile().exists(); + boolean atLeastSecondRun = nestedDirOutsideTheProject.getParentFile().getParentFile().exists(); StringBuilder eventLog = new StringBuilder(); - if (atleastSecondRun) { + if (atLeastSecondRun) { disposable = Disposer.newDisposable(); getProject().getMessageBus().connect(disposable).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { @Override public void before(@NotNull List events) { - for(VFileEvent event:events) { + for (VFileEvent event : events) { if (event instanceof VFileDeleteEvent) process(((VFileDeleteEvent)event).getFile()); } } @@ -215,7 +215,7 @@ public class PersistentFsTest extends PlatformTestCase { String path = file.getPath(); eventLog.append(path.substring(path.indexOf(testName) + testName.length() + 1)).append("\n"); Iterable files = ((NewVirtualFile)file).iterInDbChildren(); - for(VirtualFile nested:files) process(nested); + for (VirtualFile nested : files) process(nested); } }); } @@ -224,17 +224,17 @@ public class PersistentFsTest extends PlatformTestCase { VirtualFile nestedDirOutsideTheProjectFile = VfsUtil.createDirectories(nestedDirOutsideTheProject.getPath()); WriteAction.run(() -> nestedDirOutsideTheProjectFile.createChildData(null, "Foo.txt")); - // subsubDir becomes fully loaded wrt persistence + // subSubDir becomes fully loaded wrt persistence nestedDirOutsideTheProjectFile.getChildren(); - if (atleastSecondRun) { + if (atLeastSecondRun) { assertEquals("subDir\n" + "subDir/subSubDir\n" + "subDir/subSubDir/Foo.txt\n", - eventLog.toString() - ); + eventLog.toString()); } - } finally { + } + finally { if (disposable != null) Disposer.dispose(disposable); // remove /subDir via java.io to have vfs events on next test launch FileUtil.delete(nestedDirOutsideTheProject.getParentFile()); @@ -342,7 +342,7 @@ public class PersistentFsTest extends PlatformTestCase { private void log(String msg, @NotNull List events) { List names = ContainerUtil.map(events, e -> e.getClass().getSimpleName() + "->" + PathUtil.getFileName(e.getPath())); - log.append(msg).append(names).append("\n"); + log.append(msg).append(names).append('\n'); } @Override @@ -396,8 +396,7 @@ public class PersistentFsTest extends PlatformTestCase { "After:[VFileDeleteEvent->test.txt]\n", new VFileContentChangeEvent(this, vFile.getParent(), 0, 0, false), - new VFileDeleteEvent(this, vFile, false) - ); + new VFileDeleteEvent(this, vFile, false)); } public void testProcessNestedDeletions() throws IOException { @@ -417,8 +416,7 @@ public class PersistentFsTest extends PlatformTestCase { new VFileDeleteEvent(this, testTxt, false), new VFileDeleteEvent(this, testTxt.getParent(), false), - new VFileDeleteEvent(this, test2Txt, false) - ); + new VFileDeleteEvent(this, test2Txt, false)); } public void testProcessCompositeMoveEvents() throws IOException { @@ -438,8 +436,7 @@ public class PersistentFsTest extends PlatformTestCase { "After:[VFileDeleteEvent->d]\n", new VFileMoveEvent(this, testTxt, newParent), - new VFileDeleteEvent(this, newParent, false) - ); + new VFileDeleteEvent(this, newParent, false)); } public void testProcessCompositeCopyEvents() throws IOException { @@ -459,8 +456,7 @@ public class PersistentFsTest extends PlatformTestCase { "After:[VFileDeleteEvent->test.txt]\n", new VFileCopyEvent(this, testTxt, newParent,"new.txt"), - new VFileDeleteEvent(this, testTxt, false) - ); + new VFileDeleteEvent(this, testTxt, false)); } public void testProcessCompositeRenameEvents() throws IOException { @@ -480,8 +476,6 @@ public class PersistentFsTest extends PlatformTestCase { "After:[VFilePropertyChangeEvent->test2.txt]\n", new VFileDeleteEvent(this, test2Txt, false), - new VFilePropertyChangeEvent(this, testTxt, VirtualFile.PROP_NAME, file.getName(), file2.getName(), false) - ); + new VFilePropertyChangeEvent(this, testTxt, VirtualFile.PROP_NAME, file.getName(), file2.getName(), false)); } - -} +} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/io/IOUtil.java b/platform/util/src/com/intellij/util/io/IOUtil.java index 65a9b73a7f11..c2c2d29e5a21 100644 --- a/platform/util/src/com/intellij/util/io/IOUtil.java +++ b/platform/util/src/com/intellij/util/io/IOUtil.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2015 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. - */ +// Copyright 2000-2019 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; import com.intellij.openapi.util.ThreadLocalCachedValue; @@ -20,23 +6,22 @@ import com.intellij.openapi.util.ThrowableComputable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.SystemProperties; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; import java.lang.reflect.Field; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class IOUtil { - public static final boolean ourByteBuffersUseNativeByteOrder = SystemProperties.getBooleanProperty("idea.bytebuffers.use.native.byte.order", true); + @SuppressWarnings("SpellCheckingInspection") public static final boolean BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER = + SystemProperties.getBooleanProperty("idea.bytebuffers.use.native.byte.order", true); + private static final int STRING_HEADER_SIZE = 1; private static final int STRING_LENGTH_THRESHOLD = 255; - - @NonNls private static final String LONGER_THAN_64K_MARKER = "LONGER_THAN_64K"; + private static final String LONGER_THAN_64K_MARKER = "LONGER_THAN_64K"; private IOUtil() {} @@ -45,9 +30,9 @@ public class IOUtil { if (length == -1) return null; if (length == 0) return ""; - byte[] bytes = new byte[length*2]; + byte[] bytes = new byte[length * 2]; stream.readFully(bytes); - return new String(bytes, 0, length*2, CharsetToolkit.UTF_16BE_CHARSET); + return new String(bytes, 0, length * 2, CharsetToolkit.UTF_16BE_CHARSET); } public static void writeString(@Nullable String s, @NotNull DataOutput stream) throws IOException { @@ -55,6 +40,7 @@ public class IOUtil { stream.writeInt(-1); return; } + stream.writeInt(s.length()); if (s.isEmpty()) { return; @@ -91,7 +77,7 @@ public class IOUtil { } }; - public static void writeUTF(@NotNull DataOutput storage, @NotNull final String value) throws IOException { + public static void writeUTF(@NotNull DataOutput storage, @NotNull String value) throws IOException { writeUTFFast(ourReadWriteBuffersCache.getValue(), storage, value); } @@ -104,7 +90,7 @@ public class IOUtil { return new byte[STRING_LENGTH_THRESHOLD + STRING_HEADER_SIZE]; } - public static void writeUTFFast(@NotNull byte[] buffer, @NotNull DataOutput storage, @NotNull final String value) throws IOException { + public static void writeUTFFast(@NotNull byte[] buffer, @NotNull DataOutput storage, @NotNull String value) throws IOException { int len = value.length(); if (len < STRING_LENGTH_THRESHOLD) { buffer[0] = (byte)len; @@ -133,7 +119,6 @@ public class IOUtil { } } - public static final Charset US_ASCII = Charset.forName("US-ASCII"); private static final ThreadLocalCachedValue spareBufferLocal = new ThreadLocalCachedValue() { @NotNull @Override @@ -157,15 +142,16 @@ public class IOUtil { storage.readFully(buffer, 0, len); char[] chars = spareBufferLocal.getValue(); - for(int i = 0; i < len; ++i) chars[i] = (char)(buffer[i] &0xFF); + for (int i = 0; i < len; ++i) chars[i] = (char)(buffer[i] & 0xFF); return new String(chars, 0, len); } public static boolean isAscii(@NotNull String str) { return isAscii((CharSequence)str); } + public static boolean isAscii(@NotNull CharSequence str) { - for (int i = 0, length = str.length(); i < length; ++ i) { + for (int i = 0, length = str.length(); i < length; ++i) { if (str.charAt(i) >= 128) return false; } return true; @@ -183,7 +169,7 @@ public class IOUtil { public boolean accept(final File pathname) { return pathname.getName().startsWith(baseName); } - }): null; + }) : null; boolean ok = true; if (files != null) { @@ -205,7 +191,8 @@ public class IOUtil { Object o = outField.get(stream); if (o instanceof OutputStream) { stream = (OutputStream)o; - } else { + } + else { break; } } @@ -221,7 +208,8 @@ public class IOUtil { } } - public static T openCleanOrResetBroken(@NotNull ThrowableComputable factoryComputable, @NotNull final File file) throws IOException { + public static T openCleanOrResetBroken(@NotNull ThrowableComputable factoryComputable, + @NotNull final File file) throws IOException { return openCleanOrResetBroken(factoryComputable, new Runnable() { @Override public void run() { @@ -230,33 +218,32 @@ public class IOUtil { }); } - public static T openCleanOrResetBroken(@NotNull ThrowableComputable factoryComputable, @NotNull Runnable cleanupCallback) throws IOException { - for(int i = 0; i < 2; ++i) { - try { - return factoryComputable.compute(); - } catch (IOException ex) { - if (i == 1) throw ex; - cleanupCallback.run(); - } + public static T openCleanOrResetBroken(@NotNull ThrowableComputable factoryComputable, + @NotNull Runnable cleanupCallback) throws IOException { + try { + return factoryComputable.compute(); + } + catch (IOException ex) { + cleanupCallback.run(); } - return null; + return factoryComputable.compute(); } public static void writeStringList(@NotNull DataOutput out, @NotNull Collection list) throws IOException { DataInputOutputUtil.writeINT(out, list.size()); - for (final String s : list) { + for (String s : list) { writeUTF(out, s); } } @NotNull public static List readStringList(@NotNull DataInput in) throws IOException { - final int size = DataInputOutputUtil.readINT(in); - final ArrayList strings = new ArrayList(size); + int size = DataInputOutputUtil.readINT(in); + List strings = new ArrayList(size); for (int i = 0; i < size; i++) { strings.add(readUTF(in)); } return strings; } -} +} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/io/IntToIntBtree.java b/platform/util/src/com/intellij/util/io/IntToIntBtree.java index d423189a4937..3761939f400f 100644 --- a/platform/util/src/com/intellij/util/io/IntToIntBtree.java +++ b/platform/util/src/com/intellij/util/io/IntToIntBtree.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2015 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. - */ +// Copyright 2000-2019 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; import com.intellij.openapi.util.io.FileUtil; @@ -29,7 +15,7 @@ import java.util.Arrays; public class IntToIntBtree { public static int version() { - return 4 + (IOUtil.ourByteBuffersUseNativeByteOrder ? 0xFF : 0); + return 4 + (IOUtil.BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER ? 0xFF : 0); } private static final int HAS_ZERO_KEY_MASK = 0xFF000000; @@ -71,7 +57,7 @@ public class IntToIntBtree { FileUtil.delete(file); } - storage = new ResizeableMappedFile(file, pageSize, storageLockContext, 1024 * 1024, true, IOUtil.ourByteBuffersUseNativeByteOrder); + storage = new ResizeableMappedFile(file, pageSize, storageLockContext, 1024 * 1024, true, IOUtil.BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER); storage.setRoundFactor(pageSize); root = new BtreeRootNode(this); @@ -1150,14 +1136,14 @@ public class IntToIntBtree { public boolean processMappings(@NotNull KeyValueProcessor processor) throws IOException { doFlush(); - + if (hasZeroKey) { if (!processor.process(0, zeroKeyValue)) return false; } if(root.address == UNDEFINED_ADDRESS) return true; root.syncWithStore(); - + return processLeafPages(root.getNodeView(), processor); } diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java index 75926cd7e3d2..c218a5d91d52 100644 --- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java +++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2016 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. - */ +// Copyright 2000-2019 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; import com.intellij.util.ArrayUtil; @@ -91,7 +77,7 @@ public class PersistentBTreeEnumerator extends PersistentEnumeratorBase