You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@curator.apache.org by ra...@apache.org on 2017/01/26 17:49:13 UTC

[05/40] curator git commit: CURATOR-374: Replace AtomicReferences by AtomicFieldUpdaters to save allocations

CURATOR-374: Replace AtomicReferences by AtomicFieldUpdaters to save allocations


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/2ae72d67
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/2ae72d67
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/2ae72d67

Branch: refs/heads/persistent-watch
Commit: 2ae72d67a499c92a6ca0bea795d28b13b54d8b0c
Parents: 125dc96
Author: Sylvain Wallez <sy...@apache.org>
Authored: Wed Jan 4 11:47:32 2017 +0100
Committer: Sylvain Wallez <sy...@apache.org>
Committed: Wed Jan 4 19:37:27 2017 +0100

----------------------------------------------------------------------
 .../framework/recipes/cache/TreeCache.java      | 67 ++++++++++++--------
 1 file changed, 39 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/2ae72d67/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java
----------------------------------------------------------------------
diff --git a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java
index 906d23d..3ffb58f 100644
--- a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java
+++ b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/cache/TreeCache.java
@@ -54,6 +54,7 @@ import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.curator.utils.PathUtils.validatePath;
@@ -199,13 +200,23 @@ public class TreeCache implements Closeable
         PENDING, LIVE, DEAD
     }
 
+    private static final AtomicReferenceFieldUpdater<TreeNode, NodeState> nodeStateUpdater =
+            AtomicReferenceFieldUpdater.newUpdater(TreeNode.class, NodeState.class, "nodeState");
+
+    private static final AtomicReferenceFieldUpdater<TreeNode, ChildData> childDataUpdater =
+            AtomicReferenceFieldUpdater.newUpdater(TreeNode.class, ChildData.class, "childData");
+
+    private static final AtomicReferenceFieldUpdater<TreeNode, ConcurrentMap> childrenUpdater =
+            AtomicReferenceFieldUpdater.newUpdater(TreeNode.class, ConcurrentMap.class, "children");
+
     private final class TreeNode implements Watcher, BackgroundCallback
     {
-        final AtomicReference<NodeState> nodeState = new AtomicReference<NodeState>(NodeState.PENDING);
+
+        volatile NodeState nodeState = NodeState.PENDING;
+        volatile ChildData childData;
         final TreeNode parent;
         final String path;
-        final AtomicReference<ChildData> childData = new AtomicReference<ChildData>();
-        final AtomicReference<ConcurrentMap<String, TreeNode>> children = new AtomicReference<ConcurrentMap<String, TreeNode>>();
+        volatile ConcurrentMap<String, TreeNode> children;
         final int depth;
 
         TreeNode(String path, TreeNode parent)
@@ -262,7 +273,7 @@ public class TreeCache implements Closeable
         void wasReconnected() throws Exception
         {
             refresh();
-            ConcurrentMap<String, TreeNode> childMap = children.get();
+            ConcurrentMap<String, TreeNode> childMap = children;
             if ( childMap != null )
             {
                 for ( TreeNode child : childMap.values() )
@@ -279,9 +290,9 @@ public class TreeCache implements Closeable
 
         void wasDeleted() throws Exception
         {
-            ChildData oldChildData = childData.getAndSet(null);
+            ChildData oldChildData = childDataUpdater.getAndSet(this, null);
             client.clearWatcherReferences(this);
-            ConcurrentMap<String, TreeNode> childMap = children.getAndSet(null);
+            ConcurrentMap<String, TreeNode> childMap = childrenUpdater.getAndSet(this,null);
             if ( childMap != null )
             {
                 ArrayList<TreeNode> childCopy = new ArrayList<TreeNode>(childMap.values());
@@ -297,7 +308,7 @@ public class TreeCache implements Closeable
                 return;
             }
 
-            NodeState oldState = nodeState.getAndSet(NodeState.DEAD);
+            NodeState oldState = nodeStateUpdater.getAndSet(this, NodeState.DEAD);
             if ( oldState == NodeState.LIVE )
             {
                 publishEvent(TreeCacheEvent.Type.NODE_REMOVED, oldChildData);
@@ -311,7 +322,7 @@ public class TreeCache implements Closeable
             else
             {
                 // Remove from parent if we're currently a child
-                ConcurrentMap<String, TreeNode> parentChildMap = parent.children.get();
+                ConcurrentMap<String, TreeNode> parentChildMap = parent.children;
                 if ( parentChildMap != null )
                 {
                     parentChildMap.remove(ZKPaths.getNodeFromPath(path), this);
@@ -360,19 +371,19 @@ public class TreeCache implements Closeable
                 Preconditions.checkState(parent == null, "unexpected EXISTS on non-root node");
                 if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
                 {
-                    nodeState.compareAndSet(NodeState.DEAD, NodeState.PENDING);
+                    nodeStateUpdater.compareAndSet(this, NodeState.DEAD, NodeState.PENDING);
                     wasCreated();
                 }
                 break;
             case CHILDREN:
                 if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
                 {
-                    ChildData oldChildData = childData.get();
+                    ChildData oldChildData = childData;
                     if ( oldChildData != null && oldChildData.getStat().getMzxid() == newStat.getMzxid() )
                     {
                         // Only update stat if mzxid is same, otherwise we might obscure
                         // GET_DATA event updates.
-                        childData.compareAndSet(oldChildData, new ChildData(oldChildData.getPath(), newStat, oldChildData.getData()));
+                        childDataUpdater.compareAndSet(this, oldChildData, new ChildData(oldChildData.getPath(), newStat, oldChildData.getData()));
                     }
 
                     if ( event.getChildren().isEmpty() )
@@ -380,13 +391,13 @@ public class TreeCache implements Closeable
                         break;
                     }
 
-                    ConcurrentMap<String, TreeNode> childMap = children.get();
+                    ConcurrentMap<String, TreeNode> childMap = children;
                     if ( childMap == null )
                     {
                         childMap = Maps.newConcurrentMap();
-                        if ( !children.compareAndSet(null, childMap) )
+                        if ( !childrenUpdater.compareAndSet(this, null, childMap) )
                         {
-                            childMap = children.get();
+                            childMap = children;
                         }
                     }
 
@@ -423,23 +434,23 @@ public class TreeCache implements Closeable
                     ChildData oldChildData;
                     if ( cacheData )
                     {
-                        oldChildData = childData.getAndSet(toPublish);
+                        oldChildData = childDataUpdater.getAndSet(this, toPublish);
                     }
                     else
                     {
-                        oldChildData = childData.getAndSet(new ChildData(event.getPath(), newStat, null));
+                        oldChildData = childDataUpdater.getAndSet(this, new ChildData(event.getPath(), newStat, null));
                     }
 
                     boolean added;
                     if (parent == null) {
                         // We're the singleton root.
-                        added = nodeState.getAndSet(NodeState.LIVE) != NodeState.LIVE;
+                        added = nodeStateUpdater.getAndSet(this, NodeState.LIVE) != NodeState.LIVE;
                     } else {
-                        added = nodeState.compareAndSet(NodeState.PENDING, NodeState.LIVE);
+                        added = nodeStateUpdater.compareAndSet(this, NodeState.PENDING, NodeState.LIVE);
                         if (!added) {
                             // Ordinary nodes are not allowed to transition from dead -> live;
                             // make sure this isn't a delayed response that came in after death.
-                            if (nodeState.get() != NodeState.LIVE) {
+                            if (nodeState != NodeState.LIVE) {
                                 return;
                             }
                         }
@@ -643,7 +654,7 @@ public class TreeCache implements Closeable
         TreeNode current = root;
         while (!findElements.isEmpty()) {
             String nextFind = findElements.removeFirst();
-            ConcurrentMap<String, TreeNode> map = current.children.get();
+            ConcurrentMap<String, TreeNode> map = current.children;
             if ( map == null )
             {
                 return null;
@@ -668,11 +679,11 @@ public class TreeCache implements Closeable
     public Map<String, ChildData> getCurrentChildren(String fullPath)
     {
         TreeNode node = find(fullPath);
-        if ( node == null || node.nodeState.get() != NodeState.LIVE )
+        if ( node == null || node.nodeState != NodeState.LIVE )
         {
             return null;
         }
-        ConcurrentMap<String, TreeNode> map = node.children.get();
+        ConcurrentMap<String, TreeNode> map = node.children;
         Map<String, ChildData> result;
         if ( map == null )
         {
@@ -684,9 +695,9 @@ public class TreeCache implements Closeable
             for ( Map.Entry<String, TreeNode> entry : map.entrySet() )
             {
                 TreeNode childNode = entry.getValue();
-                ChildData childData = childNode.childData.get();
+                ChildData childData = childNode.childData;
                 // Double-check liveness after retreiving data.
-                if ( childData != null && childNode.nodeState.get() == NodeState.LIVE )
+                if ( childData != null && childNode.nodeState == NodeState.LIVE )
                 {
                     builder.put(entry.getKey(), childData);
                 }
@@ -695,7 +706,7 @@ public class TreeCache implements Closeable
         }
 
         // Double-check liveness after retreiving children.
-        return node.nodeState.get() == NodeState.LIVE ? result : null;
+        return node.nodeState == NodeState.LIVE ? result : null;
     }
 
     /**
@@ -709,13 +720,13 @@ public class TreeCache implements Closeable
     public ChildData getCurrentData(String fullPath)
     {
         TreeNode node = find(fullPath);
-        if ( node == null || node.nodeState.get() != NodeState.LIVE )
+        if ( node == null || node.nodeState != NodeState.LIVE )
         {
             return null;
         }
-        ChildData result = node.childData.get();
+        ChildData result = node.childData;
         // Double-check liveness after retreiving data.
-        return node.nodeState.get() == NodeState.LIVE ? result : null;
+        return node.nodeState == NodeState.LIVE ? result : null;
     }
 
     private void callListeners(final TreeCacheEvent event)