Kaynağa Gözat

Implemented 'cmp', 'partial_cmp', 'eq', 'ne', 'lt', 'le', 'gt' and 'ge' operation

master
Bergmann89 5 yıl önce
ebeveyn
işleme
60df99ff4e
7 değiştirilmiş dosya ile 330 ekleme ve 8 silme
  1. +2
    -0
      asparit/src/core/executor.rs
  2. +125
    -0
      asparit/src/core/iterator.rs
  3. +4
    -0
      asparit/src/executor/sequential.rs
  4. +4
    -0
      asparit/src/executor/tokio.rs
  5. +187
    -0
      asparit/src/iter/cmp.rs
  6. +3
    -3
      asparit/src/iter/find.rs
  7. +5
    -5
      asparit/src/iter/mod.rs

+ 2
- 0
asparit/src/core/executor.rs Dosyayı Görüntüle

@@ -23,6 +23,8 @@ where
C: Consumer<P::Item, Result = T1, Reducer = R> + 'a,
R: Reducer<T1> + Send + 'a;

fn ready(self, value: T1) -> Self::Result;

fn split(self) -> (Self, Self);

fn join<R>(left: Self::Result, right: Self::Result, reducer: R) -> Self::Result


+ 125
- 0
asparit/src/core/iterator.rs Dosyayı Görüntüle

@@ -10,6 +10,7 @@ use crate::{
chain::Chain,
chunks::Chunks,
cloned::Cloned,
cmp::{Cmp, Compare, Equal, PartialCmp},
collect::Collect,
copied::Copied,
count::Count,
@@ -1916,6 +1917,130 @@ pub trait IndexedParallelIterator<'a>: ParallelIterator<'a> {
Chunks::new(self, chunk_size)
}

/// Lexicographically compares the elements of this `ParallelIterator` with those of
/// another.
///
/// # Examples
///
/// ```
/// use rayon::prelude::*;
/// use std::cmp::Ordering::*;
///
/// let x = vec![1, 2, 3];
/// assert_eq!(x.par_iter().cmp(&vec![1, 3, 0]), Less);
/// assert_eq!(x.par_iter().cmp(&vec![1, 2, 3]), Equal);
/// assert_eq!(x.par_iter().cmp(&vec![1, 2]), Greater);
/// ```
fn cmp<X>(self, other: X) -> Cmp<Self, X::Iter>
where
X: IntoParallelIterator<'a, Item = Self::Item>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: Ord,
{
Cmp::new(self, other.into_par_iter())
}

/// Lexicographically compares the elements of this `ParallelIterator` with those of
/// another.
///
/// # Examples
///
/// ```
/// use rayon::prelude::*;
/// use std::cmp::Ordering::*;
/// use std::f64::NAN;
///
/// let x = vec![1.0, 2.0, 3.0];
/// assert_eq!(x.par_iter().partial_cmp(&vec![1.0, 3.0, 0.0]), Some(Less));
/// assert_eq!(x.par_iter().partial_cmp(&vec![1.0, 2.0, 3.0]), Some(Equal));
/// assert_eq!(x.par_iter().partial_cmp(&vec![1.0, 2.0]), Some(Greater));
/// assert_eq!(x.par_iter().partial_cmp(&vec![1.0, NAN]), None);
/// ```
fn partial_cmp<X>(self, other: X) -> PartialCmp<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialOrd<X::Item>,
{
PartialCmp::new(self, other.into_par_iter())
}

/// Determines if the elements of this `ParallelIterator`
/// are equal to those of another
fn eq<X>(self, other: X) -> Equal<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialEq<X::Item>,
{
Equal::new(self, other.into_par_iter(), true)
}

/// Determines if the elements of this `ParallelIterator`
/// are unequal to those of another
fn ne<X>(self, other: X) -> Equal<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialEq<X::Item>,
{
Equal::new(self, other.into_par_iter(), false)
}

/// Determines if the elements of this `ParallelIterator`
/// are lexicographically less than those of another.
fn lt<X>(self, other: X) -> Compare<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialOrd<X::Item>,
{
Compare::new(self, other.into_par_iter(), Ordering::Less, None)
}

/// Determines if the elements of this `ParallelIterator`
/// are less or equal to those of another.
fn le<X>(self, other: X) -> Compare<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialOrd<X::Item>,
{
Compare::new(
self,
other.into_par_iter(),
Ordering::Less,
Some(Ordering::Equal),
)
}

/// Determines if the elements of this `ParallelIterator`
/// are lexicographically greater than those of another.
fn gt<X>(self, other: X) -> Compare<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialOrd<X::Item>,
{
Compare::new(self, other.into_par_iter(), Ordering::Greater, None)
}

/// Determines if the elements of this `ParallelIterator`
/// are less or equal to those of another.
fn ge<X>(self, other: X) -> Compare<Self, X::Iter>
where
X: IntoParallelIterator<'a>,
X::Iter: IndexedParallelIterator<'a>,
Self::Item: PartialOrd<X::Item>,
{
Compare::new(
self,
other.into_par_iter(),
Ordering::Greater,
Some(Ordering::Equal),
)
}

/// Creates an iterator that yields the first `n` elements.
///
/// # Examples


+ 4
- 0
asparit/src/executor/sequential.rs Dosyayı Görüntüle

@@ -38,6 +38,10 @@ where
}
}

