Skip to content

Commit 69bc1a8

Browse files
committed
perf: optimize batch policy removal
Signed-off-by: huynhanx03 <157712338+huynhanx03@users.noreply.github.com>
1 parent 16b0c89 commit 69bc1a8

2 files changed

Lines changed: 64 additions & 8 deletions

File tree

management_api_b_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,36 @@ func BenchmarkRemovePolicyLarge(b *testing.B) {
172172
_, _ = e.RemovePolicy(fmt.Sprintf("user%d", rand.Intn(10000)), fmt.Sprintf("data%d", rand.Intn(10000)/10), "read")
173173
}
174174
}
175+
176+
func BenchmarkRemovePoliciesLarge(b *testing.B) {
177+
e, _ := NewEnforcer("examples/basic_model.conf")
178+
179+
const batchSize = 100
180+
181+
for i := 0; i < b.N; i++ {
182+
b.StopTimer()
183+
rules := make([][]string, 0, batchSize)
184+
for j := 0; j < batchSize; j++ {
185+
id := i*batchSize + j
186+
rules = append(rules, []string{fmt.Sprintf("user%d", id), fmt.Sprintf("data%d", id/10), "read"})
187+
}
188+
189+
added, err := e.AddPolicies(rules)
190+
if err != nil {
191+
b.Fatal(err)
192+
}
193+
if !added {
194+
b.Fatal("expected AddPolicies to add rules")
195+
}
196+
197+
b.StartTimer()
198+
removed, err := e.RemovePolicies(rules)
199+
b.StopTimer()
200+
if err != nil {
201+
b.Fatal(err)
202+
}
203+
if !removed {
204+
b.Fatal("expected RemovePolicies to remove rules")
205+
}
206+
}
207+
}

model/policy.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -344,24 +344,47 @@ func (model Model) RemovePolicies(sec string, ptype string, rules [][]string) (b
344344

345345
// RemovePoliciesWithAffected removes policy rules from the model, and returns affected rules.
346346
func (model Model) RemovePoliciesWithAffected(sec string, ptype string, rules [][]string) ([][]string, error) {
347-
_, err := model.GetAssertion(sec, ptype)
347+
assertion, err := model.GetAssertion(sec, ptype)
348348
if err != nil {
349349
return nil, err
350350
}
351+
351352
var affected [][]string
353+
removeSet := make(map[string]struct{}, len(rules))
354+
352355
for _, rule := range rules {
353-
index, ok := model[sec][ptype].PolicyMap[strings.Join(rule, DefaultSep)]
354-
if !ok {
356+
key := strings.Join(rule, DefaultSep)
357+
if _, ok := assertion.PolicyMap[key]; !ok {
355358
continue
356359
}
357-
360+
if _, exists := removeSet[key]; exists {
361+
continue
362+
}
363+
if affected == nil {
364+
affected = make([][]string, 0, len(rules))
365+
}
358366
affected = append(affected, rule)
359-
model[sec][ptype].Policy = append(model[sec][ptype].Policy[:index], model[sec][ptype].Policy[index+1:]...)
360-
delete(model[sec][ptype].PolicyMap, strings.Join(rule, DefaultSep))
361-
for i := index; i < len(model[sec][ptype].Policy); i++ {
362-
model[sec][ptype].PolicyMap[strings.Join(model[sec][ptype].Policy[i], DefaultSep)] = i
367+
removeSet[key] = struct{}{}
368+
}
369+
370+
if len(removeSet) == 0 {
371+
return affected, nil
372+
}
373+
374+
compactPolicy := assertion.Policy[:0]
375+
compactPolicyMap := make(map[string]int, len(assertion.Policy)-len(removeSet))
376+
for _, policyRule := range assertion.Policy {
377+
key := strings.Join(policyRule, DefaultSep)
378+
if _, ok := removeSet[key]; ok {
379+
continue
363380
}
381+
compactPolicyMap[key] = len(compactPolicy)
382+
compactPolicy = append(compactPolicy, policyRule)
364383
}
384+
385+
assertion.Policy = compactPolicy
386+
assertion.PolicyMap = compactPolicyMap
387+
365388
return affected, nil
366389
}
367390

0 commit comments

Comments
 (0)