diff options
author | Sean McGivern <sean@gitlab.com> | 2017-10-04 14:13:22 +0100 |
---|---|---|
committer | Sean McGivern <sean@gitlab.com> | 2017-10-05 10:12:58 +0100 |
commit | e9476eb97af59404438d8403968a282d6d08a20d (patch) | |
tree | 6e0b9c6cdfb18095cf7c49c470fb54b7d817d988 /lib/declarative_policy | |
parent | d7717192782232c14c4f16962ab450b08348a4c9 (diff) | |
download | gitlab-ce-e9476eb97af59404438d8403968a282d6d08a20d.tar.gz |
Speed up cached_pass? for composite rules
Both `Or` and `And` would evaluate whether each rule passed, then calculate a
value based on the results of all of those. We can actually return early in many
cases, without running the rule at all.
Diffstat (limited to 'lib/declarative_policy')
-rw-r--r-- | lib/declarative_policy/rule.rb | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/declarative_policy/rule.rb b/lib/declarative_policy/rule.rb index bfcec241489..7cfa82a9a9f 100644 --- a/lib/declarative_policy/rule.rb +++ b/lib/declarative_policy/rule.rb @@ -206,11 +206,13 @@ module DeclarativePolicy end def cached_pass?(context) - passes = @rules.map { |r| r.cached_pass?(context) } - return false if passes.any? { |p| p == false } - return true if passes.all? { |p| p == true } + @rules.each do |rule| + pass = rule.cached_pass?(context) - nil + return pass if pass.nil? || pass == false + end + + true end def repr @@ -245,11 +247,13 @@ module DeclarativePolicy end def cached_pass?(context) - passes = @rules.map { |r| r.cached_pass?(context) } - return true if passes.any? { |p| p == true } - return false if passes.all? { |p| p == false } + @rules.each do |rule| + pass = rule.cached_pass?(context) - nil + return pass if pass.nil? || pass == true + end + + false end def score(context) |