fn ready(self, value: T1) -> Self::Result {
value
}

fn split(self) -> (Self, Self) {
(Self, Self)
}


+ 4
- 0
asparit/src/executor/tokio.rs Dosyayı Görüntüle

@@ -62,6 +62,10 @@ where
exec_indexed(splitter, producer, consumer)
}

fn ready(self, value: T1) -> Self::Result {
async move { value }.boxed()
}

fn split(self) -> (Self, Self) {
let mut left = self;
let right = Self {


+ 187
- 0
asparit/src/iter/cmp.rs Dosyayı Görüntüle

@@ -0,0 +1,187 @@
use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};

use crate::{Driver, Executor, IndexedParallelIterator, ParallelIterator, WithIndexedProducer};

/* Cmp */

pub struct Cmp<XA, XB> {
iterator_a: XA,
iterator_b: XB,
}

impl<XA, XB> Cmp<XA, XB> {
pub fn new(iterator_a: XA, iterator_b: XB) -> Self {
Self {
iterator_a,
iterator_b,
}
}
}

impl<'a, XA, XB, I> Driver<'a, Ordering, Option<Ordering>> for Cmp<XA, XB>
where
XA: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
XB: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
I: Ord + Send + 'a,
{
fn exec_with<E>(self, executor: E) -> E::Result
where
E: Executor<'a, Ordering, Option<Ordering>>,
{
let Self {
iterator_a,
iterator_b,
} = self;

let len_a = iterator_a.len_hint();
let len_b = iterator_b.len_hint();
let ord_len = len_a.cmp(&len_b);

let executor = executor.into_inner();
let inner = iterator_a
.zip(iterator_b)
.map(|(a, b)| Ord::cmp(&a, &b))
.find_first(|ord| ord != &Ordering::Equal)
.exec_with(executor);

E::map(inner, move |inner| inner.unwrap_or(ord_len))
}
}

/* PartialCmp */

pub struct PartialCmp<XA, XB> {
iterator_a: XA,
iterator_b: XB,
}

impl<XA, XB> PartialCmp<XA, XB> {
pub fn new(iterator_a: XA, iterator_b: XB) -> Self {
Self {
iterator_a,
iterator_b,
}
}
}

impl<'a, XA, XB, I> Driver<'a, Option<Ordering>, Option<Option<Ordering>>> for PartialCmp<XA, XB>
where
XA: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
XB: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
I: PartialOrd + Send + 'a,
{
fn exec_with<E>(self, executor: E) -> E::Result
where
E: Executor<'a, Option<Ordering>, Option<Option<Ordering>>>,
{
let Self {
iterator_a,
iterator_b,
} = self;

let len_a = iterator_a.len_hint();
let len_b = iterator_b.len_hint();
let ord_len = len_a.cmp(&len_b);

let executor = executor.into_inner();
let inner = iterator_a
.zip(iterator_b)
.map(|(a, b)| PartialOrd::partial_cmp(&a, &b))
.find_first(|ord| ord != &Some(Ordering::Equal))
.exec_with(executor);

E::map(inner, move |inner| inner.unwrap_or(Some(ord_len)))
}
}

/* Equal */

pub struct Equal<XA, XB> {
iterator_a: XA,
iterator_b: XB,
expected: bool,
}

impl<XA, XB> Equal<XA, XB> {
pub fn new(iterator_a: XA, iterator_b: XB, expected: bool) -> Self {
Self {
iterator_a,
iterator_b,
expected,
}
}
}

impl<'a, XA, XB, I> Driver<'a, bool, Option<bool>> for Equal<XA, XB>
where
XA: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
XB: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
I: PartialEq + Send + 'a,
{
fn exec_with<E>(self, executor: E) -> E::Result
where
E: Executor<'a, bool, Option<bool>>,
{
let Self {
iterator_a,
iterator_b,
expected,
} = self;

let len_a = iterator_a.len_hint();
let len_b = iterator_b.len_hint();

if (len_a == len_b) ^ expected {
return executor.ready(false);
}

iterator_a
.zip(iterator_b)
.all(move |(x, y)| dbg!(PartialEq::eq(&x, &y)) == expected)
.exec_with(executor)
}
}

/* Compare */

pub struct Compare<XA, XB> {
iterator_a: XA,
iterator_b: XB,
ord: Ordering,
ord_opt: Option<Ordering>,
}

impl<XA, XB> Compare<XA, XB> {
pub fn new(iterator_a: XA, iterator_b: XB, ord: Ordering, ord_opt: Option<Ordering>) -> Self {
Self {
iterator_a,
iterator_b,
ord,
ord_opt,
}
}
}

impl<'a, XA, XB, I> Driver<'a, bool, Option<Ordering>, Option<Option<Ordering>>> for Compare<XA, XB>
where
XA: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
XB: IndexedParallelIterator<'a, Item = I> + WithIndexedProducer<'a, Item = I>,
I: PartialOrd + Send + 'a,
{
fn exec_with<E>(self, executor: E) -> E::Result
where
E: Executor<'a, bool, Option<Ordering>, Option<Option<Ordering>>>,
{
let Self {
iterator_a,
iterator_b,
ord,
ord_opt,
} = self;

let executor = executor.into_inner();
let inner = PartialCmp::new(iterator_a, iterator_b).exec_with(executor);

E::map(inner, move |inner| inner == Some(ord) || inner == ord_opt)
}
}

+ 3
- 3
asparit/src/iter/find.rs Dosyayı Görüntüle

@@ -160,7 +160,7 @@ where
)
.exec_with(executor);

