You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2008/09/03 15:34:44 UTC
svn commit: r691606 - in
/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name:
HashCache.java PathFactoryImpl.java PathMap.java
Author: mreutegg
Date: Wed Sep 3 06:34:43 2008
New Revision: 691606
URL: http://svn.apache.org/viewvc?rev=691606&view=rev
Log:
JCR-1715: Prevent excessive Path.Element instances
Modified:
jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/HashCache.java
jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java
jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathMap.java
Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/HashCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/HashCache.java?rev=691606&r1=691605&r2=691606&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/HashCache.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/HashCache.java Wed Sep 3 06:34:43 2008
@@ -25,7 +25,7 @@
*
* @see https://issues.apache.org/jira/browse/JCR-1663
*/
-class HashCache {
+public class HashCache {
/**
* Size of the cache (must be a power of two). Note that this is the
Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java?rev=691606&r1=691605&r2=691606&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java Wed Sep 3 06:34:43 2008
@@ -54,6 +54,8 @@
private static final Path CURRENT_PATH = new PathImpl(new Path.Element[]{CURRENT_ELEMENT}, true);
private static final Path PARENT_PATH = new PathImpl(new Path.Element[]{PARENT_ELEMENT}, true);
+ private final HashCache ELEMENT_CACHE = new HashCache();
+
private PathFactoryImpl() {}
public static PathFactory getInstance() {
@@ -180,7 +182,7 @@
} else if (name.equals(ROOT_NAME)) {
return ROOT_ELEMENT;
} else {
- return new Element(name, Path.INDEX_UNDEFINED);
+ return getCachedElement(new Element(name, Path.INDEX_UNDEFINED));
}
}
@@ -220,7 +222,7 @@
int pos = elementString.indexOf('[');
if (pos == -1) {
Name name = NAME_FACTORY.create(elementString);
- return new Element(name, Path.INDEX_UNDEFINED);
+ return getCachedElement(new Element(name, Path.INDEX_UNDEFINED));
}
Name name = NAME_FACTORY.create(elementString.substring(0, pos));
int pos1 = elementString.indexOf(']');
@@ -644,6 +646,20 @@
}
//-------------------------------------------------------< Path.Element >---
+
+ /**
+ * If a cached copy of the given element already exists, then returns
+ * that copy. Otherwise the given element is cached and returned. This
+ * method only works correctly with elements that have an undefined index!
+ *
+ * @param element the element to return from the cache
+ * @return the given element or a previously cached copy
+ */
+ private Element getCachedElement(Element element) {
+ assert element.getIndex() == Path.INDEX_UNDEFINED;
+ return (Element) ELEMENT_CACHE.get(element);
+ }
+
/**
* Object representation of a single JCR path element.
*
Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathMap.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathMap.java?rev=691606&r1=691605&r2=691606&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathMap.java (original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathMap.java Wed Sep 3 06:34:43 2008
@@ -131,7 +131,7 @@
* Internal class holding the object associated with a certain
* path element.
*/
- public static class Element {
+ public final static class Element {
/**
* Parent element
@@ -154,9 +154,11 @@
private Object obj;
/**
- * Name associated with this element
+ * Path.Element suitable for path construction associated with this
+ * element. The path element will never have a default index. Instead an
+ * undefined index value is set in that case.
*/
- private Name name;
+ private Path.Element pathElement;
/**
* 1-based index associated with this element where index=0 is
@@ -169,8 +171,13 @@
* @param nameIndex path element of this child
*/
private Element(Path.Element nameIndex) {
- this.name = nameIndex.getName();
this.index = nameIndex.getIndex();
+ if (nameIndex.denotesName()) {
+ updatePathElement(nameIndex.getName(), index);
+ } else {
+ // root, current or parent
+ this.pathElement = nameIndex;
+ }
}
/**
@@ -185,6 +192,20 @@
}
/**
+ * Updates the {@link #pathElement} with a new name and index value.
+ *
+ * @param name the new name.
+ * @param index the new index.
+ */
+ private void updatePathElement(Name name, int index) {
+ if (index == Path.INDEX_DEFAULT) {
+ pathElement = PATH_FACTORY.createElement(name);
+ } else {
+ pathElement = PATH_FACTORY.createElement(name, index);
+ }
+ }
+
+ /**
* Insert an empty child. Will shift all children having an index
* greater than or equal to the child inserted to the right.
* @param nameIndex position where child is inserted
@@ -199,6 +220,7 @@
Element element = (Element) list.get(i);
if (element != null) {
element.index = element.getNormalizedIndex() + 1;
+ element.updatePathElement(element.getName(), element.index);
}
}
list.add(index, null);
@@ -252,8 +274,8 @@
}
element.parent = this;
- element.name = nameIndex.getName();
element.index = nameIndex.getIndex();
+ element.updatePathElement(nameIndex.getName(), element.index);
childrenCount++;
}
@@ -305,6 +327,7 @@
Element sibling = (Element) list.get(i);
if (sibling != null) {
sibling.index--;
+ sibling.updatePathElement(sibling.getName(), sibling.index);
}
}
list.remove(index);
@@ -409,7 +432,7 @@
* @return name
*/
public Name getName() {
- return name;
+ return pathElement.getName();
}
/**
@@ -430,11 +453,7 @@
* @return 1-based index
*/
public int getNormalizedIndex() {
- if (index == Path.INDEX_UNDEFINED) {
- return Path.INDEX_DEFAULT;
- } else {
- return index;
- }
+ return pathElement.getNormalizedIndex();
}
/**
@@ -443,9 +462,9 @@
*/
public Path.Element getPathElement() {
if (index < Path.INDEX_DEFAULT) {
- return PATH_FACTORY.create(name).getNameElement();
+ return PATH_FACTORY.create(getName()).getNameElement();
} else {
- return PATH_FACTORY.create(name, index).getNameElement();
+ return PATH_FACTORY.create(getName(), index).getNameElement();
}
}
@@ -475,11 +494,7 @@
return;
}
parent.getPath(builder);
- if (index == Path.INDEX_UNDEFINED || index == Path.INDEX_DEFAULT) {
- builder.addLast(name);
- } else {
- builder.addLast(name, index);
- }
+ builder.addLast(pathElement);
}
/**