Skip to content

Commit e6c2869

Browse files
committed
perf(enforce): reuse pooled buffers to reduce allocations
1 parent 0fe9505 commit e6c2869

1 file changed

Lines changed: 59 additions & 7 deletions

File tree

enforcer.go

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,47 @@ func (e *Enforcer) invalidateMatcherMap() {
679679
e.matcherMap = sync.Map{}
680680
}
681681

682+
type policyEffectsBuffer struct {
683+
values []effector.Effect
684+
}
685+
686+
type matcherResultsBuffer struct {
687+
values []float64
688+
}
689+
690+
var globalPolicyEffectsPool = sync.Pool{New: func() interface{} { return &policyEffectsBuffer{values: make([]effector.Effect, 0)} }}
691+
var globalMatcherResultsPool = sync.Pool{New: func() interface{} { return &matcherResultsBuffer{values: make([]float64, 0)} }}
692+
693+
func (e *Enforcer) getPolicyEffectsBuffer(size int) ([]effector.Effect, *policyEffectsBuffer) {
694+
buffer := globalPolicyEffectsPool.Get().(*policyEffectsBuffer)
695+
if cap(buffer.values) < size {
696+
buffer.values = make([]effector.Effect, size)
697+
} else {
698+
buffer.values = buffer.values[:size]
699+
}
700+
return buffer.values, buffer
701+
}
702+
703+
func (e *Enforcer) putPolicyEffectsBuffer(buffer *policyEffectsBuffer) {
704+
buffer.values = buffer.values[:0]
705+
globalPolicyEffectsPool.Put(buffer)
706+
}
707+
708+
func (e *Enforcer) getMatcherResultsBuffer(size int) ([]float64, *matcherResultsBuffer) {
709+
buffer := globalMatcherResultsPool.Get().(*matcherResultsBuffer)
710+
if cap(buffer.values) < size {
711+
buffer.values = make([]float64, size)
712+
} else {
713+
buffer.values = buffer.values[:size]
714+
}
715+
return buffer.values, buffer
716+
}
717+
718+
func (e *Enforcer) putMatcherResultsBuffer(buffer *matcherResultsBuffer) {
719+
buffer.values = buffer.values[:0]
720+
globalMatcherResultsPool.Put(buffer)
721+
}
722+
682723
// enforce use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "".
683724
func (e *Enforcer) enforce(matcher string, explains *[]string, rvals ...interface{}) (ok bool, err error) { //nolint:funlen,cyclop,gocyclo // TODO: reduce function complexity
684725
logEntry := e.onLogBeforeEventInEnforce(rvals)
@@ -793,15 +834,22 @@ func (e *Enforcer) enforce(matcher string, explains *[]string, rvals ...interfac
793834
rvals)
794835
}
795836

796-
var policyEffects []effector.Effect
797-
var matcherResults []float64
798-
799837
var effect effector.Effect
800838
var explainIndex int
801839

802840
if policyLen := len(e.model["p"][pType].Policy); policyLen != 0 && strings.Contains(expString, pType+"_") { //nolint:nestif // TODO: reduce function complexity
803-
policyEffects = make([]effector.Effect, policyLen)
804-
matcherResults = make([]float64, policyLen)
841+
policyEffects, policyEffectsBuffer := e.getPolicyEffectsBuffer(policyLen)
842+
matcherResults, matcherResultsBuffer := e.getMatcherResultsBuffer(policyLen)
843+
defer func() {
844+
e.putPolicyEffectsBuffer(policyEffectsBuffer)
845+
e.putMatcherResultsBuffer(matcherResultsBuffer)
846+
}()
847+
for i := range matcherResults {
848+
matcherResults[i] = 0
849+
}
850+
for i := range policyEffects {
851+
policyEffects[i] = 0
852+
}
805853

806854
for policyIndex, pvals := range e.model["p"][pType].Policy {
807855
// log.LogPrint("Policy Rule: ", pvals)
@@ -867,8 +915,12 @@ func (e *Enforcer) enforce(matcher string, explains *[]string, rvals ...interfac
867915
return false, errors.New("please make sure rule exists in policy when using eval() in matcher")
868916
}
869917

870-
policyEffects = make([]effector.Effect, 1)
871-
matcherResults = make([]float64, 1)
918+
policyEffects, policyEffectsBuffer := e.getPolicyEffectsBuffer(1)
919+
matcherResults, matcherResultsBuffer := e.getMatcherResultsBuffer(1)
920+
defer func() {
921+
e.putPolicyEffectsBuffer(policyEffectsBuffer)
922+
e.putMatcherResultsBuffer(matcherResultsBuffer)
923+
}()
872924
matcherResults[0] = 1
873925

874926
parameters.pVals = make([]string, len(parameters.pTokens))

0 commit comments

Comments
 (0)