E::map(ret, |x| x.is_some())
E::map(ret, |x| x.is_none())
}
}

@@ -265,8 +265,8 @@ where
loop {
let boundary = match self.find_match {
FindMatch::Any if found > 0 => return self,
FindMatch::First if found < self.lower_bound => return self,
FindMatch::Last if found > self.upper_bound => return self,
FindMatch::First if found != 0 && found < self.lower_bound => return self,
FindMatch::Last if found != 0 && found > self.upper_bound => return self,
FindMatch::Any => self.lower_bound,
FindMatch::First => self.lower_bound,
FindMatch::Last => self.upper_bound,


+ 5
- 5
asparit/src/iter/mod.rs Dosyayı Görüntüle

@@ -1,6 +1,7 @@
pub mod chain;
pub mod chunks;
pub mod cloned;
pub mod cmp;
pub mod collect;
pub mod copied;
pub mod count;
@@ -40,15 +41,14 @@ mod tests {

#[tokio::test(flavor = "multi_thread")]
async fn test_for_each() {
vec![0usize, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let x = vec![0usize, 1, 2, 3, 4]
.into_par_iter()
.with_splits(1)
.chunks(4)
.for_each(|x| {
dbg!(x);
})
.lt(vec![0usize, 1, 2, 3, 4, 5])
.exec()
.await;

dbg!(x);
}

#[tokio::test]


Yükleniyor…
İptal
Kaydet