Skip to content

Commit

Permalink
Try using serialzation to speed up bitmap/treemap compare
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-Emann committed Jan 30, 2024
1 parent b966fd2 commit f05c6b6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 30 deletions.
57 changes: 31 additions & 26 deletions fuzz/fuzz_targets/arbitrary_ops64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl<'a> Arbitrary<'a> for Num {
}
}

#[derive(Arbitrary, Debug)]
#[derive(Arbitrary, Debug, PartialEq, Eq)]
pub enum MutableBitmapOperation {
Add(Num),
AddChecked(Num),
Expand All @@ -33,13 +33,13 @@ pub enum MutableBitmapOperation {
AddToMax(u16),
}

#[derive(Arbitrary, Debug)]
#[derive(Arbitrary, Debug, PartialEq, Eq)]
pub enum MutableRhsBitmapOperation {
MutateSelf(MutableBitmapOperation),
MutBinaryOp(BitmapMutBinop),
}

#[derive(Arbitrary, Debug)]
#[derive(Arbitrary, Debug, PartialEq, Eq)]
pub enum BitmapMutBinop {
And,
Or,
Expand Down Expand Up @@ -91,7 +91,7 @@ impl BitmapMutBinop {
}
}

#[derive(Arbitrary, Debug)]
#[derive(Arbitrary, Debug, PartialEq, Eq)]
pub enum BitmapCompOperation {
Eq,
IsSubset,
Expand All @@ -104,11 +104,11 @@ pub enum BitmapCompOperation {
AndNot,
}

#[derive(Arbitrary, Debug)]
#[derive(Arbitrary, Debug, PartialEq, Eq)]
pub enum ReadBitmapOp {
ContainsRange(RangeInclusive<Num>),
Contains(Num),
RangeCardinality(RangeInclusive<Num>),
ContainsRange(RangeInclusive<u64>),
Contains(u64),
RangeCardinality(RangeInclusive<u64>),
Cardinality,
ToVec,
GetPortableSerializedSizeInBytes,
Expand All @@ -118,32 +118,31 @@ pub enum ReadBitmapOp {
GetFrozenSerializedSizeInBytes,
*/
IsEmpty,
AddOffset(i64),
IntersectWithRange(RangeInclusive<Num>),
IntersectWithRange(RangeInclusive<u64>),
Minimum,
Maximum,
Rank(Num),
Index(Num),
Select(Num),
Rank(u64),
Index(u64),
Select(u64),
Clone,
Debug,
}

impl ReadBitmapOp {
pub fn check_against_tree(&self, b: &Bitmap64, t: &Treemap) {
match *self {
ReadBitmapOp::Contains(Num(i)) => {
ReadBitmapOp::Contains(i) => {
assert_eq!(b.contains(i), t.contains(i));
}
ReadBitmapOp::RangeCardinality(ref r) => {
// Tree doesn't implement directly, but we can do it manually
let mut t_with_range = t.clone();
if !r.is_empty() {
t_with_range.remove_range(0..r.start().0);
t_with_range.remove_range(r.end().0 + 1..);
t_with_range.remove_range(0..*r.start());
t_with_range.remove_range(r.end() + 1..);
}
assert_eq!(
b.range_cardinality(r.start().0..=r.end().0),
b.range_cardinality(r.start()..=r.end()),
t_with_range.cardinality()
);
}
Expand All @@ -160,13 +159,13 @@ impl ReadBitmapOp {
ReadBitmapOp::Maximum => {
assert_eq!(b.maximum(), t.maximum());
}
ReadBitmapOp::Rank(Num(i)) => {
ReadBitmapOp::Rank(i) => {
assert_eq!(b.rank(i), t.rank(i));
}
ReadBitmapOp::Index(Num(i)) => {
ReadBitmapOp::Index(i) => {
assert_eq!(b.position(i), t.position(i));
}
ReadBitmapOp::Select(Num(i)) => {
ReadBitmapOp::Select(i) => {
assert_eq!(b.select(i), t.select(i));
}
ReadBitmapOp::Clone => {
Expand All @@ -192,14 +191,11 @@ impl ReadBitmapOp {
}
ReadBitmapOp::ContainsRange(ref range) => {
// Unsupported by treemaps
_ = b.contains_range(range.start().0..=range.end().0);
}
ReadBitmapOp::AddOffset(_) => {
// Unsupported
_ = b.contains_range(range.start()..=range.end());
}
ReadBitmapOp::IntersectWithRange(ref range) => {
// Unsupported by treemaps
_ = b.intersect_with_range(range.start().0..=range.end().0);
_ = b.intersect_with_range(range.start()..=range.end());
}
}
}
Expand Down Expand Up @@ -414,5 +410,14 @@ impl BitmapCompOperation {

pub fn assert_64_eq(lhs: &Bitmap64, rhs: &Treemap) {
assert_eq!(lhs.cardinality(), rhs.cardinality());
assert!(lhs.iter().eq(rhs.iter()));
if lhs.serialize::<Portable>() != rhs.serialize::<Portable>() {
let mut lhs = lhs.iter().enumerate();
let mut rhs = rhs.iter();
while let Some((i, l)) = lhs.next() {
let r = rhs.next().unwrap();
assert_eq!(l, r, "{l} != {r} at {i}");
}
assert!(rhs.next().is_none());
panic!("Serialize not equal, but all items equal?")
}
}
16 changes: 12 additions & 4 deletions fuzz/fuzz_targets/fuzz_ops64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ use libfuzzer_sys::fuzz_target;
mod arbitrary_ops64;

fuzz_target!(|input: FuzzInput| {
let mut lhs64 = Bitmap64::deserialize::<Portable>(input.initial_input);
// TODO: Deserialization isn't safe yet without internal validate
// let mut lhs64 = Bitmap64::deserialize::<Portable>(input.initial_input);
// let mut lhs_tree = Treemap::from_iter(lhs64.iter());
let mut lhs64 = Bitmap64::new();
let mut rhs64 = Bitmap64::new();
let mut lhs_tree = Treemap::from_iter(lhs64.iter());
let mut lhs_tree = Treemap::new();
let mut rhs_tree = Treemap::new();

let mut input = input;
// Only dedup read-only ops
input.compares.dedup();
input.view_ops.dedup();

for op in input.lhs_ops.iter().take(10) {
op.on_bitmap64(&mut lhs64);
op.on_treemap(&mut lhs_tree);
Expand All @@ -34,10 +42,10 @@ fuzz_target!(|input: FuzzInput| {
});

#[derive(Arbitrary, Debug)]
struct FuzzInput<'a> {
struct FuzzInput {
lhs_ops: Vec<MutableBitmapOperation>,
rhs_ops: Vec<MutableRhsBitmapOperation>,
compares: Vec<BitmapCompOperation>,
view_ops: Vec<ReadBitmapOp>,
initial_input: &'a [u8],
// initial_input: &'a [u8],
}

0 comments on commit f05c6b6

Please sign in to comment.