-
Notifications
You must be signed in to change notification settings - Fork 84
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
Constant time len #182
base: main
Are you sure you want to change the base?
Constant time len #182
Conversation
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.
Maybe we can use the constant len
in select too?
fn new(bitmap: &RoaringBitmap) -> Iter { | ||
let size_hint = bitmap.len(); | ||
Iter { inner: bitmap.containers.iter().flatten(), size_hint } |
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.
Can you explain to me the fact #179 removes the size_hint implementation and here we continue to track the length of the bitmap? I feel lost.
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.
#176 Has the reasoning
The code it replaced would unconditionally panic. To guess the original author's intent: it was a runtime check that the count is tracked at the outer iterator. Panicking broke some new proptests, so we implemented the correct behavior. However, it is still true that the size hint is unreachable from the exposed API. The iterator is doing extra work the end user can never observe.
I suspect the regression went unnoticed since #125 plus this issue is still a net perf gain.
Proposing we just remove the size hints altogether and return the default (0, None). It will satisfy the validity requirements of tests without needlessly slowing down iteration.
We track the len of the RoaringBitmap
here, therefore the the BitmapStore
iter size_hint
is unreachable by the external api. However, it should not panic, because it is reachable by tests, so it can return the default (0, None)
which indicates no size hint.
pub fn push(&mut self, value: u64) -> bool { | ||
let (hi, lo) = util::split(value); | ||
self.map.entry(hi).or_insert_with(RoaringBitmap::new).push(lo) | ||
let pushed = self.map.entry(hi).or_insert_with(RoaringBitmap::new).push(lo); | ||
self.len += pushed as u64; | ||
pushed |
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.
Pushes
value
in the treemap only if it is greater than the current maximum value.
This is wrong BTW 😄
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.
You're right! Please open an issue.
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.
Maybe we can use the new constant len
in select too?
I'm not sure what the right approach to testing this is. |
Do you mean benchmarking the constant length or checking that However, checking that the length is valid is maybe a little bit complex, we could maybe add an |
This is what I meant. I'm trying to think of a clean way to |
Wouldn't it be ok to directly do I just hope that we haven't implemented the |
I just checked in the playground and the macro expansion indeed works like that: it didn't panic when compiling in release. |
Of course it does. Why should it recompute the cached len? Edit: It's an exact size iterator whose size hint is initialized by |
Ok so we should trick by doing a |
We'd probably have to wrap it in a |
@@ -375,8 +386,6 @@ impl RoaringBitmap { | |||
/// assert_eq!(rb.rank(10), 2) | |||
/// ``` | |||
pub fn rank(&self, value: u32) -> u64 { | |||
// if len becomes cached for RoaringBitmap: return len if len > value |
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.
This is incorrect. Should have been return len if len > max
Computing max is not constant time for BitmapStore
Thinking we should assert invariants #197 before we merge this to be sure we didn't introduce a regression |
Fixes #45
Closes #105