use roaring::RoaringBitmap;
use super::SymbolOrdinal;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct SymbolSet {
bitmap: RoaringBitmap,
}
impl SymbolSet {
pub fn new() -> Self {
Self {
bitmap: RoaringBitmap::new(),
}
}
pub fn insert(&mut self, symbol: SymbolOrdinal) -> bool {
self.bitmap.insert(symbol.raw())
}
pub fn remove(&mut self, symbol: SymbolOrdinal) -> bool {
self.bitmap.remove(symbol.raw())
}
pub fn contains(&self, symbol: SymbolOrdinal) -> bool {
self.bitmap.contains(symbol.raw())
}
pub fn intersect_with(&mut self, other: &Self) {
self.bitmap &= &other.bitmap;
}
pub fn union_with(&mut self, other: &Self) {
self.bitmap |= &other.bitmap;
}
pub fn remove_all(&mut self, other: &Self) {
self.bitmap -= &other.bitmap;
}
pub fn intersection(&self, other: &Self) -> Self {
let mut result = self.clone();
result.intersect_with(other);
result
}
pub fn union(&self, other: &Self) -> Self {
let mut result = self.clone();
result.union_with(other);
result
}
pub fn difference(&self, other: &Self) -> Self {
let mut result = self.clone();
result.remove_all(other);
result
}
pub fn from_symbol(symbol: SymbolOrdinal) -> Self {
let mut set = Self::new();
set.insert(symbol);
set
}
pub fn is_empty(&self) -> bool {
self.bitmap.is_empty()
}
pub fn serialized_size(&self) -> usize {
self.bitmap.serialized_size()
}
pub(super) fn estimated_heap_bytes(&self) -> usize {
self.bitmap.serialized_size()
}
pub fn single(&self) -> Option<SymbolOrdinal> {
(self.len() == 1).then(|| self.iter().next()).flatten()
}
pub fn len(&self) -> usize {
let len = self.bitmap.len();
assert!(
usize::try_from(len).is_ok(),
"symbol set length exceeds usize"
);
len as usize
}
pub fn iter(&self) -> impl Iterator<Item = SymbolOrdinal> + '_ {
self.bitmap.iter().map(SymbolOrdinal)
}
}
impl FromIterator<SymbolOrdinal> for SymbolSet {
fn from_iter<T: IntoIterator<Item = SymbolOrdinal>>(iter: T) -> Self {
let mut set = Self::new();
for symbol in iter {
set.insert(symbol);
}
set
}
}