From 614d00b258507ba5ab219dc412e61ea6ca7fed33 Mon Sep 17 00:00:00 2001 From: Ryan Gustafson Date: Fri, 1 May 2009 04:57:10 +0000 Subject: [PATCH] Clean up ReportTree.addRuleViolation, to stop using String.split, and += on Strings. This removes a regex, and vastly reduces the number of memory/buffer allocations that are going on. git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@6932 51baf565-9d33-0410-a72c-fc3788e3496d --- .../pmd/lang/dfa/report/ReportTree.java | 268 +++++++++--------- 1 file changed, 132 insertions(+), 136 deletions(-) diff --git a/pmd/src/net/sourceforge/pmd/lang/dfa/report/ReportTree.java b/pmd/src/net/sourceforge/pmd/lang/dfa/report/ReportTree.java index a55f4b10bb..b7ac27d55b 100644 --- a/pmd/src/net/sourceforge/pmd/lang/dfa/report/ReportTree.java +++ b/pmd/src/net/sourceforge/pmd/lang/dfa/report/ReportTree.java @@ -1,9 +1,9 @@ package net.sourceforge.pmd.lang.dfa.report; -import net.sourceforge.pmd.RuleViolation; - import java.util.Iterator; +import net.sourceforge.pmd.RuleViolation; + public class ReportTree { private PackageNode rootNode = new PackageNode(""); @@ -11,94 +11,92 @@ public class ReportTree { private class TreeIterator implements Iterator { - private AbstractReportNode iterNode = rootNode; - private boolean hasNextFlag; + private AbstractReportNode iterNode = rootNode; + private boolean hasNextFlag; - public void remove() { - throw new UnsupportedOperationException(); - } + public void remove() { + throw new UnsupportedOperationException(); + } - public boolean hasNext() { - this.hasNextFlag = true; - return this.getNext() != null; - } + public boolean hasNext() { + this.hasNextFlag = true; + return this.getNext() != null; + } - public RuleViolation next() { + public RuleViolation next() { + if (!this.hasNextFlag) { + this.getNext(); + } else { + this.hasNextFlag = false; + } - if (!this.hasNextFlag) { - this.getNext(); - } else { - this.hasNextFlag = false; - } + if (this.iterNode instanceof ViolationNode) { + return ((ViolationNode) this.iterNode).getRuleViolation(); + } + return null; + } - if (this.iterNode instanceof ViolationNode) { - return ((ViolationNode) this.iterNode).getRuleViolation(); - } - return null; - } + /** + * It's some kind of left-right-middle search (postorder). + * It always returns only + * leafs. The first node he returns is the most left handed leaf he can + * found. Now he's looking for siblings and if there are any, he starts + * searching for the next most left handed leaf. If there are no + * siblings he goes up to his parent and starts looking for siblings. + * If there are any he starts searching for the next most left handed + * leaf again. And so on ... until he wants to get the parent of the + * root node. Because there is no one, the search stops. + */ - /** - * It's some kind of left-right-middle search (postorder). - * It always returns only - * leafs. The first node he returns is the most left handed leaf he can - * found. Now he's looking for siblings and if there are any, he starts - * searching for the next most left handed leaf. If there are no - * siblings he goes up to his parent and starts looking for siblings. - * If there are any he starts searching for the next most left handed - * leaf again. And so on ... until he wants to get the parent of the - * root node. Because there is no one, the search stops. - */ + private AbstractReportNode getNext() { + AbstractReportNode node; - private AbstractReportNode getNext() { - AbstractReportNode node; + while (true) { + if (this.iterNode.isLeaf()) { - while (true) { - if (this.iterNode.isLeaf()) { + while ((node = this.iterNode.getNextSibling()) == null) { - while ((node = this.iterNode.getNextSibling()) == null) { + node = this.iterNode.getParent(); + if (node == null) { + return null; + } else { + this.iterNode = node; + } + } - node = this.iterNode.getParent(); - if (node == null) { - return null; - } else { - this.iterNode = node; - } - } - - this.iterNode = node; - if (this.iterNode.isLeaf()) { - return this.iterNode; - } else { - continue; - } - } else { - this.iterNode = this.iterNode.getFirstChild(); - if (this.iterNode.isLeaf()) { - return this.iterNode; - } else { - continue; - } - } - } - } + this.iterNode = node; + if (this.iterNode.isLeaf()) { + return this.iterNode; + } else { + continue; + } + } else { + this.iterNode = this.iterNode.getFirstChild(); + if (this.iterNode.isLeaf()) { + return this.iterNode; + } else { + continue; + } + } + } + } } - public Iterator iterator() { - return new TreeIterator(); + return new TreeIterator(); } public int size() { - int count = 0; - for (Iterator i = iterator(); i.hasNext();) { - i.next(); - count++; - } - return count; + int count = 0; + for (Iterator i = iterator(); i.hasNext();) { + i.next(); + count++; + } + return count; } public AbstractReportNode getRootNode() { - return rootNode; + return rootNode; } /** @@ -106,62 +104,64 @@ public class ReportTree { * package, class and violation gets there own tree node. */ public void addRuleViolation(RuleViolation violation) { - String pack = violation.getPackageName(); - String[] a = {}; - if (pack == null) { - a = new String[]{""}; - } else if (pack.indexOf('.') != -1) { - String[] tmp = pack.split("\\."); - a = new String[tmp.length]; - System.arraycopy(tmp, 0, a, 0, tmp.length); - } else { - a = new String[]{pack}; - } + String packageName = violation.getPackageName(); + if (packageName == null) { + packageName = ""; + } - this.level = this.rootNode; - String plugedPackageName = ""; + this.level = this.rootNode; - for (int i = 0; i < a.length; i++) { - String packageName = a[i]; - plugedPackageName += packageName + '.'; + int endIndex = packageName.indexOf('.'); + while (true) { + String parentPackage; + if (endIndex < 0) { + parentPackage = packageName; + } else { + parentPackage = packageName.substring(0, endIndex); + } - if (!this.isStringInLevel(plugedPackageName)) { - PackageNode node = new PackageNode(plugedPackageName); - this.level.addFirst(node); - // gotoLevel - this.level = node; - } - } + if (!this.isStringInLevel(parentPackage)) { + PackageNode node = new PackageNode(parentPackage); + this.level.addFirst(node); + // gotoLevel + this.level = node; + } - String cl = violation.getClassName(); + if (endIndex < 0) { + break; + } + endIndex = packageName.indexOf('.', endIndex + 1); + } - if (!this.isStringInLevel(cl)) { - ClassNode node = new ClassNode(cl); - this.level.addFirst(node); - // gotoLevel - this.level = node; - } + String cl = violation.getClassName(); - /* - * Filters dublicated rule violations. Like the comparator in - * RuleViolation if he already exists. - */ - ViolationNode tmp = new ViolationNode(violation); - if (!this.equalsNodeInLevel(this.level, tmp)) { - this.level.add(tmp); - } + if (!this.isStringInLevel(cl)) { + ClassNode node = new ClassNode(cl); + this.level.addFirst(node); + // gotoLevel + this.level = node; + } + + /* + * Filters duplicated rule violations. Like the comparator in + * RuleViolation if he already exists. + */ + ViolationNode tmp = new ViolationNode(violation); + if (!this.equalsNodeInLevel(this.level, tmp)) { + this.level.add(tmp); + } } /** * Checks if node is a child of the level node. */ private boolean equalsNodeInLevel(AbstractReportNode level, AbstractReportNode node) { - for (int i = 0; i < level.getChildCount(); i++) { - if (level.getChildAt(i).equalsNode(node)) { - return true; - } - } - return false; + for (int i = 0; i < level.getChildCount(); i++) { + if (level.getChildAt(i).equalsNode(node)) { + return true; + } + } + return false; } /** @@ -171,28 +171,24 @@ public class ReportTree { */ private boolean isStringInLevel(String str) { - for (int i = 0; i < this.level.getChildCount(); i++) { - AbstractReportNode child = this.level.getChildAt(i); - String tmp = null; + for (int i = 0; i < this.level.getChildCount(); i++) { + final AbstractReportNode child = this.level.getChildAt(i); + final String tmp; + if (child instanceof PackageNode) { + tmp = ((PackageNode) child).getPackageName(); + } else if (child instanceof ClassNode) { + tmp = ((ClassNode) child).getClassName(); + } else { + return false; + } - if (child instanceof PackageNode) { - tmp = ((PackageNode) child).getPackageName(); - } - if (child instanceof ClassNode) { - tmp = ((ClassNode) child).getClassName(); - } - - if (tmp == null) { - return false; - } - - if (tmp.equals(str)) { - // goto level - this.level = child; - return true; - } - } - return false; + if (tmp != null && tmp.equals(str)) { + // goto level + this.level = child; + return true; + } + } + return false; } }