jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1561246 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: plugins/observation/ spi/commit/
Date Sat, 25 Jan 2014 02:29:12 GMT
Author: jukka
Date: Sat Jan 25 02:29:12 2014
New Revision: 1561246

URL: http://svn.apache.org/r1561246
Log:
OAK-1332: Large number of changes to the same node can fill observation queue

Extract the shared state of all observation events originating from the
same commit to a separate EventContext object. This helps reduce the
memory overhead of a large queue of events.

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java
  (with props)
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/JcrListener.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java?rev=1561246&r1=1561245&r2=1561246&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
Sat Jan 25 02:29:12 2014
@@ -163,10 +163,11 @@ public class ChangeProcessor implements 
                     EventFilter acFilter = new ACFilter(previousRoot, root, permissionProvider,
basePath);
                     ImmutableTree beforeTree = getTree(previousRoot, basePath);
                     ImmutableTree afterTree = getTree(root, basePath);
+                    EventContext context = new EventContext(namePathMapper, info);
                     EventIterable<Event> events = new EventIterable<Event>(
                             beforeTree.getNodeState(), afterTree.getNodeState(),
                             Filters.all(userFilter, acFilter),
-                            new JcrListener(beforeTree, afterTree, namePathMapper, info));
+                            new JcrListener(context, beforeTree, afterTree));
                     Iterator<Event> iterator = events.iterator();
                     if (iterator.hasNext() && runningMonitor.enterIf(running)) {
                         try {

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java?rev=1561246&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java
(added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java
Sat Jan 25 02:29:12 2014
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.observation;
+
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+
+/**
+ * Information shared by all events coming from a single commit.
+ */
+final class EventContext {
+
+    /**
+     * Dummy session identifier used to identify external commits.
+     */
+    private static final String OAK_EXTERNAL = "oak:external";
+
+    private final NamePathMapper mapper;
+
+    private final CommitInfo info;
+
+    EventContext(NamePathMapper mapper, CommitInfo info) {
+        this.mapper = mapper;
+        if (info != null) {
+            this.info = info;
+        } else {
+            // Generate a dummy CommitInfo object to avoid extra null checks.
+            // The current time is used as a rough estimate of the commit time.
+            this.info = new CommitInfo(OAK_EXTERNAL, null, null);
+        }
+    }
+
+    String getJcrName(String name) {
+        return mapper.getJcrName(name);
+    }
+
+    String getJcrPath(String path) {
+        return mapper.getJcrPath(path);
+    }
+
+    String getUserID() {
+        return info.getUserId();
+    }
+
+    String getUserData() {
+        return info.getMessage();
+    }
+
+    long getDate() {
+        return info.getDate();
+    }
+
+    boolean isExternal() {
+        return info.getSessionId() == OAK_EXTERNAL;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        } else if (object instanceof EventContext) {
+            EventContext that = (EventContext) object;
+            return info.equals(that.info);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return info.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return info.toString();
+    }
+
+}
\ No newline at end of file

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java?rev=1561246&r1=1561245&r2=1561246&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java
Sat Jan 25 02:29:12 2014
@@ -16,41 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.jackrabbit.oak.plugins.observation;
 
-import java.util.Collections;
 import java.util.Map;
 
-import javax.jcr.RepositoryException;
-
 import org.apache.jackrabbit.api.observation.JackrabbitEvent;
 
+import com.google.common.base.Objects;
+
 /**
  * TODO document
  */
-class EventImpl implements JackrabbitEvent {
+final class EventImpl implements JackrabbitEvent {
 
+    private final EventContext context;
     private final int type;
-    private final String jcrPath;
-    private final String userID;
+    private final String path;
     private final String identifier;
     private final Map<?, ?> info;
-    private final long date;
-    private final String userData;
-    private final boolean external;
-
-    EventImpl(
-            int type, String jcrPath, String userID, String identifier,
-            Map<?, ?> info, long date, String userData, boolean external) {
+
+    EventImpl(EventContext context,
+            int type, String path, String identifier, Map<?, ?> info) {
+        this.context = context;
         this.type = type;
-        this.jcrPath = jcrPath;
-        this.userID = userID;
+        this.path = path;
         this.identifier = identifier;
-        this.info = info == null ? Collections.emptyMap() : info;
-        this.date = date;
-        this.userData = userData;
-        this.external = external;
+        this.info = info;
     }
 
     @Override
@@ -59,13 +50,13 @@ class EventImpl implements JackrabbitEve
     }
 
     @Override
-    public String getPath() throws RepositoryException {
-        return jcrPath;
+    public String getPath() {
+        return context.getJcrPath(path);
     }
 
     @Override
     public String getUserID() {
-        return userID;
+        return context.getUserID();
     }
 
     @Override
@@ -80,63 +71,51 @@ class EventImpl implements JackrabbitEve
 
     @Override
     public String getUserData() {
-        return userData;
+        return context.getUserData();
     }
 
     @Override
     public long getDate() {
-        return date;
+        return context.getDate();
     }
 
     @Override
-    public synchronized boolean isExternal() {
-        return external;
+    public boolean isExternal() {
+        return context.isExternal();
     }
 
+    //------------------------------------------------------------< Object >--
+
     @Override
-    public final boolean equals(Object other) {
-        if (this == other) {
+    public boolean equals(Object object) {
+        if (this == object) {
             return true;
-        }
-        if (other == null || getClass() != other.getClass()) {
+        } else if (object instanceof EventImpl) {
+            EventImpl that = (EventImpl) object;
+            return Objects.equal(this.context, that.context)
+                    && this.type == that.type
+                    && Objects.equal(this.path, that.path)
+                    && Objects.equal(this.identifier, that.identifier)
+                    && Objects.equal(this.info, that.info);
+        } else {
             return false;
         }
-
-        EventImpl that = (EventImpl) other;
-        return date == that.date && type == that.type &&
-                (identifier == null ? that.identifier == null : identifier.equals(that.identifier))
&&
-                (info == null ? that.info == null : info.equals(that.info)) &&
-                (jcrPath == null ? that.jcrPath == null : jcrPath.equals(that.jcrPath)) &&
-                (userID == null ? that.userID == null : userID.equals(that.userID)) &&
-                (userData == null ? that.userData == null : userData.equals(that.userData))
&&
-                external == that.external;
-
     }
 
     @Override
-    public final int hashCode() {
-        int result = type;
-        result = 31 * result + (jcrPath == null ? 0 : jcrPath.hashCode());
-        result = 31 * result + (userID == null ? 0 : userID.hashCode());
-        result = 31 * result + (identifier == null ? 0 : identifier.hashCode());
-        result = 31 * result + (info == null ? 0 : info.hashCode());
-        result = 31 * result + (int) (date ^ (date >>> 32));
-        result = 31 * result + (userData == null ? 0 :  userData.hashCode());
-        return result;
+    public int hashCode() {
+        return Objects.hashCode(context, type, path, identifier, info);
     }
 
     @Override
     public String toString() {
-        return "EventImpl{" +
-                "type=" + type +
-                ", jcrPath='" + jcrPath + '\'' +
-                ", userID='" + userID + '\'' +
-                ", identifier='" + identifier + '\'' +
-                ", info=" + info +
-                ", date=" + date +
-                ", userData=" + userData +
-                ", external=" + external +
-                '}';
+        return Objects.toStringHelper(this)
+                .add("type", type)
+                .add("path", path)
+                .add("identifier", identifier)
+                .add("info", info)
+                .add("context", context)
+                .toString();
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/JcrListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/JcrListener.java?rev=1561246&r1=1561245&r2=1561246&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/JcrListener.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/JcrListener.java
Sat Jan 25 02:29:12 2014
@@ -39,52 +39,28 @@ import com.google.common.collect.Immutab
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.namepath.PathMapper;
+import org.apache.jackrabbit.oak.core.ImmutableTree;
 import org.apache.jackrabbit.oak.plugins.observation.EventIterable.IterableListener;
-import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 /**
  * TODO JcrListener...
  */
 class JcrListener implements IterableListener<Event> {
-    private final Tree beforeTree;
-    private final Tree afterTree;
-    private final List<Event> events = newArrayList();
-    private final PathMapper namePathMapper;
-    private final String userId;
-    private final long timestamp;
-    private final String message;
-    private final boolean external;
 
-    JcrListener(Tree beforeTree, Tree afterTree, PathMapper namePathMapper, CommitInfo info)
{
-        this.beforeTree = beforeTree;
-        this.afterTree = afterTree;
-        this.namePathMapper = namePathMapper;
-        if (info != null) {
-            this.userId = info.getUserId();
-            this.message = info.getMessage();
-            this.timestamp = info.getDate();
-            this.external = false;
-        } else {
-            this.userId = CommitInfo.OAK_UNKNOWN;
-            this.message = null;
-            // we can't tell exactly when external changes were committed,
-            // so we just use a rough estimate like this
-            this.timestamp = System.currentTimeMillis();
-            this.external = true;
-        }
-    }
+    private final EventContext context;
 
-    private JcrListener(Tree beforeTree, Tree afterTree, PathMapper namePathMapper, String
userId,
-            long timestamp, String message, boolean external) {
+    private final ImmutableTree beforeTree;
+    private final ImmutableTree afterTree;
+
+    private final List<Event> events = newArrayList();
+
+    JcrListener(
+            EventContext context,
+            ImmutableTree beforeTree, ImmutableTree afterTree) {
+        this.context = context;
         this.beforeTree = beforeTree;
         this.afterTree = afterTree;
-        this.namePathMapper = namePathMapper;
-        this.userId = userId;
-        this.timestamp = timestamp;
-        this.message = message;
-        this.external = external;
     }
 
     @Override
@@ -122,14 +98,15 @@ class JcrListener implements IterableLis
         String destPath = PathUtils.concat(afterTree.getPath(), name);
         events.add(createEvent(NODE_MOVED, afterTree.getChild(name),
                 ImmutableMap.of(
-                        "srcAbsPath", namePathMapper.getJcrPath(sourcePath),
-                        "destAbsPath", namePathMapper.getJcrPath(destPath))));
+                        "srcAbsPath", context.getJcrPath(sourcePath),
+                        "destAbsPath", context.getJcrPath(destPath))));
     }
 
     @Override
     public JcrListener create(String name, NodeState before, NodeState after) {
-        return new JcrListener(beforeTree.getChild(name), afterTree.getChild(name), namePathMapper,
-                userId, timestamp, message, external);
+        return new JcrListener(
+                context,
+                new ImmutableTree(beforeTree, name, before), afterTree.getChild(name));
     }
 
     @Override
@@ -156,30 +133,24 @@ class JcrListener implements IterableLis
                     beforeNames.set(a, beforeName);
                     events.add(createEvent(NODE_MOVED, afterTree.getChild(name).getChild(afterName),
                             ImmutableMap.of(
-                                    "srcChildRelPath", beforeNames.get(a),
-                                    "destChildRelPath", beforeNames.get(a + 1))));
+                                    "srcChildRelPath", context.getJcrName(beforeNames.get(a)),
+                                    "destChildRelPath", context.getJcrName(beforeNames.get(a
+ 1)))));
                 }
             }
         }
     }
 
     private Event createEvent(int eventType, Tree tree) {
-        return createEvent(eventType, tree.getPath(), getIdentifier(tree), emptyMap());
+        return new EventImpl(context, eventType, tree.getPath(), getIdentifier(tree), emptyMap());
     }
 
     private Event createEvent(int eventType, Tree tree, Map<?, ?> info) {
-        return createEvent(eventType, tree.getPath(), getIdentifier(tree), info);
+        return new EventImpl(context, eventType, tree.getPath(), getIdentifier(tree), info);
     }
 
     private Event createEvent(int eventType, Tree parent, PropertyState property) {
         String path = PathUtils.concat(parent.getPath(), property.getName());
-        return createEvent(eventType, path, getIdentifier(parent), emptyMap());
-    }
-
-    private Event createEvent(int eventType, String path, String id, Map<?, ?> info)
{
-        return new EventImpl(
-                eventType, namePathMapper.getJcrPath(path), userId, id,
-                info, timestamp, message, external);
+        return new EventImpl(context, eventType, path, getIdentifier(parent), emptyMap());
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java?rev=1561246&r1=1561245&r2=1561246&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/CommitInfo.java
Sat Jan 25 02:29:12 2014
@@ -25,10 +25,12 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import com.google.common.base.Objects;
+
 /**
  * Commit info instances associate some meta data with a commit.
  */
-public class CommitInfo {
+public final class CommitInfo {
 
     public static final String OAK_UNKNOWN = "oak:unknown";
 
@@ -84,6 +86,28 @@ public class CommitInfo {
         return date;
     }
 
+    //------------------------------------------------------------< Object >--
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        } else if (object instanceof CommitInfo) {
+            CommitInfo that = (CommitInfo) object;
+            return sessionId.equals(that.sessionId)
+                    && userId.equals(that.userId)
+                    && Objects.equal(this.message, that.message)
+                    && this.date == that.date;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(sessionId, userId, message, date);
+    }
+
     @Override
     public String toString() {
         return toStringHelper(this)
@@ -93,4 +117,5 @@ public class CommitInfo {
                 .add("date", date)
                 .toString();
     }
+
 }



Mime
View raw message