You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2011/09/08 16:30:51 UTC
svn commit: r1166711 -
/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
Author: stefan
Date: Thu Sep 8 14:30:51 2011
New Revision: 1166711
URL: http://svn.apache.org/viewvc?rev=1166711&view=rev
Log:
getJournal() performance tweak
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java?rev=1166711&r1=1166710&r2=1166711&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelImpl.java Thu Sep 8 14:30:51 2011
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.mk.store.No
import org.apache.jackrabbit.mk.store.NodeUtils;
import org.apache.jackrabbit.mk.util.CommitGate;
import org.apache.jackrabbit.mk.util.PathUtils;
+import org.apache.jackrabbit.mk.util.SimpleLRUCache;
import java.io.InputStream;
import java.util.ArrayList;
@@ -42,6 +43,7 @@ public class MicroKernelImpl implements
protected Repository rep;
private final CommitGate gate = new CommitGate();
+ private final SimpleLRUCache<String, String> diffCache = SimpleLRUCache.newInstance(100);
public MicroKernelImpl(String homeDir) throws MicroKernelException {
init(homeDir);
@@ -66,6 +68,7 @@ public class MicroKernelImpl implements
}
rep = null;
}
+ diffCache.clear();
}
public String getHeadRevision() throws MicroKernelException {
@@ -169,91 +172,32 @@ public class MicroKernelImpl implements
key("id").value(commit.getId()).
key("ts").value(commit.getCommitTS()).
key("msg").value(commit.getMsg());
- final JsopBuilder buff = new JsopBuilder();
- // maps (key: id of target node, value: path/to/target)
- // for tracking added/removed nodes; this allows us
- // to detect 'move' operations
- final HashMap<String, String> addedNodes = new HashMap<String, String>();
- final HashMap<String, String> removedNodes = new HashMap<String, String>();
- try {
- String path = "/";
- Node node1 = rep.getNode(commit.getParentId(), path);
- Node node2 = rep.getNode(commit.getId(), path);
-
- NodeUtils.diff(path, node1, node2, true, rep.getPersistenceManager(), new NodeDiffHandler() {
- public void propAdded(String nodePath, String propName, String value) {
- buff.appendTag("+ ").
- key(PathUtils.concat(nodePath, propName)).
- encodedValue(value).
- newline();
- }
-
- public void propChanged(String nodePath, String propName, String oldValue, String newValue) {
- buff.appendTag("^ ").
- key(PathUtils.concat(nodePath, propName)).
- encodedValue(newValue).
- newline();
- }
-
- public void propDeleted(String nodePath, String propName, String value) {
- // since property and node deletions can't be distinguished
- // using the "- <path>" notation we're representing
- // property deletions as "^ <path>:null"
- buff.appendTag("^ ").
- key(PathUtils.concat(nodePath, propName)).
- encodedValue("null").
- newline();
- }
+ String diff = diffCache.get(commit.getId());
+ if (diff == null) {
+ final JsopBuilder buff = new JsopBuilder();
+ // maps (key: id of target node, value: path/to/target)
+ // for tracking added/removed nodes; this allows us
+ // to detect 'move' operations
+ final HashMap<String, String> addedNodes = new HashMap<String, String>();
+ final HashMap<String, String> removedNodes = new HashMap<String, String>();
+ try {
+ String path = "/";
+ Node node1 = rep.getNode(commit.getParentId(), path);
+ Node node2 = rep.getNode(commit.getId(), path);
- public void childNodeAdded(String nodePath, String childName, String id) {
- addedNodes.put(id, PathUtils.concat(nodePath, childName));
- buff.appendTag("+ ").
- key(PathUtils.concat(nodePath, childName)).object();
- try {
- toJson(buff, rep.getPersistenceManager().getNode(id), childName, Integer.MAX_VALUE, 0, -1);
- } catch (Exception e) {
- buff.value("ERROR: failed to retrieve node " + id);
- }
- buff.endObject().newline();
- }
-
- public void childNodeDeleted(String nodePath, String childName, String id) {
- removedNodes.put(id, PathUtils.concat(nodePath, childName));
- buff.appendTag("- ");
- buff.value(PathUtils.concat(nodePath, childName));
- buff.newline();
- }
-
- public void childNodeChanged(String nodePath, String childName, String oldId, String newId) {
- // we're not interested
- }
- });
-
- // check if this commit includes 'move' operations
- // by building intersection of added and removed nodes
- addedNodes.keySet().retainAll(removedNodes.keySet());
- if (!addedNodes.isEmpty()) {
- // this commit includes 'move' operations
- removedNodes.keySet().retainAll(addedNodes.keySet());
- // addedNodes & removedNodes now only contain information about moved nodes
-
- // re-build the diff in a 2nd pass, this time representing moves correctly
- buff.reset();
-
- // TODO refactor code, avoid duplication
NodeUtils.diff(path, node1, node2, true, rep.getPersistenceManager(), new NodeDiffHandler() {
public void propAdded(String nodePath, String propName, String value) {
buff.appendTag("+ ").
key(PathUtils.concat(nodePath, propName)).
encodedValue(value).
- appendTag("\n");
+ newline();
}
public void propChanged(String nodePath, String propName, String oldValue, String newValue) {
buff.appendTag("^ ").
key(PathUtils.concat(nodePath, propName)).
encodedValue(newValue).
- appendTag("\n");
+ newline();
}
public void propDeleted(String nodePath, String propName, String value) {
@@ -263,14 +207,11 @@ public class MicroKernelImpl implements
buff.appendTag("^ ").
key(PathUtils.concat(nodePath, propName)).
encodedValue("null").
- appendTag("\n");
+ newline();
}
public void childNodeAdded(String nodePath, String childName, String id) {
- if (addedNodes.containsKey(id)) {
- // moved node, will be processed separately
- return;
- }
+ addedNodes.put(id, PathUtils.concat(nodePath, childName));
buff.appendTag("+ ").
key(PathUtils.concat(nodePath, childName)).object();
try {
@@ -278,37 +219,104 @@ public class MicroKernelImpl implements
} catch (Exception e) {
buff.value("ERROR: failed to retrieve node " + id);
}
- buff.endObject().appendTag("\n");
+ buff.endObject().newline();
}
public void childNodeDeleted(String nodePath, String childName, String id) {
- if (addedNodes.containsKey(id)) {
- // moved node, will be processed separately
- return;
- }
+ removedNodes.put(id, PathUtils.concat(nodePath, childName));
buff.appendTag("- ");
buff.value(PathUtils.concat(nodePath, childName));
- buff.appendTag("\n");
+ buff.newline();
}
public void childNodeChanged(String nodePath, String childName, String oldId, String newId) {
// we're not interested
}
});
- // finally process moved nodes
- for (Map.Entry<String, String> entry : addedNodes.entrySet()) {
- buff.appendTag("> ").
- // path/to/deleted/node
- key(removedNodes.get(entry.getKey())).
- // path/to/added/node
- value(entry.getValue()).
- newline();
+
+ // check if this commit includes 'move' operations
+ // by building intersection of added and removed nodes
+ addedNodes.keySet().retainAll(removedNodes.keySet());
+ if (!addedNodes.isEmpty()) {
+ // this commit includes 'move' operations
+ removedNodes.keySet().retainAll(addedNodes.keySet());
+ // addedNodes & removedNodes now only contain information about moved nodes
+
+ // re-build the diff in a 2nd pass, this time representing moves correctly
+ buff.reset();
+
+ // TODO refactor code, avoid duplication
+ NodeUtils.diff(path, node1, node2, true, rep.getPersistenceManager(), new NodeDiffHandler() {
+ public void propAdded(String nodePath, String propName, String value) {
+ buff.appendTag("+ ").
+ key(PathUtils.concat(nodePath, propName)).
+ encodedValue(value).
+ appendTag("\n");
+ }
+
+ public void propChanged(String nodePath, String propName, String oldValue, String newValue) {
+ buff.appendTag("^ ").
+ key(PathUtils.concat(nodePath, propName)).
+ encodedValue(newValue).
+ appendTag("\n");
+ }
+
+ public void propDeleted(String nodePath, String propName, String value) {
+ // since property and node deletions can't be distinguished
+ // using the "- <path>" notation we're representing
+ // property deletions as "^ <path>:null"
+ buff.appendTag("^ ").
+ key(PathUtils.concat(nodePath, propName)).
+ encodedValue("null").
+ appendTag("\n");
+ }
+
+ public void childNodeAdded(String nodePath, String childName, String id) {
+ if (addedNodes.containsKey(id)) {
+ // moved node, will be processed separately
+ return;
+ }
+ buff.appendTag("+ ").
+ key(PathUtils.concat(nodePath, childName)).object();
+ try {
+ toJson(buff, rep.getPersistenceManager().getNode(id), childName, Integer.MAX_VALUE, 0, -1);
+ } catch (Exception e) {
+ buff.value("ERROR: failed to retrieve node " + id);
+ }
+ buff.endObject().appendTag("\n");
+ }
+
+ public void childNodeDeleted(String nodePath, String childName, String id) {
+ if (addedNodes.containsKey(id)) {
+ // moved node, will be processed separately
+ return;
+ }
+ buff.appendTag("- ");
+ buff.value(PathUtils.concat(nodePath, childName));
+ buff.appendTag("\n");
+ }
+
+ public void childNodeChanged(String nodePath, String childName, String oldId, String newId) {
+ // we're not interested
+ }
+ });
+ // finally process moved nodes
+ for (Map.Entry<String, String> entry : addedNodes.entrySet()) {
+ buff.appendTag("> ").
+ // path/to/deleted/node
+ key(removedNodes.get(entry.getKey())).
+ // path/to/added/node
+ value(entry.getValue()).
+ newline();
+ }
}
+ diff = buff.toString();
+ diffCache.put(commit.getId(), diff);
+ } catch (Exception e) {
+ throw new MicroKernelException(e);
}
- } catch (Exception e) {
- throw new MicroKernelException(e);
}
- commitBuff.key("changes").value(buff.toString()).endObject();
+ commitBuff.key("changes").value(diff).endObject();
}
return commitBuff.endArray().toString();
}
@@ -383,6 +391,7 @@ public class MicroKernelImpl implements
break;
}
case '>': {
+ // TODO: support reorder syntax
String relPath = t.readString();
t.read(':');
String targetPath = t.readString();
@@ -390,64 +399,6 @@ public class MicroKernelImpl implements
targetPath = PathUtils.concat(path, targetPath);
}
cb.moveNode(PathUtils.concat(path, relPath), targetPath);
-/*
- path = t.readString();
- String from = PathUtils.concat(fromRoot, path);
- String name = PathUtils.getName(from);
- t.read(':');
- String position, target;
- boolean rename;
- String to;
- if (t.matches('{')) {
- rename = false;
- position = t.readString();
- t.read(':');
- target = t.readString();
- t.read('}');
- } else {
- rename = true;
- position = null;
- target = t.readString();
- }
- boolean before = false;
- if ("last".equals(position)) {
- target = PathUtils.concat(target, name);
- position = null;
- } else if ("first".equals(position)) {
- target = PathUtils.concat(target, name);
- position = null;
- before = true;
- } else if ("before".equals(position)) {
- position = PathUtils.getName(target);
- target = PathUtils.getParentPath(target);
- target = PathUtils.concat(target, name);
- before = true;
- } else if ("after".equals(position)) {
- position = PathUtils.getName(target);
- target = PathUtils.getParentPath(target);
- target = PathUtils.concat(target, name);
- } else if (position == null) {
- // move
- } else {
- throw new AssertionError("position: " + position);
- }
- to = PathUtils.concat(fromRoot, target);
- boolean inPlaceRename = false;
- if (rename) {
- if (PathUtils.getParentPath(from).equals(PathUtils.getParentPath(to))) {
- inPlaceRename = true;
- position = PathUtils.getName(from);
- }
- }
- NodeImpl node = headRoot.getNode(from);
- if (!inPlaceRename) {
- headRoot = headRoot.cloneAndRemoveChildNode(from, headRevId);
- }
- headRoot = headRoot.cloneAndAddChildNode(to, before, position, node, headRevId);
- if (inPlaceRename) {
- headRoot = headRoot.cloneAndRemoveChildNode(from, headRevId);
- }
-*/
break;
}
default: