Skip to content

Commit

Permalink
Lets see ....
Browse files Browse the repository at this point in the history
  • Loading branch information
Firstyear committed Apr 9, 2021
1 parent 5aed2f7 commit f1f99ca
Show file tree
Hide file tree
Showing 2 changed files with 266 additions and 7 deletions.
12 changes: 6 additions & 6 deletions benches/bench_idl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,21 @@ fn do_bench_duplex(c: &mut Criterion, label: &str, i: Duplex) {
);
group.bench_with_input(
BenchmarkId::new("Compressed V2 Sparse Sparse", &ri),
&ri,
&v2i,
|t, V2Duplex(a, b)| t.iter(|| { b | a }.sum()),
);

v2i.0.compress();
group.bench_with_input(
BenchmarkId::new("Compressed V2 Sparse Compressed", &ri),
&ri,
&v2i,
|t, V2Duplex(a, b)| t.iter(|| { b | a }.sum()),
);

v2i.1.compress();
group.bench_with_input(
BenchmarkId::new("Compressed V2 Compressed Compressed", &ri),
&ri,
&v2i,
|t, V2Duplex(a, b)| t.iter(|| { b | a }.sum()),
);
group.finish();
Expand All @@ -163,21 +163,21 @@ fn do_bench_duplex(c: &mut Criterion, label: &str, i: Duplex) {

group.bench_with_input(
BenchmarkId::new("Compressed V2 Sparse Sparse", &ri),
&ri,
&v2i,
|t, V2Duplex(a, b)| t.iter(|| { b & a }.sum()),
);

v2i.0.compress();
group.bench_with_input(
BenchmarkId::new("Compressed V2 Sparse Compressed", &ri),
&ri,
&v2i,
|t, V2Duplex(a, b)| t.iter(|| { b & a }.sum()),
);

v2i.1.compress();
group.bench_with_input(
BenchmarkId::new("Compressed V2 Compressed Compressed", &ri),
&ri,
&v2i,
|t, V2Duplex(a, b)| t.iter(|| { b & a }.sum()),
);

Expand Down
261 changes: 260 additions & 1 deletion src/v2.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

use std::iter::FromIterator;
use std::cmp::Ordering;
use std::ops::BitAnd;
use std::ops::{BitOr, BitAnd};
use smallvec::SmallVec;
use std::slice;

Expand Down Expand Up @@ -106,6 +106,15 @@ impl IDLBitRange {
}
}

pub fn sum(&self) -> u64 {
match &self.state {
IDLState::Sparse(list) => list.iter().fold(0, |acc, x| x + acc),
IDLState::Compressed(list) =>
IDLBitRangeIter::new(&list)
.fold(0, |acc, x| x + acc),
}
}

pub fn contains(&self, id: u64) -> bool {
match &self.state {
IDLState::Sparse(list) => {
Expand Down Expand Up @@ -336,6 +345,148 @@ impl IDLBitRange {
}
}
}


#[inline(always)]
fn bitor_inner(&self, rhs: &Self) -> Self {
match (&self.state, &rhs.state) {
(IDLState::Sparse(lhs), IDLState::Sparse(rhs)) => {
let mut nlist = SmallVec::with_capacity(lhs.len() + rhs.len());
let mut liter = lhs.iter();
let mut riter = rhs.iter();

let mut lnext = liter.next();
let mut rnext = riter.next();

while lnext.is_some() && rnext.is_some() {
let l = lnext.unwrap();
let r = rnext.unwrap();

let n = if l == r {
lnext = liter.next();
rnext = riter.next();
l
} else if l < r {
lnext = liter.next();
l
} else {
rnext = riter.next();
r
};
nlist.push(*n);
}

while lnext.is_some() {
let l = lnext.unwrap();
nlist.push(*l);
lnext = liter.next();
}

while rnext.is_some() {
let r = rnext.unwrap();
nlist.push(*r);
rnext = riter.next();
}

IDLBitRange {
state: IDLState::Sparse(nlist)
}
}
(IDLState::Sparse(sparselist), IDLState::Compressed(list)) |
(IDLState::Compressed(list), IDLState::Sparse(sparselist)) => {
let mut nlist = SmallVec::with_capacity(self.len() + rhs.len());
let mut liter = sparselist.iter();
let mut riter = IDLBitRangeIter::new(&list);

let mut lnext = liter.next();
let mut rnext = riter.next();

while lnext.is_some() && rnext.is_some() {
let l = *lnext.unwrap();
let r = rnext.unwrap();

let n = if l == r {
lnext = liter.next();
rnext = riter.next();
l
} else if l < r {
lnext = liter.next();
l
} else {
rnext = riter.next();
r
};
nlist.push(n);
}

while lnext.is_some() {
let l = lnext.unwrap();
nlist.push(*l);
lnext = liter.next();
}

while rnext.is_some() {
let r = rnext.unwrap();
nlist.push(r);
rnext = riter.next();
}

IDLBitRange {
state: IDLState::Sparse(nlist)
}
}
(IDLState::Compressed(list1), IDLState::Compressed(list2)) => {
let llen = list1.len();
let rlen = list2.len();

let mut nlist = Vec::with_capacity(llen + rlen);

let mut liter = list1.iter();
let mut riter = list2.iter();

let mut lnextrange = liter.next();
let mut rnextrange = riter.next();

while lnextrange.is_some() && rnextrange.is_some() {
let l = lnextrange.unwrap();
let r = rnextrange.unwrap();

let (range, mask) = if l.range == r.range {
lnextrange = liter.next();
rnextrange = riter.next();
(l.range, l.mask | r.mask)
} else if l.range < r.range {
lnextrange = liter.next();
(l.range, l.mask)
} else {
rnextrange = riter.next();
(r.range, r.mask)
};
let newrange = IDLRange::new(range, mask);
nlist.push(newrange);
}

while lnextrange.is_some() {
let l = lnextrange.unwrap();

let newrange = IDLRange::new(l.range, l.mask);
nlist.push(newrange);
lnextrange = liter.next();
}

while rnextrange.is_some() {
let r = rnextrange.unwrap();

let newrange = IDLRange::new(r.range, r.mask);
nlist.push(newrange);
rnextrange = riter.next();
}
IDLBitRange {
state: IDLState::Compressed(nlist)
}
}
} // end match
}
}

impl FromIterator<u64> for IDLBitRange {
Expand Down Expand Up @@ -413,6 +564,52 @@ impl BitAnd for IDLBitRange {
}
}

impl BitOr for &IDLBitRange {
type Output = IDLBitRange;

/// Perform an Or (union) operation between two sets. This returns
/// a new set containing the results.
///
/// # Examples
/// ```
/// # use idlset::IDLBitRange;
/// # use std::iter::FromIterator;
/// let idl_a = IDLBitRange::from_iter(vec![1, 2, 3]);
/// let idl_b = IDLBitRange::from_iter(vec![2]);
///
/// let idl_result = idl_a | idl_b;
///
/// let idl_expect = IDLBitRange::from_iter(vec![1, 2, 3]);
/// assert_eq!(idl_result, idl_expect);
/// ```
fn bitor(self, rhs: &IDLBitRange) -> IDLBitRange {
self.bitor_inner(rhs)
}
}

impl BitOr for IDLBitRange {
type Output = IDLBitRange;

/// Perform an Or (union) operation between two sets. This returns
/// a new set containing the results.
///
/// # Examples
/// ```
/// # use idlset::IDLBitRange;
/// # use std::iter::FromIterator;
/// let idl_a = IDLBitRange::from_iter(vec![1, 2, 3]);
/// let idl_b = IDLBitRange::from_iter(vec![2]);
///
/// let idl_result = idl_a | idl_b;
///
/// let idl_expect = IDLBitRange::from_iter(vec![1, 2, 3]);
/// assert_eq!(idl_result, idl_expect);
/// ```
fn bitor(self, rhs: Self) -> IDLBitRange {
self.bitor_inner(&rhs)
}
}

#[derive(Debug)]
pub struct IDLBitRangeIter<'a> {
// rangeiter: std::vec::IntoIter<IDLRange>,
Expand Down Expand Up @@ -756,4 +953,66 @@ mod tests {
let idl_result = idl_a & idl_b;
assert_eq!(idl_result, idl_expect);
}

#[test]
fn test_range_union_1() {
let idl_a = IDLBitRange::from_iter(vec![1, 2, 3]);
let idl_b = IDLBitRange::from_iter(vec![2]);
let idl_expect = IDLBitRange::from_iter(vec![1, 2, 3]);

let idl_result = idl_a | idl_b;
assert_eq!(idl_result, idl_expect);
}

#[test]
fn test_range_union_2() {
let idl_a = IDLBitRange::from_iter(vec![1, 2, 3]);
let idl_b = IDLBitRange::from_iter(vec![4, 67]);
let idl_expect = IDLBitRange::from_iter(vec![1, 2, 3, 4, 67]);

let idl_result = idl_a | idl_b;
assert_eq!(idl_result, idl_expect);
}

#[test]
fn test_range_union_3() {
let idl_a = IDLBitRange::from_iter(vec![
2, 3, 8, 35, 64, 128, 130, 150, 152, 180, 256, 800, 900,
]);
let idl_b = IDLBitRange::from_iter(1..1024);
let idl_expect = IDLBitRange::from_iter(1..1024);

let idl_result = idl_a | idl_b;
assert_eq!(idl_result, idl_expect);
}

#[test]
fn test_range_union_compressed() {
let mut idl_a = IDLBitRange::from_iter(vec![
2, 3, 8, 35, 64, 128, 130, 150, 152, 180, 256, 800, 900,
]);
let mut idl_b = IDLBitRange::from_iter(1..1024);
let mut idl_expect = IDLBitRange::from_iter(1..1024);

idl_a.compress();
idl_b.compress();
idl_expect.compress();

let idl_result = idl_a | idl_b;
assert_eq!(idl_result, idl_expect);
}

#[test]
fn test_range_sparse_union_compressed() {
let mut idl_a = IDLBitRange::from_iter(vec![
2, 3, 8, 35, 64, 128, 130, 150, 152, 180, 256, 800, 900,
]);
let mut idl_b = IDLBitRange::from_iter(1..1024);
let mut idl_expect = IDLBitRange::from_iter(1..1024);

idl_a.compress();

let idl_result = idl_a | idl_b;
assert_eq!(idl_result, idl_expect);
}
}

0 comments on commit f1f99ca

Please sign in to comment.