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: