This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch wicket-8.x
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/wicket-8.x by this push:
     new b127a01  WICKET-6839 Use request flag for caching 
`isVisibleInHierarchy`
b127a01 is described below

commit b127a01582cc4097e40941ca6d57989f614466d1
Author: Thomas Heigl <[email protected]>
AuthorDate: Fri Oct 23 11:31:10 2020 +0200

    WICKET-6839 Use request flag for caching `isVisibleInHierarchy`
    
    (cherry picked from commit 931c873e84ebefc1cbb96b5b62e94fce3de6fc0b)
---
 .../src/main/java/org/apache/wicket/Component.java | 48 +++++++++++-----
 .../java/org/apache/wicket/MarkupContainer.java    |  8 ++-
 .../test/java/org/apache/wicket/ComponentTest.java | 64 +++++++++++++++++++++-
 3 files changed, 102 insertions(+), 18 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java 
b/wicket-core/src/main/java/org/apache/wicket/Component.java
index a3bf34f..05f30dd 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -420,26 +420,34 @@ public abstract class Component
        private int flags = FLAG_VISIBLE | FLAG_ESCAPE_MODEL_STRINGS | 
FLAG_VERSIONED | FLAG_ENABLED |
                FLAG_IS_RENDER_ALLOWED | FLAG_VISIBILITY_ALLOWED | 
FLAG_RESERVED5 /* page's stateless hint */;
 
-       private static final short RFLAG_ENABLED_IN_HIERARCHY_VALUE = 0x1;
-       private static final short RFLAG_ENABLED_IN_HIERARCHY_SET = 0x2;
-       private static final short RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED = 0x4;
-       private static final short RFLAG_VISIBLE_IN_HIERARCHY_SET = 0x8;
+       // @formatter:off       
+       private static final short RFLAG_ENABLED_IN_HIERARCHY_VALUE        = 
0x1;
+       private static final short RFLAG_ENABLED_IN_HIERARCHY_SET          = 
0x2;
+       private static final short RFLAG_VISIBLE_IN_HIERARCHY_VALUE        = 
0x4;
+       private static final short RFLAG_VISIBLE_IN_HIERARCHY_SET          = 
0x8;
        /** onconfigure has been called */
-       private static final short RFLAG_CONFIGURED = 0x10;
+       private static final short RFLAG_CONFIGURED                        = 
0x10;
        private static final short RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED = 
0x20;
-       private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED = 0x40;
-       protected static final short RFLAG_CONTAINER_DEQUEING = 0x80;
-       private static final short RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED = 0x100;
+       private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED    = 
0x40;
+       protected static final short RFLAG_CONTAINER_DEQUEING              = 
0x80;
+       private static final short RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED     = 
0x100;
        /**
         * Flag that makes we are in before-render callback phase Set after 
component.onBeforeRender is
         * invoked (right before invoking beforeRender on children)
         */
-       private static final short RFLAG_RENDERING = 0x200;
-       private static final short RFLAG_PREPARED_FOR_RENDER = 0x400;
-       private static final short RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED = 
0x800;
-       private static final short RFLAG_DETACHING = 0x1000;    
+       private static final short RFLAG_RENDERING                         = 
0x200;
+       private static final short RFLAG_PREPARED_FOR_RENDER               = 
0x400;
+       private static final short RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED  = 
0x800;
+       private static final short RFLAG_DETACHING                         = 
0x1000;
        /** True when a component is being removed from the hierarchy */
-       private static final short RFLAG_REMOVING_FROM_HIERARCHY = 0x2000;
+       private static final short RFLAG_REMOVING_FROM_HIERARCHY           = 
0x2000;
+       /**
+        * This flag tracks if removals have been set on this component. 
Clearing this key is an
+        * expensive operation. With this flag this expensive call can be 
avoided.
+        */
+       protected static final short RFLAG_CONTAINER_HAS_REMOVALS          = 
0x4000;
+       private static final short RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED  = 
(short) 0x8000;
+       // @formatter:on
 
        /**
         * Flags that only keep their value during the request. Useful for 
cache markers, etc. At the
@@ -2095,15 +2103,25 @@ public abstract class Component
         */
        public final boolean isVisibleInHierarchy()
        {
+               if (getRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_SET))
+               {
+                       return getRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_VALUE);
+               }
+
+               final boolean state;
                Component parent = getParent();
                if (parent != null && !parent.isVisibleInHierarchy())
                {
-                       return false;
+                       state = false;
                }
                else
                {
-                       return determineVisibility();
+                       state = determineVisibility();
                }
+
+               setRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_SET, true);
+               setRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_VALUE, state);
+               return state;
        }
 
        /**
diff --git a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java 
b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
index 8dbb089..e3f72e0 100644
--- a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
@@ -1322,7 +1322,7 @@ public abstract class MarkupContainer extends Component 
implements Iterable<Comp
         */
        private LinkedList<RemovedChild> removals_get()
        {
-               return getMetaData(REMOVALS_KEY);
+               return getRequestFlag(RFLAG_CONTAINER_HAS_REMOVALS) ? 
getMetaData(REMOVALS_KEY) : null;
        }
 
        /**
@@ -1334,6 +1334,7 @@ public abstract class MarkupContainer extends Component 
implements Iterable<Comp
         */
        private void removals_set(LinkedList<RemovedChild> removals)
        {
+               setRequestFlag(RFLAG_CONTAINER_HAS_REMOVALS, removals != null);
                setMetaData(REMOVALS_KEY, removals);
        }
 
@@ -1342,7 +1343,10 @@ public abstract class MarkupContainer extends Component 
implements Iterable<Comp
         */
        private void removals_clear()
        {
-               setMetaData(REMOVALS_KEY, null);
+               if (getRequestFlag(RFLAG_CONTAINER_HAS_REMOVALS))
+               {
+                       removals_set(null);
+               }
        }
 
        /**
diff --git a/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java 
b/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
index d3c0dc2..587cb21 100644
--- a/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/ComponentTest.java
@@ -243,6 +243,38 @@ public class ComponentTest extends WicketTestCase
                assertTrue(component.getFlagReserved5());
        }
 
+       @Test
+       public void isEnabledInHierarchyCachesResult()
+       {
+               final SpyComponent c = new SpyComponent("test");
+
+               c.isEnabledInHierarchy();
+               c.isEnabledInHierarchy();
+               assertEquals(1, c.isEnabledCallCount);
+
+               c.setEnabled(false);
+
+               c.isEnabledInHierarchy();
+               c.isEnabledInHierarchy();
+               assertEquals(2, c.isEnabledCallCount);
+       }
+
+       @Test
+       public void isVisibleInHierarchyCachesResult()
+       {
+               final SpyComponent c = new SpyComponent("test");
+               
+               c.isVisibleInHierarchy();
+               c.isVisibleInHierarchy();
+               assertEquals(1, c.isVisibleCallCount);
+               
+               c.setVisible(false);
+               
+               c.isVisibleInHierarchy();
+               c.isVisibleInHierarchy();
+               assertEquals(2, c.isVisibleCallCount);
+       }
+
        /**
         * Component#FLAG_RESERVED5 (Page's STATELESS_HINT) must be initially 
set to true
         */
@@ -262,4 +294,34 @@ public class ComponentTest extends WicketTestCase
                protected void onRender() {
                }
        }
-}
\ No newline at end of file
+
+       private static class SpyComponent extends Component
+       {
+
+               int isEnabledCallCount;
+               int isVisibleCallCount;
+
+               public SpyComponent(final String id)
+               {
+                       super(id);
+               }
+
+               @Override
+               public boolean isEnabled()
+               {
+                       isEnabledCallCount++;
+                       return super.isEnabled();
+               }
+
+               @Override
+               public boolean isVisible()
+               {
+                       isVisibleCallCount++;
+                       return super.isVisible();
+               }
+
+               @Override
+               protected void onRender() {
+               }
+       }
+}

Reply via email to