Skip to content

Commit

Permalink
feat: improve GetNamedImplicitPermissionsForUser performance (#1405)
Browse files Browse the repository at this point in the history
  • Loading branch information
MuZhou233 committed Jun 8, 2024
1 parent a29d8a8 commit eec10eb
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions rbac_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,21 @@ func (e *Enforcer) GetNamedImplicitPermissionsForUser(ptype string, user string,
if rm == nil {
return nil, fmt.Errorf("role manager is not initialized")
}

roles, err := e.GetImplicitRolesForUser(user, domain...)
if err != nil {
return nil, err
}
policyRoles := make(map[string]struct{}, len(roles)+1)
policyRoles[user] = struct{}{}
for _, r := range roles {
policyRoles[r] = struct{}{}
}

domainIndex, err := e.GetFieldIndex(ptype, constant.DomainIndex)
for _, rule := range e.model["p"][ptype].Policy {
if len(domain) == 0 {
matched, _ := rm.HasLink(user, rule[0])
if matched {
if _, ok := policyRoles[rule[0]]; ok {
permission = append(permission, deepCopyPolicy(rule))
}
continue
Expand All @@ -337,8 +347,7 @@ func (e *Enforcer) GetNamedImplicitPermissionsForUser(ptype string, user string,
if !matched {
continue
}
matched, _ = rm.HasLink(user, rule[0], d)
if matched {
if _, ok := policyRoles[rule[0]]; ok {
newRule := deepCopyPolicy(rule)
newRule[domainIndex] = d
permission = append(permission, newRule)
Expand Down

1 comment on commit eec10eb

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: eec10eb Previous: a29d8a8 Ratio
BenchmarkCachedRaw 17.41 ns/op 0 B/op 0 allocs/op 17.41 ns/op 0 B/op 0 allocs/op 1
BenchmarkCachedRaw - ns/op 17.41 ns/op 17.41 ns/op 1
BenchmarkCachedRaw - B/op 0 B/op 0 B/op 1
BenchmarkCachedRaw - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkCachedBasicModel 171.5 ns/op 104 B/op 4 allocs/op 168.3 ns/op 104 B/op 4 allocs/op 1.02
BenchmarkCachedBasicModel - ns/op 171.5 ns/op 168.3 ns/op 1.02
BenchmarkCachedBasicModel - B/op 104 B/op 104 B/op 1
BenchmarkCachedBasicModel - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedRBACModel 170.3 ns/op 104 B/op 4 allocs/op 171.4 ns/op 104 B/op 4 allocs/op 0.99
BenchmarkCachedRBACModel - ns/op 170.3 ns/op 171.4 ns/op 0.99
BenchmarkCachedRBACModel - B/op 104 B/op 104 B/op 1
BenchmarkCachedRBACModel - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedRBACModelSmall 178.2 ns/op 104 B/op 4 allocs/op 176.4 ns/op 104 B/op 4 allocs/op 1.01
BenchmarkCachedRBACModelSmall - ns/op 178.2 ns/op 176.4 ns/op 1.01
BenchmarkCachedRBACModelSmall - B/op 104 B/op 104 B/op 1
BenchmarkCachedRBACModelSmall - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedRBACModelMedium 185.7 ns/op 104 B/op 4 allocs/op 182.9 ns/op 104 B/op 4 allocs/op 1.02
BenchmarkCachedRBACModelMedium - ns/op 185.7 ns/op 182.9 ns/op 1.02
BenchmarkCachedRBACModelMedium - B/op 104 B/op 104 B/op 1
BenchmarkCachedRBACModelMedium - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedRBACModelLarge 154.4 ns/op 96 B/op 3 allocs/op 159.2 ns/op 96 B/op 3 allocs/op 0.97
BenchmarkCachedRBACModelLarge - ns/op 154.4 ns/op 159.2 ns/op 0.97
BenchmarkCachedRBACModelLarge - B/op 96 B/op 96 B/op 1
BenchmarkCachedRBACModelLarge - allocs/op 3 allocs/op 3 allocs/op 1
BenchmarkCachedRBACModelWithResourceRoles 170.7 ns/op 104 B/op 4 allocs/op 175.6 ns/op 104 B/op 4 allocs/op 0.97
BenchmarkCachedRBACModelWithResourceRoles - ns/op 170.7 ns/op 175.6 ns/op 0.97
BenchmarkCachedRBACModelWithResourceRoles - B/op 104 B/op 104 B/op 1
BenchmarkCachedRBACModelWithResourceRoles - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedRBACModelWithDomains 182.6 ns/op 120 B/op 4 allocs/op 182.5 ns/op 120 B/op 4 allocs/op 1.00
BenchmarkCachedRBACModelWithDomains - ns/op 182.6 ns/op 182.5 ns/op 1.00
BenchmarkCachedRBACModelWithDomains - B/op 120 B/op 120 B/op 1
BenchmarkCachedRBACModelWithDomains - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedABACModel 2831 ns/op 1543 B/op 18 allocs/op 2906 ns/op 1546 B/op 18 allocs/op 0.97
BenchmarkCachedABACModel - ns/op 2831 ns/op 2906 ns/op 0.97
BenchmarkCachedABACModel - B/op 1543 B/op 1546 B/op 1.00
BenchmarkCachedABACModel - allocs/op 18 allocs/op 18 allocs/op 1
BenchmarkCachedKeyMatchModel 189.4 ns/op 152 B/op 4 allocs/op 190.2 ns/op 152 B/op 4 allocs/op 1.00
BenchmarkCachedKeyMatchModel - ns/op 189.4 ns/op 190.2 ns/op 1.00
BenchmarkCachedKeyMatchModel - B/op 152 B/op 152 B/op 1
BenchmarkCachedKeyMatchModel - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedRBACModelWithDeny 171 ns/op 104 B/op 4 allocs/op 170.5 ns/op 104 B/op 4 allocs/op 1.00
BenchmarkCachedRBACModelWithDeny - ns/op 171 ns/op 170.5 ns/op 1.00
BenchmarkCachedRBACModelWithDeny - B/op 104 B/op 104 B/op 1
BenchmarkCachedRBACModelWithDeny - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedPriorityModel 170.9 ns/op 104 B/op 4 allocs/op 170.7 ns/op 104 B/op 4 allocs/op 1.00
BenchmarkCachedPriorityModel - ns/op 170.9 ns/op 170.7 ns/op 1.00
BenchmarkCachedPriorityModel - B/op 104 B/op 104 B/op 1
BenchmarkCachedPriorityModel - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkCachedWithEnforceContext 305.4 ns/op 240 B/op 5 allocs/op 306.9 ns/op 240 B/op 5 allocs/op 1.00
BenchmarkCachedWithEnforceContext - ns/op 305.4 ns/op 306.9 ns/op 1.00
BenchmarkCachedWithEnforceContext - B/op 240 B/op 240 B/op 1
BenchmarkCachedWithEnforceContext - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkCachedRBACModelMediumParallel 164.4 ns/op 105 B/op 4 allocs/op 168.4 ns/op 105 B/op 4 allocs/op 0.98
BenchmarkCachedRBACModelMediumParallel - ns/op 164.4 ns/op 168.4 ns/op 0.98
BenchmarkCachedRBACModelMediumParallel - B/op 105 B/op 105 B/op 1
BenchmarkCachedRBACModelMediumParallel - allocs/op 4 allocs/op 4 allocs/op 1
BenchmarkHasPolicySmall 533.4 ns/op 150 B/op 6 allocs/op 519.1 ns/op 150 B/op 6 allocs/op 1.03
BenchmarkHasPolicySmall - ns/op 533.4 ns/op 519.1 ns/op 1.03
BenchmarkHasPolicySmall - B/op 150 B/op 150 B/op 1
BenchmarkHasPolicySmall - allocs/op 6 allocs/op 6 allocs/op 1
BenchmarkHasPolicyMedium 566.8 ns/op 157 B/op 6 allocs/op 553.3 ns/op 157 B/op 6 allocs/op 1.02
BenchmarkHasPolicyMedium - ns/op 566.8 ns/op 553.3 ns/op 1.02
BenchmarkHasPolicyMedium - B/op 157 B/op 157 B/op 1
BenchmarkHasPolicyMedium - allocs/op 6 allocs/op 6 allocs/op 1
BenchmarkHasPolicyLarge 560.5 ns/op 165 B/op 7 allocs/op 589.4 ns/op 165 B/op 7 allocs/op 0.95
BenchmarkHasPolicyLarge - ns/op 560.5 ns/op 589.4 ns/op 0.95
BenchmarkHasPolicyLarge - B/op 165 B/op 165 B/op 1
BenchmarkHasPolicyLarge - allocs/op 7 allocs/op 7 allocs/op 1
BenchmarkAddPolicySmall 515.9 ns/op 152 B/op 6 allocs/op 553.1 ns/op 152 B/op 6 allocs/op 0.93
BenchmarkAddPolicySmall - ns/op 515.9 ns/op 553.1 ns/op 0.93
BenchmarkAddPolicySmall - B/op 152 B/op 152 B/op 1
BenchmarkAddPolicySmall - allocs/op 6 allocs/op 6 allocs/op 1
BenchmarkAddPolicyMedium 561.9 ns/op 168 B/op 7 allocs/op 645.8 ns/op 169 B/op 7 allocs/op 0.87
BenchmarkAddPolicyMedium - ns/op 561.9 ns/op 645.8 ns/op 0.87
BenchmarkAddPolicyMedium - B/op 168 B/op 169 B/op 0.99
BenchmarkAddPolicyMedium - allocs/op 7 allocs/op 7 allocs/op 1
BenchmarkAddPolicyLarge 1272 ns/op 459 B/op 9 allocs/op 1242 ns/op 464 B/op 9 allocs/op 1.02
BenchmarkAddPolicyLarge - ns/op 1272 ns/op 1242 ns/op 1.02
BenchmarkAddPolicyLarge - B/op 459 B/op 464 B/op 0.99
BenchmarkAddPolicyLarge - allocs/op 9 allocs/op 9 allocs/op 1
BenchmarkRemovePolicySmall 551.7 ns/op 166 B/op 7 allocs/op 522.1 ns/op 166 B/op 7 allocs/op 1.06
BenchmarkRemovePolicySmall - ns/op 551.7 ns/op 522.1 ns/op 1.06
BenchmarkRemovePolicySmall - B/op 166 B/op 166 B/op 1
BenchmarkRemovePolicySmall - allocs/op 7 allocs/op 7 allocs/op 1
BenchmarkRemovePolicyMedium 587.8 ns/op 175 B/op 7 allocs/op 558.8 ns/op 175 B/op 7 allocs/op 1.05
BenchmarkRemovePolicyMedium - ns/op 587.8 ns/op 558.8 ns/op 1.05
BenchmarkRemovePolicyMedium - B/op 175 B/op 175 B/op 1
BenchmarkRemovePolicyMedium - allocs/op 7 allocs/op 7 allocs/op 1
BenchmarkRemovePolicyLarge 1315 ns/op 281 B/op 12 allocs/op 1322 ns/op 288 B/op 13 allocs/op 0.99
BenchmarkRemovePolicyLarge - ns/op 1315 ns/op 1322 ns/op 0.99
BenchmarkRemovePolicyLarge - B/op 281 B/op 288 B/op 0.98
BenchmarkRemovePolicyLarge - allocs/op 12 allocs/op 13 allocs/op 0.92
BenchmarkRaw 17.56 ns/op 0 B/op 0 allocs/op 17.58 ns/op 0 B/op 0 allocs/op 1.00
BenchmarkRaw - ns/op 17.56 ns/op 17.58 ns/op 1.00
BenchmarkRaw - B/op 0 B/op 0 B/op 1
BenchmarkRaw - allocs/op 0 allocs/op 0 allocs/op 1
BenchmarkBasicModel 3581 ns/op 1504 B/op 17 allocs/op 3690 ns/op 1509 B/op 17 allocs/op 0.97
BenchmarkBasicModel - ns/op 3581 ns/op 3690 ns/op 0.97
BenchmarkBasicModel - B/op 1504 B/op 1509 B/op 1.00
BenchmarkBasicModel - allocs/op 17 allocs/op 17 allocs/op 1
BenchmarkRBACModel 5283 ns/op 2058 B/op 35 allocs/op 5549 ns/op 2069 B/op 35 allocs/op 0.95
BenchmarkRBACModel - ns/op 5283 ns/op 5549 ns/op 0.95
BenchmarkRBACModel - B/op 2058 B/op 2069 B/op 0.99
BenchmarkRBACModel - allocs/op 35 allocs/op 35 allocs/op 1
BenchmarkRBACModelSizes/small 48025 ns/op 20266 B/op 480 allocs/op 52640 ns/op 20284 B/op 480 allocs/op 0.91
BenchmarkRBACModelSizes/small - ns/op 48025 ns/op 52640 ns/op 0.91
BenchmarkRBACModelSizes/small - B/op 20266 B/op 20284 B/op 1.00
BenchmarkRBACModelSizes/small - allocs/op 480 allocs/op 480 allocs/op 1
BenchmarkRBACModelSizes/medium 478346 ns/op 191647 B/op 4828 allocs/op 534539 ns/op 191714 B/op 4829 allocs/op 0.89
BenchmarkRBACModelSizes/medium - ns/op 478346 ns/op 534539 ns/op 0.89
BenchmarkRBACModelSizes/medium - B/op 191647 B/op 191714 B/op 1.00
BenchmarkRBACModelSizes/medium - allocs/op 4828 allocs/op 4829 allocs/op 1.00
BenchmarkRBACModelSizes/large 5163997 ns/op 1899883 B/op 48175 allocs/op 6081113 ns/op 1900765 B/op 48203 allocs/op 0.85
BenchmarkRBACModelSizes/large - ns/op 5163997 ns/op 6081113 ns/op 0.85
BenchmarkRBACModelSizes/large - B/op 1899883 B/op 1900765 B/op 1.00
BenchmarkRBACModelSizes/large - allocs/op 48175 allocs/op 48203 allocs/op 1.00
BenchmarkRBACModelSmall 58456 ns/op 20183 B/op 615 allocs/op 62771 ns/op 20404 B/op 615 allocs/op 0.93
BenchmarkRBACModelSmall - ns/op 58456 ns/op 62771 ns/op 0.93
BenchmarkRBACModelSmall - B/op 20183 B/op 20404 B/op 0.99
BenchmarkRBACModelSmall - allocs/op 615 allocs/op 615 allocs/op 1
BenchmarkRBACModelMedium 539888 ns/op 194121 B/op 6017 allocs/op 595611 ns/op 194707 B/op 6018 allocs/op 0.91
BenchmarkRBACModelMedium - ns/op 539888 ns/op 595611 ns/op 0.91
BenchmarkRBACModelMedium - B/op 194121 B/op 194707 B/op 1.00
BenchmarkRBACModelMedium - allocs/op 6017 allocs/op 6018 allocs/op 1.00
BenchmarkRBACModelLarge 5762432 ns/op 1932815 B/op 60295 allocs/op 6139679 ns/op 1933403 B/op 60306 allocs/op 0.94
BenchmarkRBACModelLarge - ns/op 5762432 ns/op 6139679 ns/op 0.94
BenchmarkRBACModelLarge - B/op 1932815 B/op 1933403 B/op 1.00
BenchmarkRBACModelLarge - allocs/op 60295 allocs/op 60306 allocs/op 1.00
BenchmarkRBACModelWithResourceRoles 5153 ns/op 2733 B/op 28 allocs/op 5484 ns/op 2740 B/op 28 allocs/op 0.94
BenchmarkRBACModelWithResourceRoles - ns/op 5153 ns/op 5484 ns/op 0.94
BenchmarkRBACModelWithResourceRoles - B/op 2733 B/op 2740 B/op 1.00
BenchmarkRBACModelWithResourceRoles - allocs/op 28 allocs/op 28 allocs/op 1
BenchmarkRBACModelWithDomains 4989 ns/op 1826 B/op 25 allocs/op 5204 ns/op 1827 B/op 25 allocs/op 0.96
BenchmarkRBACModelWithDomains - ns/op 4989 ns/op 5204 ns/op 0.96
BenchmarkRBACModelWithDomains - B/op 1826 B/op 1827 B/op 1.00
BenchmarkRBACModelWithDomains - allocs/op 25 allocs/op 25 allocs/op 1
BenchmarkABACModel 2772 ns/op 1534 B/op 17 allocs/op 2879 ns/op 1537 B/op 17 allocs/op 0.96
BenchmarkABACModel - ns/op 2772 ns/op 2879 ns/op 0.96
BenchmarkABACModel - B/op 1534 B/op 1537 B/op 1.00
BenchmarkABACModel - allocs/op 17 allocs/op 17 allocs/op 1
BenchmarkABACRuleModel 3891015 ns/op 1328409 B/op 40092 allocs/op 4091106 ns/op 1329131 B/op 40092 allocs/op 0.95
BenchmarkABACRuleModel - ns/op 3891015 ns/op 4091106 ns/op 0.95
BenchmarkABACRuleModel - B/op 1328409 B/op 1329131 B/op 1.00
BenchmarkABACRuleModel - allocs/op 40092 allocs/op 40092 allocs/op 1
BenchmarkKeyMatchModel 5991 ns/op 3064 B/op 37 allocs/op 6298 ns/op 3074 B/op 37 allocs/op 0.95
BenchmarkKeyMatchModel - ns/op 5991 ns/op 6298 ns/op 0.95
BenchmarkKeyMatchModel - B/op 3064 B/op 3074 B/op 1.00
BenchmarkKeyMatchModel - allocs/op 37 allocs/op 37 allocs/op 1
BenchmarkRBACModelWithDeny 6883 ns/op 2482 B/op 49 allocs/op 6978 ns/op 2482 B/op 49 allocs/op 0.99
BenchmarkRBACModelWithDeny - ns/op 6883 ns/op 6978 ns/op 0.99
BenchmarkRBACModelWithDeny - B/op 2482 B/op 2482 B/op 1
BenchmarkRBACModelWithDeny - allocs/op 49 allocs/op 49 allocs/op 1
BenchmarkPriorityModel 4133 ns/op 1763 B/op 22 allocs/op 4305 ns/op 1765 B/op 22 allocs/op 0.96
BenchmarkPriorityModel - ns/op 4133 ns/op 4305 ns/op 0.96
BenchmarkPriorityModel - B/op 1763 B/op 1765 B/op 1.00
BenchmarkPriorityModel - allocs/op 22 allocs/op 22 allocs/op 1
BenchmarkRBACModelWithDomainPatternLarge 22314 ns/op 16738 B/op 164 allocs/op 24866 ns/op 16722 B/op 164 allocs/op 0.90
BenchmarkRBACModelWithDomainPatternLarge - ns/op 22314 ns/op 24866 ns/op 0.90
BenchmarkRBACModelWithDomainPatternLarge - B/op 16738 B/op 16722 B/op 1.00
BenchmarkRBACModelWithDomainPatternLarge - allocs/op 164 allocs/op 164 allocs/op 1
BenchmarkRoleManagerSmall 67739 ns/op 11954 B/op 797 allocs/op 72311 ns/op 11955 B/op 797 allocs/op 0.94
BenchmarkRoleManagerSmall - ns/op 67739 ns/op 72311 ns/op 0.94
BenchmarkRoleManagerSmall - B/op 11954 B/op 11955 B/op 1.00
BenchmarkRoleManagerSmall - allocs/op 797 allocs/op 797 allocs/op 1
BenchmarkRoleManagerMedium 714578 ns/op 125914 B/op 8741 allocs/op 736318 ns/op 125915 B/op 8741 allocs/op 0.97
BenchmarkRoleManagerMedium - ns/op 714578 ns/op 736318 ns/op 0.97
BenchmarkRoleManagerMedium - B/op 125914 B/op 125915 B/op 1.00
BenchmarkRoleManagerMedium - allocs/op 8741 allocs/op 8741 allocs/op 1
BenchmarkRoleManagerLarge 7732673 ns/op 1349919 B/op 89741 allocs/op 7947330 ns/op 1349921 B/op 89741 allocs/op 0.97
BenchmarkRoleManagerLarge - ns/op 7732673 ns/op 7947330 ns/op 0.97
BenchmarkRoleManagerLarge - B/op 1349919 B/op 1349921 B/op 1.00
BenchmarkRoleManagerLarge - allocs/op 89741 allocs/op 89741 allocs/op 1
BenchmarkBuildRoleLinksWithPatternLarge 5859712437 ns/op 5345583480 B/op 60948514 allocs/op 6416438245 ns/op 5345527312 B/op 60949275 allocs/op 0.91
BenchmarkBuildRoleLinksWithPatternLarge - ns/op 5859712437 ns/op 6416438245 ns/op 0.91
BenchmarkBuildRoleLinksWithPatternLarge - B/op 5345583480 B/op 5345527312 B/op 1.00
BenchmarkBuildRoleLinksWithPatternLarge - allocs/op 60948514 allocs/op 60949275 allocs/op 1.00
BenchmarkBuildRoleLinksWithDomainPatternLarge 162026121 ns/op 141772106 B/op 1676515 allocs/op 178943074 ns/op 141563910 B/op 1676494 allocs/op 0.91
BenchmarkBuildRoleLinksWithDomainPatternLarge - ns/op 162026121 ns/op 178943074 ns/op 0.91
BenchmarkBuildRoleLinksWithDomainPatternLarge - B/op 141772106 B/op 141563910 B/op 1.00
BenchmarkBuildRoleLinksWithDomainPatternLarge - allocs/op 1676515 allocs/op 1676494 allocs/op 1.00
BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge 6034492315 ns/op 5485225440 B/op 62559574 allocs/op 6619276996 ns/op 5482336640 B/op 62559659 allocs/op 0.91
BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge - ns/op 6034492315 ns/op 6619276996 ns/op 0.91
BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge - B/op 5485225440 B/op 5482336640 B/op 1.00
BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge - allocs/op 62559574 allocs/op 62559659 allocs/op 1.00
BenchmarkHasLinkWithPatternLarge 9997 ns/op 7606 B/op 111 allocs/op 10949 ns/op 7606 B/op 111 allocs/op 0.91
BenchmarkHasLinkWithPatternLarge - ns/op 9997 ns/op 10949 ns/op 0.91
BenchmarkHasLinkWithPatternLarge - B/op 7606 B/op 7606 B/op 1
BenchmarkHasLinkWithPatternLarge - allocs/op 111 allocs/op 111 allocs/op 1
BenchmarkHasLinkWithDomainPatternLarge 470.9 ns/op 80 B/op 5 allocs/op 500.9 ns/op 80 B/op 5 allocs/op 0.94
BenchmarkHasLinkWithDomainPatternLarge - ns/op 470.9 ns/op 500.9 ns/op 0.94
BenchmarkHasLinkWithDomainPatternLarge - B/op 80 B/op 80 B/op 1
BenchmarkHasLinkWithDomainPatternLarge - allocs/op 5 allocs/op 5 allocs/op 1
BenchmarkHasLinkWithPatternAndDomainPatternLarge 9990 ns/op 7611 B/op 111 allocs/op 10644 ns/op 7604 B/op 111 allocs/op 0.94
BenchmarkHasLinkWithPatternAndDomainPatternLarge - ns/op 9990 ns/op 10644 ns/op 0.94
BenchmarkHasLinkWithPatternAndDomainPatternLarge - B/op 7611 B/op 7604 B/op 1.00
BenchmarkHasLinkWithPatternAndDomainPatternLarge - allocs/op 111 allocs/op 111 allocs/op 1

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.