Skip to content
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

Is there a way to get the inverse of a bitset? #686

Closed
arnoldrobbins opened this issue Jan 8, 2025 · 4 comments
Closed

Is there a way to get the inverse of a bitset? #686

arnoldrobbins opened this issue Jan 8, 2025 · 4 comments

Comments

@arnoldrobbins
Copy link

Looking at the headers, I don't see an easy way to invert a bitset. The equivalent of the C ~ operator.

We have an application that needs to do LHS |= RHS and also LHS |= ~ RHS. The latter doesn't look doable with CRoaring. Can that be added?

Thanks!

@Dr-Emann
Copy link
Member

Dr-Emann commented Jan 8, 2025

There is roaring_bitmap_flip (and closed/in place versions), which take a range, so to roaring_bitmap_t *inverted_rhs = roaring_bitmap_flip_closed(RHS, 0, UINT32_MAX) may be what you want.

@lemire
Copy link
Member

lemire commented Jan 8, 2025

@Dr-Emann has the correct answer:

/**
 * Compute the negation of the bitmap in the interval [range_start, range_end).
 * The number of negated values is range_end - range_start.
 * Areas outside the range are passed through unchanged.
 */
roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *r1,
                                      uint64_t range_start, uint64_t range_end);

/**
 * Compute the negation of the bitmap in the interval [range_start, range_end].
 * The number of negated values is range_end - range_start + 1.
 * Areas outside the range are passed through unchanged.
 */
roaring_bitmap_t *roaring_bitmap_flip_closed(const roaring_bitmap_t *x1,
                                             uint32_t range_start,
                                             uint32_t range_end);

so to roaring_bitmap_t *inverted_rhs = roaring_bitmap_flip_closed(RHS, 0, UINT32_MAX) may be what you want.

I suspect not because this full range up to UINT32_MAX might insert 4 billions 1-bits in your bitmap... which is a lot. Typically, if a bit reversal is what you really need, you have a reasonable universe size... E.g., in the case of the C operator, the universe size might be 32 or 64. So if your bitmaps are in the range from 0 to 1000000, you do roaring_bitmap_flip(RHS, 0, 1000000). That's sensible.

I am going to close this issue as the functionality is already present.

@lemire lemire closed this as completed Jan 8, 2025
@Dr-Emann
Copy link
Member

Dr-Emann commented Jan 9, 2025

Will also note, thanks to range containers, fully inverting an empty bitmap will "only" involve 65k full range containers, but yeah, you can do a lot better if you have a defined max that you actually care about.

Will also also note, LHS |= ~RHS is much less common than LHS &= ~RHS, which is available as a single efficent operation, roaring_bitmap_andnot_inplace

@arnoldrobbins
Copy link
Author

@Dr-Emann and @lemire Thank you both for this. This is exactly what I need. The range I'm working on is 0 to less than 1,200,000, so I don't need anywhere near UNIT32_MAX.

I'm hoping that CRoaring will be useful; I plan to try to try it out today. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants