From 2fdb536ee9468d7341f3ee294f5af9fb6f80a7da Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 3 May 2012 16:09:05 +0400 Subject: [PATCH] avoid using NanoXml with InputStream to reduce unneeded garbage --- .../detection/FileContentPattern.java | 4 +- .../com/intellij/util/xml/NanoXmlUtil.java | 6 ++ .../xml/index/XsdNamespaceBuilder.java | 25 ++++----- .../com/intellij/util/text/CharArrayUtil.java | 4 +- .../util/text/UnsyncCharArrayReader.java | 56 +++++++++++++++++++ .../org/jetbrains/android/AndroidIdIndex.java | 3 +- .../android/AndroidValueResourcesIndex.java | 3 +- .../xpath/xslt/impl/XsltIncludeProvider.java | 3 +- .../lang/xpath/xslt/impl/XsltSymbolIndex.java | 2 +- .../com/intellij/util/xml/DomFileIndex.java | 4 +- .../intellij/xml/index/XmlNamespaceIndex.java | 4 +- .../intellij/xml/index/XmlTagNamesIndex.java | 4 +- .../intellij/xml/index/XsdTagNameBuilder.java | 25 ++++----- .../intellij/xml/util/XIncludeProvider.java | 3 +- .../model/resolve/RelaxIncludeProvider.java | 3 +- .../model/resolve/RelaxSymbolIndex.java | 3 +- 16 files changed, 99 insertions(+), 53 deletions(-) create mode 100644 platform/util/src/com/intellij/util/text/UnsyncCharArrayReader.java diff --git a/platform/lang-api/src/com/intellij/framework/detection/FileContentPattern.java b/platform/lang-api/src/com/intellij/framework/detection/FileContentPattern.java index 481f3ddeb7f7..423160a5dfad 100644 --- a/platform/lang-api/src/com/intellij/framework/detection/FileContentPattern.java +++ b/platform/lang-api/src/com/intellij/framework/detection/FileContentPattern.java @@ -18,7 +18,7 @@ package com.intellij.framework.detection; import com.intellij.patterns.*; import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileContent; -import com.intellij.util.text.CharSequenceReader; +import com.intellij.util.text.CharArrayUtil; import com.intellij.util.xml.NanoXmlUtil; import com.intellij.util.xml.XmlFileHeader; import org.jetbrains.annotations.NotNull; @@ -101,7 +101,7 @@ public class FileContentPattern extends ObjectPattern() { - public String fun(final InputStream inputStream) { - return computeNamespace(inputStream); - } - }); - } private String myNamespace; diff --git a/platform/util/src/com/intellij/util/text/CharArrayUtil.java b/platform/util/src/com/intellij/util/text/CharArrayUtil.java index 164b1ad9eb9d..c5244ba4ca7b 100644 --- a/platform/util/src/com/intellij/util/text/CharArrayUtil.java +++ b/platform/util/src/com/intellij/util/text/CharArrayUtil.java @@ -549,8 +549,8 @@ public class CharArrayUtil { public static Reader readerFromCharSequence(CharSequence text) { Reader reader; char[] chars = fromSequenceWithoutCopying(text); - if (chars != null) reader = new CharArrayReader(chars, 0, text.length()); - else reader = new StringReader(text.toString()); + if (chars != null) reader = new UnsyncCharArrayReader(chars, 0, text.length()); + else reader = new CharSequenceReader(text.toString()); return reader; } } diff --git a/platform/util/src/com/intellij/util/text/UnsyncCharArrayReader.java b/platform/util/src/com/intellij/util/text/UnsyncCharArrayReader.java new file mode 100644 index 000000000000..d8e942462fb3 --- /dev/null +++ b/platform/util/src/com/intellij/util/text/UnsyncCharArrayReader.java @@ -0,0 +1,56 @@ +/* + * 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.text; + +import java.io.Reader; + +/** + * @author max + */ +public class UnsyncCharArrayReader extends Reader { + private final char[] myText; + private final int myLength; + private int myCurPos; + + public UnsyncCharArrayReader(final char[] text, int offset, int length) { + myText = text; + myLength = length; + myCurPos = offset; + } + + public void close() {} + + public int read(char[] cbuf, int off, int len) { + if (off < 0 || off > cbuf.length || len < 0 || off + len > cbuf.length || off + len < 0) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + int charsToCopy = Math.min(len, myLength - myCurPos); + if (charsToCopy <= 0) return -1; + + System.arraycopy(myText, myCurPos, cbuf, off, charsToCopy); + + myCurPos += charsToCopy; + return charsToCopy; + } + + public int read() { + if (myCurPos >= myLength) return -1; + return myText[myCurPos++]; + } +} diff --git a/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java b/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java index 5c1e51662892..e68a3ec9ea4b 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java +++ b/plugins/android/src/org/jetbrains/android/AndroidIdIndex.java @@ -30,7 +30,6 @@ import com.intellij.util.xml.NanoXmlUtil; import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; -import java.io.ByteArrayInputStream; import java.util.Collections; import java.util.Map; @@ -61,7 +60,7 @@ public class AndroidIdIndex extends ScalarIndexExtension { } final HashMap ids = new HashMap(); - NanoXmlUtil.parse(new ByteArrayInputStream(inputData.getContent()), new NanoXmlUtil.IXMLBuilderAdapter() { + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() { @Override public void addAttribute(String key, String nsPrefix, String nsURI, String value, String type) throws Exception { super.addAttribute(key, nsPrefix, nsURI, value, type); diff --git a/plugins/android/src/org/jetbrains/android/AndroidValueResourcesIndex.java b/plugins/android/src/org/jetbrains/android/AndroidValueResourcesIndex.java index 729abf003566..f40f1a0d024e 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidValueResourcesIndex.java +++ b/plugins/android/src/org/jetbrains/android/AndroidValueResourcesIndex.java @@ -16,7 +16,6 @@ import org.jetbrains.android.util.ValueResourcesFileParser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.ByteArrayInputStream; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; @@ -49,7 +48,7 @@ public class AndroidValueResourcesIndex extends FileBasedIndexExtension> result = new HashMap>(); - NanoXmlUtil.parse(new ByteArrayInputStream(inputData.getContent()), new ValueResourcesFileParser() { + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new ValueResourcesFileParser() { @Override protected void stop() { throw new NanoXmlUtil.ParserStoppedException(); diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeProvider.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeProvider.java index f16f64ae18c7..c2195487b78b 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeProvider.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltIncludeProvider.java @@ -22,7 +22,6 @@ import com.intellij.psi.impl.include.FileIncludeInfo; import com.intellij.psi.impl.include.FileIncludeProvider; import com.intellij.util.indexing.FileContent; import com.intellij.util.text.CharArrayUtil; -import com.intellij.util.text.CharSequenceReader; import com.intellij.util.xml.NanoXmlUtil; import org.intellij.lang.xpath.xslt.XsltSupport; import org.jetbrains.annotations.NotNull; @@ -77,7 +76,7 @@ public class XsltIncludeProvider extends FileIncludeProvider { } }; - NanoXmlUtil.parse(new CharSequenceReader(contentAsText), builder); + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(contentAsText), builder); return infos.toArray(new FileIncludeInfo[infos.size()]); } } diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java index c9c78c410fee..fb62ec3f0fcb 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/impl/XsltSymbolIndex.java @@ -95,7 +95,7 @@ public class XsltSymbolIndex extends FileBasedIndexExtension map = new HashMap(); - NanoXmlUtil.parse(new UnsyncByteArrayInputStream(inputData.getContent()), new NanoXmlUtil.IXMLBuilderAdapter() { + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() { NanoXmlUtil.IXMLBuilderAdapter attributeHandler; int depth; diff --git a/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java b/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java index 84400c4f1fbb..5e025a85be68 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java +++ b/xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java @@ -22,7 +22,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.*; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; -import com.intellij.util.io.UnsyncByteArrayInputStream; +import com.intellij.util.text.CharArrayUtil; import com.intellij.util.xml.impl.DomApplicationComponent; import gnu.trove.THashMap; import gnu.trove.THashSet; @@ -52,7 +52,7 @@ public class DomFileIndex extends ScalarIndexExtension{ @NotNull public Map map(final FileContent inputData) { final Set namespaces = new THashSet(); - final XmlFileHeader header = NanoXmlUtil.parseHeader(new UnsyncByteArrayInputStream(inputData.getContent())); + final XmlFileHeader header = NanoXmlUtil.parseHeader(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText())); ContainerUtil.addIfNotNull(header.getPublicId(), namespaces); ContainerUtil.addIfNotNull(header.getSystemId(), namespaces); ContainerUtil.addIfNotNull(header.getRootTagNamespace(), namespaces); diff --git a/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java b/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java index 51f584c0ead8..77400f1557c9 100644 --- a/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java +++ b/xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java @@ -24,7 +24,7 @@ import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.FileContent; import com.intellij.util.indexing.ID; import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.UnsyncByteArrayInputStream; +import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -73,7 +73,7 @@ public class XmlNamespaceIndex extends XmlIndex { @Override @NotNull public Map map(final FileContent inputData) { - final String ns = XsdNamespaceBuilder.computeNamespace(new UnsyncByteArrayInputStream(inputData.getContent())); + final String ns = XsdNamespaceBuilder.computeNamespace(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText())); final HashMap map = new HashMap(2); if (ns != null) { map.put(ns, ""); diff --git a/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java b/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java index 432a5656604c..a0c3b7aa1ad9 100644 --- a/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java +++ b/xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java @@ -20,7 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.HashMap; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.UnsyncByteArrayInputStream; +import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -55,7 +55,7 @@ public class XmlTagNamesIndex extends XmlIndex { @Override @NotNull public Map map(final FileContent inputData) { - final Collection tags = XsdTagNameBuilder.computeTagNames(new UnsyncByteArrayInputStream(inputData.getContent())); + final Collection tags = XsdTagNameBuilder.computeTagNames(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText())); if (tags != null && !tags.isEmpty()) { final HashMap map = new HashMap(tags.size()); for (String tag : tags) { diff --git a/xml/impl/src/com/intellij/xml/index/XsdTagNameBuilder.java b/xml/impl/src/com/intellij/xml/index/XsdTagNameBuilder.java index 7295dbd7c396..1754fbdffbd1 100644 --- a/xml/impl/src/com/intellij/xml/index/XsdTagNameBuilder.java +++ b/xml/impl/src/com/intellij/xml/index/XsdTagNameBuilder.java @@ -16,14 +16,13 @@ package com.intellij.xml.index; import com.intellij.util.xml.NanoXmlUtil; -import com.intellij.util.NullableFunction; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VfsUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.util.ArrayList; import java.util.Collection; @@ -34,15 +33,20 @@ public class XsdTagNameBuilder extends NanoXmlUtil.IXMLBuilderAdapter { @Nullable public static Collection computeTagNames(final InputStream is) { + return computeTagNames(new InputStreamReader(is)); + } + + @Nullable + public static Collection computeTagNames(final Reader reader) { try { final XsdTagNameBuilder builder = new XsdTagNameBuilder(); - NanoXmlUtil.parse(is, builder); + NanoXmlUtil.parse(reader, builder); return builder.myTagNames; } finally { try { - if (is != null) { - is.close(); + if (reader != null) { + reader.close(); } } catch (IOException e) { @@ -51,15 +55,6 @@ public class XsdTagNameBuilder extends NanoXmlUtil.IXMLBuilderAdapter { } } - @Nullable - public static Collection computeTagNames(final VirtualFile file) { - return VfsUtil.processInputStream(file, new NullableFunction>() { - public Collection fun(final InputStream inputStream) { - return computeTagNames(inputStream); - } - }); - } - private final Collection myTagNames = new ArrayList(); private boolean myElementStarted; diff --git a/xml/impl/src/com/intellij/xml/util/XIncludeProvider.java b/xml/impl/src/com/intellij/xml/util/XIncludeProvider.java index b20fe9c1571f..a0708fbd4c6f 100644 --- a/xml/impl/src/com/intellij/xml/util/XIncludeProvider.java +++ b/xml/impl/src/com/intellij/xml/util/XIncludeProvider.java @@ -23,7 +23,6 @@ import com.intellij.psi.impl.include.FileIncludeInfo; import com.intellij.psi.impl.include.FileIncludeProvider; import com.intellij.util.indexing.FileContent; import com.intellij.util.text.CharArrayUtil; -import com.intellij.util.text.CharSequenceReader; import com.intellij.util.xml.NanoXmlUtil; import org.jetbrains.annotations.NotNull; @@ -51,7 +50,7 @@ public class XIncludeProvider extends FileIncludeProvider { CharSequence contentAsText = content.getContentAsText(); if (CharArrayUtil.indexOf(contentAsText, XmlUtil.XINCLUDE_URI, 0) == -1) return FileIncludeInfo.EMPTY; final ArrayList infos = new ArrayList(); - NanoXmlUtil.parse(new CharSequenceReader(contentAsText), new NanoXmlUtil.IXMLBuilderAdapter() { + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(contentAsText), new NanoXmlUtil.IXMLBuilderAdapter() { boolean isXInclude; @Override diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxIncludeProvider.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxIncludeProvider.java index 60e0cf6949c4..657cb60e137a 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxIncludeProvider.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxIncludeProvider.java @@ -7,7 +7,6 @@ import com.intellij.psi.impl.include.FileIncludeInfo; import com.intellij.psi.impl.include.FileIncludeProvider; import com.intellij.util.indexing.FileContent; import com.intellij.util.text.CharArrayUtil; -import com.intellij.util.text.CharSequenceReader; import com.intellij.util.xml.NanoXmlUtil; import org.intellij.plugins.relaxNG.ApplicationLoader; import org.intellij.plugins.relaxNG.compact.RncFileType; @@ -45,7 +44,7 @@ public class RelaxIncludeProvider extends FileIncludeProvider { CharSequence inputDataContentAsText = content.getContentAsText(); if (CharArrayUtil.indexOf(inputDataContentAsText, ApplicationLoader.RNG_NAMESPACE, 0) == -1) return FileIncludeInfo.EMPTY; infos = new ArrayList(); - NanoXmlUtil.parse(new CharSequenceReader(inputDataContentAsText), new RngBuilderAdapter(infos)); + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(content.getContentAsText()), new RngBuilderAdapter(infos)); } else if (content.getFileType() == RncFileType.getInstance()) { infos = new ArrayList(); content.getPsiFile().acceptChildren(new RncElementVisitor() { diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java index c52531b9f647..e92869d41b9a 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/model/resolve/RelaxSymbolIndex.java @@ -22,7 +22,6 @@ import com.intellij.util.indexing.*; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.intellij.util.text.CharArrayUtil; -import com.intellij.util.text.CharSequenceReader; import com.intellij.util.xml.NanoXmlUtil; import org.intellij.plugins.relaxNG.ApplicationLoader; import org.intellij.plugins.relaxNG.compact.RncFileType; @@ -73,7 +72,7 @@ public class RelaxSymbolIndex extends ScalarIndexExtension { if (inputData.getFileType() == XmlFileType.INSTANCE) { CharSequence inputDataContentAsText = inputData.getContentAsText(); if (CharArrayUtil.indexOf(inputDataContentAsText, ApplicationLoader.RNG_NAMESPACE, 0) == -1) return Collections.EMPTY_MAP; - NanoXmlUtil.parse(new CharSequenceReader(inputDataContentAsText), new NanoXmlUtil.IXMLBuilderAdapter() { + NanoXmlUtil.parse(CharArrayUtil.readerFromCharSequence(inputData.getContentAsText()), new NanoXmlUtil.IXMLBuilderAdapter() { NanoXmlUtil.IXMLBuilderAdapter attributeHandler; int depth;