jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1363804 - /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
Date Fri, 20 Jul 2012 14:35:45 GMT
Author: jukka
Date: Fri Jul 20 14:35:44 2012
New Revision: 1363804

URL: http://svn.apache.org/viewvc?rev=1363804&view=rev
Log:
OAK-175: MemoryNodeStateBuilder inefficient for large child node lists

Reduce the amount of in-memory copying done by MNSB.getNodeState() by introducing an explicit
"frozen" state for the modified properties map.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java?rev=1363804&r1=1363803&r2=1363804&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStateBuilder.java
Fri Jul 20 14:35:44 2012
@@ -36,7 +36,7 @@ public class MemoryNodeStateBuilder impl
     /**
      * Set of added, modified or removed ({@code null} value) property states.
      */
-    private final Map<String, PropertyState> properties =
+    private Map<String, PropertyState> properties =
             new HashMap<String, PropertyState>();
 
     /**
@@ -46,17 +46,40 @@ public class MemoryNodeStateBuilder impl
     private final Map<String, NodeStateBuilder> builders =
             new HashMap<String, NodeStateBuilder>();
 
+    /**
+     * Flag to indicate that the current {@link #properties} map is being
+     * referenced by a {@link ModifiedNodeState} instance returned by a
+     * previous {@link #getNodeState()} call, and thus should not be
+     * modified unless first explicitly {@link #unfreeze() unfrozen}.
+     */
+    private boolean frozen = false;
+
     public MemoryNodeStateBuilder(NodeState base) {
         assert base != null;
         this.base = base;
     }
 
+    /**
+     * Ensures that the current {@link #properties} map is not {@link #frozen}.
+     */
+    private void unfreeze() {
+        if (frozen) {
+            properties = new HashMap<String, PropertyState>(properties);
+            frozen = false;
+        }
+    }
+
     @Override
     public NodeState getNodeState() {
-        if (properties.isEmpty() && builders.isEmpty()) {
-            return base; // shortcut
-        } else {
-            Map<String, NodeState> nodes = new HashMap<String, NodeState>();
+        Map<String, PropertyState> props = Collections.emptyMap();
+        if (!properties.isEmpty()) {
+            frozen = true;
+            props = properties;
+        }
+
+        Map<String, NodeState> nodes = Collections.emptyMap();
+        if (!builders.isEmpty()) {
+            nodes = new HashMap<String, NodeState>(builders.size() * 2);
             for (Map.Entry<String, NodeStateBuilder> entry
                     : builders.entrySet()) {
                 NodeStateBuilder builder = entry.getValue();
@@ -66,25 +89,12 @@ public class MemoryNodeStateBuilder impl
                     nodes.put(entry.getKey(), null);
                 }
             }
-            return new ModifiedNodeState(
-                    base, snapshot(properties), snapshot(nodes));
         }
-    }
 
-    /**
-     * Returns an optimized snapshot of the current state of the given map.
-     *
-     * @param map mutable map
-     * @return optimized snapshot
-     */
-    private static <T> Map<String, T> snapshot(Map<String, T> map) {
-        if (map.isEmpty()) {
-            return Collections.emptyMap();
-        } else if (map.size() == 1) {
-            Map.Entry<String, T> entry = map.entrySet().iterator().next();
-            return Collections.singletonMap(entry.getKey(), entry.getValue());
+        if (props.isEmpty() && nodes.isEmpty()) {
+            return base;
         } else {
-            return new HashMap<String, T>(map);
+            return new ModifiedNodeState(base, props, nodes);
         }
     }
 
@@ -112,11 +122,13 @@ public class MemoryNodeStateBuilder impl
 
     @Override
     public void setProperty(String name, CoreValue value) {
+        unfreeze();
         properties.put(name, new SinglePropertyState(name, value));
     }
 
     @Override
     public void setProperty(String name, List<CoreValue> values) {
+        unfreeze();
         if (values.isEmpty()) {
             properties.put(name, new EmptyPropertyState(name));
         } else {
@@ -126,6 +138,7 @@ public class MemoryNodeStateBuilder impl
 
     @Override
     public void removeProperty(String name) {
+        unfreeze();
         if (base.getProperty(name) != null) {
             properties.put(name, null);
         } else {



Mime
View raw message