Browse Source
Optimize batch state checker model lookup from O(N²) to O(N)
Replace linear scans with Dictionary/HashSet lookups in both
RequirePermissionsSimpleBatchStateChecker and
RequireFeaturesSimpleBatchStateChecker for consistency.
pull/25276/head
maliming
6 months ago
No known key found for this signature in database
GPG Key ID: A646B9CB645ECEA4
2 changed files with
47 additions and
11 deletions
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RequirePermissionsSimpleBatchStateChecker.cs
framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesSimpleBatchStateChecker.cs
@ -47,13 +47,33 @@ public class RequirePermissionsSimpleBatchStateChecker<TState> : SimpleBatchStat
var result = new SimpleStateCheckerResult < TState > ( context . States ) ;
var permissions = _ models . Where ( x = > context . States . Any ( s = > s . Equals ( x . State ) ) ) . SelectMany ( x = > x . Permissions ) . Distinct ( ) . ToArray ( ) ;
var grantResult = await permissionChecker . IsGrantedAsync ( permissions ) ;
var stateSet = new HashSet < TState > ( context . States ) ;
var modelLookup = new Dictionary < TState , RequirePermissionsSimpleBatchStateCheckerModel < TState > > ( ) ;
var allPermissions = new HashSet < string > ( ) ;
foreach ( var model in _ models )
{
if ( ! stateSet . Contains ( model . State ) )
{
continue ;
}
if ( ! modelLookup . ContainsKey ( model . State ) )
{
modelLookup [ model . State ] = model ;
}
foreach ( var permission in model . Permissions )
{
allPermissions . Add ( permission ) ;
}
}
var grantResult = await permissionChecker . IsGrantedAsync ( allPermissions . ToArray ( ) ) ;
foreach ( var state in context . States )
{
var model = _ models . FirstOrDefault ( x = > x . State . Equals ( state ) ) ;
if ( model ! = null )
if ( modelLookup . TryGetValue ( state , out var model ) )
{
if ( model . RequiresAll )
{
@ -49,17 +49,33 @@ public class RequireFeaturesSimpleBatchStateChecker<TState> : SimpleBatchStateCh
var result = new SimpleStateCheckerResult < TState > ( context . States ) ;
var relevantModels = _ models
. Where ( x = > context . States . Any ( s = > s . Equals ( x . State ) ) )
. ToList ( ) ;
var stateSet = new HashSet < TState > ( context . States ) ;
var modelLookup = new Dictionary < TState , RequireFeaturesSimpleBatchStateCheckerModel < TState > > ( ) ;
var allFeatures = new HashSet < string > ( ) ;
var features = relevantModels . SelectMany ( x = > x . FeatureNames ) . Distinct ( ) . ToArray ( ) ;
var featureValues = await featureChecker . IsEnabledAsync ( features ) ;
foreach ( var model in _ models )
{
if ( ! stateSet . Contains ( model . State ) )
{
continue ;
}
if ( ! modelLookup . ContainsKey ( model . State ) )
{
modelLookup [ model . State ] = model ;
}
foreach ( var featureName in model . FeatureNames )
{
allFeatures . Add ( featureName ) ;
}
}
var featureValues = await featureChecker . IsEnabledAsync ( allFeatures . ToArray ( ) ) ;
foreach ( var state in context . States )
{
var model = relevantModels . FirstOrDefault ( x = > x . State . Equals ( state ) ) ;
if ( model ! = null )
if ( modelLookup . TryGetValue ( state , out var model ) )
{
if ( model . RequiresAll )
{