-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
auth: store cached permission information in a form of interval tree #7569
Conversation
Codecov Report
@@ Coverage Diff @@
## master #7569 +/- ##
=========================================
Coverage ? 70.15%
=========================================
Files ? 320
Lines ? 26165
Branches ? 0
=========================================
Hits ? 18355
Misses ? 6355
Partials ? 1455
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to see patches that remove code. Looks OK in general, but would benefit from some tests (at least for the [a, z) vs ([a, c) U [x,z)) case)
auth/range_perm_cache.go
Outdated
|
||
case authpb.WRITE: | ||
writePerms = append(writePerms, rp) | ||
if len(perm.RangeEnd) != 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var ivl adt.Interval
if len(perm.RangeEnd) != 0 {
ivl = adt.NewStringAffineInterval(string(perm.Key), string(perm.RangeEnd))
} else {
ivl = adt.NewStringAffinePoint(string(perm.Key))
}
switch perm.PermType {
...
}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes, the type of the return value of NewStringAffinePoint()
is also Interval
, so it can be simplified as you pointed. I'll fix it.
auth/range_perm_cache.go
Outdated
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I check for permission on [a, z) and I have permission for ranges [a, c) and [x, z), this will say there's permission for all of [a, z)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed the case... thanks! Possibly
- visit every interval that overlaps with the required range
- check all the intervals are continuous
- if they are not continuous, permission denied
return minBegin.Compare(adt.StringComparable(key)) < 0 && maxEnd.Compare(adt.StringComparable(maxEnd)) < 0
I'll also add some test cases. At first I thought that the implementation of interval tree has its own tests, so adding new tests would be redundant. But clearly it was wrong...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're not necessarily continuous for cases like [a, f), [c, d), [f, z). If you're feeling adventurous, this can probably be written abstractly using only adt.Comparable
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The word "continuous" wasn't good. I just tried to mean "no hole in the granted permissions". The check would be performed like this:
tocheck.Visit(ivl, func(n *adt.IntervalValue) bool {
visited = append(visited, n)
return false
})
for i := 0; i < len(visited)-1; i++ {
if visited[i].Ivl.End.Compare(visited[i+1].Ivl.Begin) == -1 {
// there is a hole, permission denied
return false
}
}
The loop can handle the case you showed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's still possible to get something like [a, d), [a, b), [c, f)
.
isContiguous := true
var maxEnd, minBegin adt.Comparable
tocheck.Visit(ivl, func(n *adt.IntervalValue) bool {
if minBegin == nil { minBegin = n.Ivl.Begin; maxEnd = n.Ivl.End; return true}
if maxEnd.Compare(n.ivl.Begin) < 0 { isContiguous = false; return false }
if maxEnd.Compare(n.ivl.End) > 0 { maxEnd = n.ivl.End }
return true
})
contains := isContiguous && maxEnd.Compare(ivl.End) >= 0 && minBegin.Compare(ivl.Begin) <= 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your strategy seems to be good, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I got the bools right-- false should stop evaluating. On the other hand, it appears that the interval tree is ignoring the return value entirely. haha oops. I'll fix it in that sorted visit PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was my misunderstanding... I noticed it and updated my comment because I didn't receive your reply at that time ;)
@heyitsanthony updated based on your comments. The main changed points:
But this PR depends on your PR #7581 so it cannot be merged now. |
This commit change the type of cached permission information from the home made thing to interval tree. It improves computational complexity of permission checking from O(n) to O(lg n).
@heyitsanthony rebased on the master (that includes your changes of interval tree), so this PR would be able to work well. Could you take a look? |
@heyitsanthony two test fails can be found but they don't seem to be related with this change because they are related to membership management: #7594 and #7595 |
@heyitsanthony kindly ping? Do you have any opinions about the failed tests? |
@mitake oops sorry for losing this in the shuffle. I kicked CI and it's passing. The interval tree adt could stand to have contiguity checking and lgtm, thanks! |
@heyitsanthony then I'm merging it, thanks! I also add the changes of interval tree in other PRs. BTW the failed test seems to be same with #7595 |
This commit change the type of cached permission information from the
home made thing to interval tree. It improves computational complexity
of permission checking from O(n) to O(lg n).
/cc @heyitsanthony This is a preparation for #7468 , could you take a look? We can support the unlimited range by configuring a permission like ["a", "\xff") in a simple manner thanks to interval tree.