@@ -2001,6 +2001,118 @@ func BenchmarkIterateHierarchyV2FromClusterScoped_25Percent_WithScan(b *testing.
20012001 }
20022002}
20032003
2004+ // BenchmarkIterateHierarchyV2_NamespaceScaling tests how namespace scanning scales with namespace size
2005+ func BenchmarkIterateHierarchyV2_NamespaceScaling (b * testing.B ) {
2006+ testCases := []struct {
2007+ name string
2008+ namespaceResourceCount int
2009+ crossNamespacePercent float64
2010+ }{
2011+ {"100_Resources_10pct" , 100 , 0.10 },
2012+ {"1000_Resources_10pct" , 1000 , 0.10 },
2013+ {"5000_Resources_10pct" , 5000 , 0.10 },
2014+ {"10000_Resources_10pct" , 10000 , 0.10 },
2015+ {"20000_Resources_10pct" , 20000 , 0.10 },
2016+ // Also test with different cross-namespace percentages
2017+ {"5000_Resources_0pct" , 5000 , 0.00 },
2018+ {"5000_Resources_5pct" , 5000 , 0.05 },
2019+ {"5000_Resources_25pct" , 5000 , 0.25 },
2020+ {"5000_Resources_50pct" , 5000 , 0.50 },
2021+ }
2022+
2023+ for _ , tc := range testCases {
2024+ b .Run (tc .name , func (b * testing.B ) {
2025+ cluster := newCluster (b ).WithAPIResources ([]kube.APIResourceInfo {{
2026+ GroupKind : schema.GroupKind {Group : "rbac.authorization.k8s.io" , Kind : "ClusterRole" },
2027+ GroupVersionResource : schema.GroupVersionResource {Group : "rbac.authorization.k8s.io" , Version : "v1" , Resource : "clusterroles" },
2028+ Meta : metav1.APIResource {Namespaced : false },
2029+ }})
2030+
2031+ // Calculate resource distribution
2032+ clusterParents := 100 // Fixed number of cluster-scoped resources
2033+ crossNamespacePods := int (float64 (tc .namespaceResourceCount ) * tc .crossNamespacePercent )
2034+ regularPods := tc .namespaceResourceCount - crossNamespacePods
2035+
2036+ testResources := buildParameterizedCrossNamespaceTestResourceMapWithUIDs (
2037+ clusterParents ,
2038+ regularPods ,
2039+ crossNamespacePods ,
2040+ )
2041+
2042+ for _ , resource := range testResources {
2043+ cluster .setNode (resource )
2044+ }
2045+
2046+ // Start from a cluster-scoped resource
2047+ startKey := kube.ResourceKey {
2048+ Group : "rbac.authorization.k8s.io" ,
2049+ Kind : "ClusterRole" ,
2050+ Namespace : "" ,
2051+ Name : "cluster-role-0" ,
2052+ }
2053+
2054+ b .ResetTimer ()
2055+ for n := 0 ; n < b .N ; n ++ {
2056+ // Test scanning the "default" namespace which has the most resources
2057+ cluster .IterateHierarchyV2 ([]kube.ResourceKey {startKey }, func (_ * Resource , _ map [kube.ResourceKey ]* Resource ) bool {
2058+ return true
2059+ }, "default" )
2060+ }
2061+ })
2062+ }
2063+ }
2064+
2065+ // BenchmarkIterateHierarchyV2_NamespaceScaling_NoScan provides baseline for comparison
2066+ func BenchmarkIterateHierarchyV2_NamespaceScaling_NoScan (b * testing.B ) {
2067+ testCases := []struct {
2068+ name string
2069+ namespaceResourceCount int
2070+ }{
2071+ {"100_Resources" , 100 },
2072+ {"1000_Resources" , 1000 },
2073+ {"5000_Resources" , 5000 },
2074+ {"10000_Resources" , 10000 },
2075+ {"20000_Resources" , 20000 },
2076+ }
2077+
2078+ for _ , tc := range testCases {
2079+ b .Run (tc .name , func (b * testing.B ) {
2080+ cluster := newCluster (b ).WithAPIResources ([]kube.APIResourceInfo {{
2081+ GroupKind : schema.GroupKind {Group : "rbac.authorization.k8s.io" , Kind : "ClusterRole" },
2082+ GroupVersionResource : schema.GroupVersionResource {Group : "rbac.authorization.k8s.io" , Version : "v1" , Resource : "clusterroles" },
2083+ Meta : metav1.APIResource {Namespaced : false },
2084+ }})
2085+
2086+ // All resources have cluster-scoped parents but we won't scan for them
2087+ testResources := buildParameterizedCrossNamespaceTestResourceMapWithUIDs (
2088+ 100 ,
2089+ 0 ,
2090+ tc .namespaceResourceCount ,
2091+ )
2092+
2093+ for _ , resource := range testResources {
2094+ cluster .setNode (resource )
2095+ }
2096+
2097+ // Start from a cluster-scoped resource
2098+ startKey := kube.ResourceKey {
2099+ Group : "rbac.authorization.k8s.io" ,
2100+ Kind : "ClusterRole" ,
2101+ Namespace : "" ,
2102+ Name : "cluster-role-0" ,
2103+ }
2104+
2105+ b .ResetTimer ()
2106+ for n := 0 ; n < b .N ; n ++ {
2107+ // No namespace scanning - just traverse cluster-scoped children
2108+ cluster .IterateHierarchyV2 ([]kube.ResourceKey {startKey }, func (_ * Resource , _ map [kube.ResourceKey ]* Resource ) bool {
2109+ return true
2110+ }, "" )
2111+ }
2112+ })
2113+ }
2114+ }
2115+
20042116func TestIterateHierarchyV2_NoDuplicatesInSameNamespace (t * testing.T ) {
20052117 // Create a parent-child relationship in the same namespace
20062118 parent := & appsv1.Deployment {
0 commit comments