Skip to content

Commit

Permalink
Merge pull request #392 from angelozerr/memory-improvement
Browse files Browse the repository at this point in the history
Improve memory with Integer (see #389)
  • Loading branch information
angelozerr authored May 27, 2019
2 parents f549ca7 + 7c14064 commit b69c38e
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ public class DOMElement extends DOMNode implements org.w3c.dom.Element {
boolean selfClosed;

//DomElement.start == startTagOpenOffset
Integer startTagOpenOffset; // |<root>
Integer startTagCloseOffset; // <root |>
int startTagOpenOffset = NULL_VALUE; // |<root>
int startTagCloseOffset = NULL_VALUE; // <root |>

Integer endTagOpenOffset; // <root> |</root >
Integer endTagCloseOffset;// <root> </root |>
int endTagOpenOffset = NULL_VALUE; // <root> |</root >
int endTagCloseOffset = NULL_VALUE;// <root> </root |>
//DomElement.end = <root> </root>| , is always scanner.getTokenEnd()

public DOMElement(int start, int end, DOMDocument ownerDocument) {
Expand Down Expand Up @@ -312,7 +312,7 @@ public boolean isSameTag(String tagInLowerCase) {
}

public boolean isInStartTag(int offset) {
if (startTagOpenOffset == null || startTagCloseOffset == null) {
if (startTagOpenOffset == NULL_VALUE || startTagCloseOffset == NULL_VALUE) {
// case <|
return true;
}
Expand All @@ -324,7 +324,7 @@ public boolean isInStartTag(int offset) {
}

public boolean isInEndTag(int offset) {
if (endTagOpenOffset == null) {
if (endTagOpenOffset == NULL_VALUE) {
// case >|
return false;
}
Expand All @@ -335,23 +335,48 @@ public boolean isInEndTag(int offset) {
return false;
}

public boolean hasStartTagClose() {
return startTagCloseOffset != null;
}

public Integer getStartTagOpenOffset() {
/**
* Returns the start tag open offset and {@link DOMNode#NULL_VALUE} if it
* doesn't exist.
*
* @return the start tag open offset and {@link DOMNode#NULL_VALUE} if it
* doesn't exist.
*/
public int getStartTagOpenOffset() {
return startTagOpenOffset;
}

public Integer getStartTagCloseOffset() {
/**
* Returns the start tag close offset and {@link DOMNode#NULL_VALUE} if it
* doesn't exist.
*
* @return the start tag close offset and {@link DOMNode#NULL_VALUE} if it
* doesn't exist.
*/
public int getStartTagCloseOffset() {
return startTagCloseOffset;
}

public Integer getEndTagOpenOffset() {
/**
* Returns the end tag open offset and {@link DOMNode#NULL_VALUE} if it doesn't
* exist.
*
* @return the end tag open offset and {@link DOMNode#NULL_VALUE} if it doesn't
* exist.
*/
public int getEndTagOpenOffset() {
return endTagOpenOffset;
}

public Integer getEndTagCloseOffset() {

/**
* Returns the end tag close offset and {@link DOMNode#NULL_VALUE} if it doesn't
* exist.
*
* @return the end tag close offset and {@link DOMNode#NULL_VALUE} if it doesn't
* exist.
*/
public int getEndTagCloseOffset() {
return endTagCloseOffset;
}

Expand All @@ -364,7 +389,7 @@ public Integer getEndTagCloseOffset() {
* @return true if has a start tag.
*/
public boolean hasStartTag() {
return startTagOpenOffset != null;
return getStartTagOpenOffset() != NULL_VALUE;
}

/**
Expand All @@ -376,27 +401,27 @@ public boolean hasStartTag() {
* @return true if has an end tag.
*/
public boolean hasEndTag() {
return endTagOpenOffset != null;
return getEndTagOpenOffset() != NULL_VALUE;
}

/**
* If '>' exists in <root>
*/
public boolean isStartTagClosed() {
return startTagCloseOffset != null;
return getStartTagCloseOffset() != NULL_VALUE;
}

/**
* If '>' exists in </root>
*/
public boolean isEndTagClosed() {
return endTagCloseOffset != null;
return getEndTagCloseOffset() != NULL_VALUE;
}

@Override

/**
* If Element has a closing end tag eg: <a> </a> -> true , <a> </b> -> false
*/
@Override
public boolean isClosed() {
return super.isClosed();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
*/
public abstract class DOMNode implements Node {

/**
* Null value used for offset.
*/
public static final int NULL_VALUE = -1;

/**
* The node is a <code>DTD Element Declaration</code>.
*/
Expand Down Expand Up @@ -190,7 +195,7 @@ private String toString(int indent) {
}

/**
* Returns the node before
* Returns the node before
*/
public DOMNode findNodeBefore(int offset) {
List<DOMNode> children = getChildren();
Expand Down Expand Up @@ -292,7 +297,7 @@ public DOMAttr getAttributeNode(String name) {
*/
public DOMAttr getAttributeNode(String prefix, String suffix) {
StringBuilder sb = new StringBuilder();
if(prefix != null) {
if (prefix != null) {
sb.append(prefix);
sb.append(":");
}
Expand Down Expand Up @@ -441,7 +446,6 @@ public boolean isDoctype() {
public boolean isGenericDTDDecl() {
return getNodeType() == DOMNode.DTD_DECL_NODE;
}


public boolean isElement() {
return getNodeType() == DOMNode.ELEMENT_NODE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class DOMProcessingInstruction extends DOMCharacterData implements org.w3
boolean processingInstruction = false;
int startContent;
int endContent;
Integer endTagOpenOffset;
int endTagOpenOffset = NULL_VALUE;

public DOMProcessingInstruction(int start, int end, DOMDocument ownerDocument) {
super(start, end, ownerDocument);
Expand All @@ -46,7 +46,14 @@ public int getEndContent() {
return endContent;
}

public Integer getEndTagStart() {
/**
* Returns the end tag start offset and {@link DOMNode#NULL_VALUE} if it doesn't
* exist.
*
* @return the end tag start offset and {@link DOMNode#NULL_VALUE} if it doesn't
* exist.
*/
public int getEndTagStart() {
return endTagOpenOffset;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,6 @@ public String getUnrecognized() {

public void setUnrecognized(int start, int end) {
unrecognized = addNewParameter(start, end);
}

public static String getValueFromOffsets(DOMDocumentType document, String value, Integer start, Integer end) {
if(value == null && start != null && end != null) {
return document.getSubstring(start, end);
}
return value;
}

public DTDDeclParameter addNewParameter(int start, int end) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public AutoCloseTagResponse doTagComplete(DOMDocument xmlDocument, Position posi

// Case: <a/| ...
if(closeBracketAfterSlash == false) { // no '>' after slash
if(element1.getStartTagCloseOffset() != null) { // tag has closing '>', but slash is in incorrect area (not directly before the '>')
if(element1.isStartTagClosed()) { // tag has closing '>', but slash is in incorrect area (not directly before the '>')
return null;
}
snippet = ">$0";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ public static Range selectPreviousNodesEndTag(int offset, DOMDocument document)
}
if(node != null) {
DOMElement element = (DOMElement) node;
if(element.isClosed() && element.getEndTagCloseOffset() == null) {
if(element.isClosed() && !element.isEndTagClosed()) {
return selectEndTag(element.getEnd(), document);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.eclipse.lsp4xml.dom;

import static org.eclipse.lsp4xml.utils.IOUtils.convertStreamToString;

import java.io.InputStream;

import javax.xml.xpath.XPath;
Expand Down Expand Up @@ -151,11 +153,6 @@ public void findElementListWithXPath() throws XPathExpressionException {

}

static String convertStreamToString(InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}

@Test
public void testUsesSchemaTrue1WithNamespace() {
String text =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import java.util.ArrayList;

import org.eclipse.lsp4j.FormattingOptions;
import org.eclipse.lsp4xml.dom.DOMDocumentType.DocumentTypeKind;
import org.junit.Assert;
import org.junit.Ignore;
Expand Down Expand Up @@ -96,8 +95,7 @@ public void singleEndTag() {
assertDocument("</meta>", meta);
Assert.assertFalse(meta.hasStartTag());
Assert.assertTrue(meta.hasEndTag());
Assert.assertNotNull(meta.getEndTagOpenOffset());
Assert.assertEquals(meta.getEndTagOpenOffset().intValue(), 0); // |</meta>
Assert.assertEquals(meta.getEndTagOpenOffset(), 0); // |</meta>
}

@Test
Expand All @@ -109,8 +107,7 @@ public void insideEndTag() {
assertDocument("<html></meta></html>", html);
Assert.assertFalse(meta.hasStartTag());
Assert.assertTrue(meta.hasEndTag());
Assert.assertNotNull(meta.getEndTagOpenOffset());
Assert.assertEquals(meta.getEndTagOpenOffset().intValue(), 6); // |</meta>
Assert.assertEquals(meta.getEndTagOpenOffset(), 6); // |</meta>
}

@Test
Expand Down Expand Up @@ -447,11 +444,9 @@ public void elementOffsets() {
Assert.assertNotNull(a);
Assert.assertEquals(a.getTagName(), "a");
Assert.assertEquals(a.getStart(), 0); // |<a></a>
Assert.assertNotNull(a.getStartTagOpenOffset()); // |<a></a>
Assert.assertEquals(a.getStartTagOpenOffset().intValue(), 0); // |<a></a>
Assert.assertNotNull(a.getStartTagCloseOffset()); // <a|></a>
Assert.assertEquals(a.getStartTagCloseOffset().intValue(), 2); // <a|></a>
Assert.assertEquals(a.getEndTagOpenOffset().intValue(), 3); // <a>|</a>
Assert.assertEquals(a.getStartTagOpenOffset(), 0); // |<a></a>
Assert.assertEquals(a.getStartTagCloseOffset(), 2); // <a|></a>
Assert.assertEquals(a.getEndTagOpenOffset(), 3); // <a>|</a>
Assert.assertEquals(a.getEnd(), 7); // <a></a>|

Assert.assertFalse(a.isInStartTag(0)); // |<a></a>
Expand Down Expand Up @@ -1003,10 +998,10 @@ private static DOMNode createNode(short nodeType, int start, int end) {
private static void setRestOfNode(DOMNode n, String tag, Integer endTagStart, boolean closed) {
if (n.isElement()) {
((DOMElement) n).tag = tag;
((DOMElement) n).endTagOpenOffset = endTagStart;
((DOMElement) n).endTagOpenOffset = endTagStart != null ? endTagStart : DOMNode.NULL_VALUE;
} else if (n instanceof DOMProcessingInstruction) {
((DOMProcessingInstruction) n).target = tag;
((DOMProcessingInstruction) n).endTagOpenOffset = endTagStart;
((DOMProcessingInstruction) n).endTagOpenOffset = endTagStart != null ? endTagStart : DOMNode.NULL_VALUE;
}
n.closed = closed;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lsp4xml.performance;

import static org.eclipse.lsp4xml.utils.IOUtils.convertStreamToString;

import java.io.InputStream;

import org.eclipse.lsp4xml.commons.TextDocument;
import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.dom.DOMParser;

/**
* This utility class is used to check the memory usage of {@link DOMParser},
* loading the large nasa.xml file.
*
* @author Angelo ZERR
*
*/
public class DOMParserPerformance {

public static void main(String[] args) {
InputStream in = DOMParserPerformance.class.getResourceAsStream("/xml/nasa.xml");
String text = convertStreamToString(in);
TextDocument document = new TextDocument(text, "nasa.xml");
// Continuously parses the large nasa.xml file with the DOM parser.
while (true) {
long start = System.currentTimeMillis();
DOMDocument xmlDocument = DOMParser.getInstance().parse(document, null);
System.err.println("Parsed 'nasa.xml' with DOMParser in " + (System.currentTimeMillis() - start) + " ms.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2019 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lsp4xml.performance;

import static org.eclipse.lsp4xml.utils.IOUtils.convertStreamToString;

import java.io.InputStream;

import org.eclipse.lsp4xml.dom.parser.Scanner;
import org.eclipse.lsp4xml.dom.parser.TokenType;
import org.eclipse.lsp4xml.dom.parser.XMLScanner;

/**
* This utility class is used to check the memory usage of {@link XMLScanner},
* loading the large nasa.xml file
*
* @author Angelo ZERR
*
*/
public class XMLScannerPerformance {

public static void main(String[] args) {
InputStream in = XMLScannerPerformance.class.getResourceAsStream("/xml/nasa.xml");
String text = convertStreamToString(in);
// Continuously parses the large nasa.xml file with the XML scanner
while (true) {
long start = System.currentTimeMillis();
Scanner scanner = XMLScanner.createScanner(text);
TokenType token = scanner.scan();
while (token != TokenType.EOS) {
token = scanner.scan();
}
System.err.println("Parsed 'nasa.xml' with XMLScanner in " + (System.currentTimeMillis() - start) + " ms.");
}
}
}
Loading

0 comments on commit b69c38e

Please sign in to comment.