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);
