#![deny(missing_docs)]
use std::io::{Read, Write};
use std::os::raw::c_void;
use std::ptr;
use std::sync::Once;
mod fixedbitset_api;
fn init_lib() {
static START: Once = Once::new();
START.call_once(|| {
unsafe {
let res = bitmagic_sys::BM_init(ptr::null_mut());
_check_res(res);
};
});
}
pub struct BVector {
handle: *mut c_void,
}
impl BVector {
pub fn serialize<W>(&self, mut wtr: W) -> Result<(), Box<dyn std::error::Error>>
where
W: Write,
{
let mut bv_stat = bitmagic_sys::BM_bvector_statistics {
bit_blocks: 0,
gap_blocks: 0,
max_serialize_mem: 0,
memory_used: 0,
};
let mut res;
unsafe {
res = bitmagic_sys::BM_bvector_optimize(self.handle, 3, &mut bv_stat);
}
_check_res(res);
let mut buf = vec![0u8; bv_stat.max_serialize_mem as usize];
let mut blob_size = 0;
unsafe {
res = bitmagic_sys::BM_bvector_serialize(
self.handle,
buf.as_mut_ptr() as *mut ::std::os::raw::c_char,
buf.len(),
&mut blob_size,
);
}
_check_res(res);
if blob_size == 0 || blob_size > bv_stat.max_serialize_mem {
unimplemented!("throw error")
}
wtr.write_all(buf.as_slice())?;
Ok(())
}
pub fn deserialize<R>(mut rdr: R) -> Result<Self, Box<dyn std::error::Error>>
where
R: Read,
{
let mut buf = vec![];
rdr.read_to_end(&mut buf)?;
let bnew = BVector::with_capacity(1);
let res;
unsafe {
res = bitmagic_sys::BM_bvector_deserialize(
bnew.handle,
buf.as_ptr() as *const ::std::os::raw::c_char,
buf.len(),
);
}
_check_res(res);
Ok(bnew)
}
pub fn intersection_count(&self, other: &BVector) -> usize {
let mut pcount = 0;
let res;
unsafe {
res = bitmagic_sys::BM_bvector_count_AND(self.handle, other.handle, &mut pcount);
}
_check_res(res);
pcount as usize
}
pub fn union_count(&self, other: &BVector) -> usize {
let mut pcount = 0;
let res;
unsafe {
res = bitmagic_sys::BM_bvector_count_OR(self.handle, other.handle, &mut pcount);
}
_check_res(res);
pcount as usize
}
pub fn difference_count(&self, other: &BVector) -> usize {
let mut pcount = 0;
let res;
unsafe {
res = bitmagic_sys::BM_bvector_count_SUB(self.handle, other.handle, &mut pcount);
}
_check_res(res);
pcount as usize
}
pub fn symmetric_difference_count(&self, other: &BVector) -> usize {
let mut pcount = 0;
let res;
unsafe {
res = bitmagic_sys::BM_bvector_count_XOR(self.handle, other.handle, &mut pcount);
}
_check_res(res);
pcount as usize
}
}
pub(crate) fn _check_res(_res: i32) {
}
#[cfg(test)]
mod tests {
use crate::BVector;
#[test]
fn serde() {
let mut bv = BVector::with_capacity(100);
bv.set_range(10..20, true);
bv.set_range(50..70, true);
let mut wtr = vec![];
bv.serialize(&mut wtr).unwrap();
let new_bv = BVector::deserialize(wtr.as_slice()).unwrap();
assert_eq!(new_bv, bv);
for i in 10..20 {
assert!(new_bv.contains(i));
}
for i in 50..70 {
assert!(new_bv.contains(i));
}
}
}