You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/11/02 03:08:36 UTC
svn commit: r1538131 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath:
GlobalNameMapper.java LocalNameMapper.java NamePathMapperImpl.java
Author: jukka
Date: Sat Nov 2 02:08:35 2013
New Revision: 1538131
URL: http://svn.apache.org/r1538131
Log:
OAK-1015: Optimise path parsing
Imprve the heuristics used to avoid full path parsing for "simple" paths
Also unify the getJcrName() checks against hidden and expanded names
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java?rev=1538131&r1=1538130&r2=1538131&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java Sat Nov 2 02:08:35 2013
@@ -41,6 +41,19 @@ import static org.apache.jackrabbit.oak.
*/
public class GlobalNameMapper implements NameMapper {
+ protected static boolean isHiddenName(String name) {
+ return name.startsWith(":");
+ }
+
+ protected static boolean isExpandedName(String name) {
+ if (name.startsWith("{")) {
+ int brace = name.indexOf('}', 1);
+ return brace != -1 && name.substring(1, brace).indexOf(':') != -1;
+ } else {
+ return false;
+ }
+ }
+
protected final Tree tree;
public GlobalNameMapper(Tree tree) {
@@ -51,8 +64,8 @@ public class GlobalNameMapper implements
public String getJcrName(@Nonnull String oakName) {
// Sanity checks, can be turned to assertions if needed for performance
checkNotNull(oakName);
- checkArgument(!oakName.startsWith(":")); // hidden name
- checkArgument(!oakName.startsWith("{")); // expanded name
+ checkArgument(!isHiddenName(oakName), oakName);
+ checkArgument(!isExpandedName(oakName), oakName);
return oakName;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java?rev=1538131&r1=1538130&r2=1538131&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java Sat Nov 2 02:08:35 2013
@@ -35,15 +35,6 @@ public abstract class LocalNameMapper ex
super(tree);
}
- private static boolean isExpandedName(String name) {
- if (name.startsWith("{")) {
- int brace = name.indexOf('}', 1);
- return brace != -1 && name.substring(1, brace).indexOf(':') != -1;
- } else {
- return false;
- }
- }
-
@Override @CheckForNull
public String getJcrName(String oakName) {
checkNotNull(oakName);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java?rev=1538131&r1=1538130&r2=1538131&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImpl.java Sat Nov 2 02:08:35 2013
@@ -140,9 +140,8 @@ public class NamePathMapperImpl implemen
}
private String getOakPath(final String jcrPath, final boolean keepIndex) {
- if ("/".equals(jcrPath)) {
- // avoid the need to special case the root path later on
- return "/";
+ if (!needsFullMapping(jcrPath)) {
+ return jcrPath;
}
int length = jcrPath.length();
@@ -160,23 +159,6 @@ public class NamePathMapperImpl implemen
return this.idManager.getPath(jcrPath.substring(1, length - 1));
}
- // Shortcut iff the JCR path does not start with a dot, does not contain any of
- // {}[]/ and if it contains a colon the session does not have local re-mappings.
- boolean hasLocalMappings = hasSessionLocalMappings();
- boolean shortcut = length > 0 && jcrPath.charAt(0) != '.';
- for (int i = 0; shortcut && i < length; i++) {
- char c = jcrPath.charAt(i);
- if (c == '{' || c == '}' || c == '[' || c == ']' || c == '/') {
- shortcut = false;
- } else if (c == ':') {
- shortcut = !hasLocalMappings;
- }
- }
-
- if (shortcut) {
- return jcrPath;
- }
-
final StringBuilder parseErrors = new StringBuilder();
PathListener listener = new PathListener() {
@@ -233,6 +215,68 @@ public class NamePathMapperImpl implemen
return oakPath.toString();
}
+ /**
+ * Checks if the given path needs to be fully parsed to apply namespace
+ * mappings or to validate its syntax. If the given path is "simple", i.e.
+ * it doesn't contain any complex constructs, and there are no local
+ * namespace remappings, it's possible to skip the full path parsing
+ * and simply use the JCR path string as-is as an Oak path.
+ *
+ * @param path JCR path
+ * @return {@code true} if the path needs to be fully parsed,
+ * {@code false} if not
+ */
+ private boolean needsFullMapping(String path) {
+ int length = path.length();
+ if (length == 0) {
+ return true;
+ }
+
+ int slash = -1; // index of the last slash in the path
+ int colon = -1; // index of the last colon in the path
+
+ switch (path.charAt(0)) {
+ case '{': // possibly an expanded name
+ case '[': // starts with an identifier
+ case '.': // possibly "." or ".."
+ case ':': // colon as the first character
+ return true;
+ case '/':
+ if (length == 1) {
+ return false; // the root path
+ }
+ slash = 0;
+ break;
+ }
+
+ for (int i = 1; i < length; i++) {
+ switch (path.charAt(i)) {
+ case '{': // possibly an expanded name
+ case '[': // possibly an index
+ return true;
+ case '.':
+ if (i == slash + 1) {
+ return true; // possibly "." or ".."
+ }
+ break;
+ case ':':
+ if (i == slash + 1 || i == colon + i || i + 1 == length) {
+ return true; // colon following slash/colon or as last char
+ }
+ colon = i;
+ break;
+ case '/':
+ if (i == slash + 1 || i == colon + i || i + 1 == length) {
+ return true; // colon following slash/colon or as last char
+ }
+ slash = i;
+ break;
+ }
+ }
+
+ return colon != -1 && hasSessionLocalMappings();
+ }
+
//------------------------------------------------------------< PathListener >---
private abstract static class PathListener implements Listener {