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

Feature Request: BitSet wrapper for BitVec #171

Open
bjchambers opened this issue Apr 8, 2022 · 3 comments
Open

Feature Request: BitSet wrapper for BitVec #171

bjchambers opened this issue Apr 8, 2022 · 3 comments

Comments

@bjchambers
Copy link

I believe that BitVec provides all the necessary functionality to implement a BitSet wrapper, in a way that would be reasonably convenient.

  • Inserting an element -- resize (inserting 0) if needed to grow the array, then set the index to 1.
  • Contains -- check to see if the index is 1
  • Iterator -- iter_ones
  • Union / Intersection -- use existing BitAnd and BitOr implementations

The main thing it would provide is a way to use BitVec as a set without needing to explicitly manage the length.

Does this seem like a worthwhile addition (at least behind a feature flag)?

Right now I use bitvec for vectors and bit-set (https://crates.io/crates/bit-set) for the set operations, which then means I also depend (transitively) on bit-vec. The latter two seem less maintained, so it would be nice to have a single standard crate for both vector and set-like operations.

@myrrlyn
Copy link
Collaborator

myrrlyn commented Jul 4, 2022

If I'm reading this correctly, the only missing API is the resizing insert? Contains is .get(idx).unwrap_or(false), .iter_ones() and the Boolean arithmetic traits work as described.

To your favor, I have already extended the BitSlice API to include bit-set functions. Arbitrary insertion could be done as simply as

impl<T, O> BitVec<T, O> where T: BitStore, O: BitOrder {
  pub fn reallocating_insert(&mut self, idx: usize, value: bool) {
    if self.len() <= idx {
      // ensure that `idx` itself is allocated
      self.resize(idx + 1, false);
    }
    self.set(idx, value);
  }
}

If you'd like to try this out in a patched fork and see if it works for you, I'd be willing to accept a PR if you want the contribution credit, or I can just put it in the upcoming 1.1 myself.

@bjchambers
Copy link
Author

I think that would be a good start. The other things that could be useful in this direction:

  • A version of reallocating_insert that takes Iterator<Item = usize>. That could be useful to (possibly) do the reallocation once, although I guess that would need to know the upper bound, so may be not possible (unless the iterator was sorted or something).
  • A struct that wrapped BitVec and implemented a BitSet like interface (contains, insert, etc.). But -- that could also be implemented for each use if needed.

Looking at the method, I do believe it would help with my use case.

@bjchambers
Copy link
Author

It may also need additional functionality for things like union and intersect. Looking deeper, the BitAnd and BitOr seem to truncate the length to the first set, rather then resizing.

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

2 participants