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

reschke pushed a commit to branch OAK-11731
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit ce261e917bd714b391ad3771e96b84d1e65d168b
Author: Julian Reschke <[email protected]>
AuthorDate: Wed Nov 26 16:04:24 2025 +0100

    OAK-11731: expose NodeCounter (getEstimatedChildNodeCounts) in 
JackrabbitNode (wip)
---
 .../src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java  | 4 ++++
 .../src/main/java/org/apache/jackrabbit/api/package-info.java    | 2 +-
 .../java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java     | 5 +++++
 .../org/apache/jackrabbit/oak/jcr/session/SessionContext.java    | 9 +++++++++
 .../java/org/apache/jackrabbit/oak/jcr/JackrabbitNodeTest.java   | 8 +++++++-
 5 files changed, 26 insertions(+), 2 deletions(-)

diff --git 
a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
 
b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
index c5669fb102..afc2d0d19a 100644
--- 
a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
+++ 
b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
@@ -103,4 +103,8 @@ public interface JackrabbitNode extends Node {
             return null;
         }
     }
+
+    default long getEstimatedChildNodes() throws RepositoryException {
+        return -1;
+    }
 }
diff --git 
a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java 
b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java
index 0994258e1b..811b8cf240 100644
--- 
a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java
+++ 
b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/package-info.java
@@ -18,6 +18,6 @@
 /**
  * Jackrabbit extensions for JCR core interfaces
  */
[email protected]("2.11.0")
[email protected]("2.12.0")
 package org.apache.jackrabbit.api;
 
diff --git 
a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java 
b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java
index 73c7a39f10..72cace8b09 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java
@@ -1695,6 +1695,11 @@ public class NodeImpl<T extends NodeDelegate> extends 
ItemImpl<T> implements Jac
         });
     }
 
+    @Override
+    public long getEstimatedChildNodes() throws RepositoryException {
+        return 
sessionContext.getNodeCounterMBean().getEstimatedNodeCount(dlg.getPath());
+    }
+
     /**
      * Provide current node path. Should be invoked from within
      * the SessionDelegate#perform and preferred instead of getPath
diff --git 
a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java
 
b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java
index ebc3781783..4ecbbe0f8c 100644
--- 
a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java
+++ 
b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java
@@ -53,6 +53,7 @@ import org.apache.jackrabbit.oak.jcr.security.AccessManager;
 import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.namepath.impl.NamePathMapperImpl;
+import org.apache.jackrabbit.oak.plugins.index.counter.jmx.NodeCounterMBean;
 import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
 import org.apache.jackrabbit.oak.plugins.observation.CommitRateLimiter;
 import org.apache.jackrabbit.oak.plugins.value.jcr.ValueFactoryImpl;
@@ -65,6 +66,7 @@ import 
org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
 import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
 import org.apache.jackrabbit.oak.stats.CounterStats;
 import org.apache.jackrabbit.oak.stats.MeterStats;
@@ -108,6 +110,7 @@ public class SessionContext implements NamePathMapper {
     private PrivilegeManager privilegeManager;
     private ObservationManagerImpl observationManager;
     private BlobAccessProvider blobAccessProvider;
+    private NodeCounterMBean nodeCounterMBean;
 
     /** Paths (tokens) of all open scoped locks held by this session. */
     private final Set<String> openScopedLocks = new TreeSet<>();
@@ -152,6 +155,7 @@ public class SessionContext implements NamePathMapper {
         this.valueFactory = new ValueFactoryImpl(
                 delegate.getRoot(), namePathMapper, this.blobAccessProvider);
         this.sessionQuerySettings = sessionQuerySettings;
+        this.nodeCounterMBean = WhiteboardUtils.getService(whiteboard, 
NodeCounterMBean.class);
     }
 
     public final Map<String, Object> getAttributes() {
@@ -333,6 +337,11 @@ public class SessionContext implements NamePathMapper {
         return mountInfoProvider;
     }
 
+    @Nullable
+    public NodeCounterMBean getNodeCounterMBean() {
+        return nodeCounterMBean;
+    }
+
     //-----------------------------------------------------< NamePathMapper 
>---
 
     @Override
diff --git 
a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/JackrabbitNodeTest.java 
b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/JackrabbitNodeTest.java
index 6510a3daf8..5dc1ba252d 100644
--- 
a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/JackrabbitNodeTest.java
+++ 
b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/JackrabbitNodeTest.java
@@ -323,7 +323,13 @@ public class JackrabbitNodeTest extends AbstractJCRTest {
         assertNotNull(jn.getNodeOrNull("a"));
         assertNotNull(jn.getNodeOrNull("a/aa"));
     }
-    
+
+    public void testEstimated() throws Exception {
+        // needs a proper test scenario
+        JackrabbitNode jn = (JackrabbitNode) testRootNode;
+        assertTrue(-2 < jn.getEstimatedChildNodes());
+    }
+
     public void testGetPropertyOrNull() throws Exception {
         JackrabbitNode jn = (JackrabbitNode) testRootNode;
         Node aa = jn.addNode("a/aa", NodeTypeConstants.NT_OAK_UNSTRUCTURED);

Reply via email to