From 75acdfd30add3089649145ea1ac06a92f864e094 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Tue, 11 Jun 2024 10:59:57 -0400 Subject: [PATCH 1/2] Product with flatcontainer Signed-off-by: Moritz Hoffmann --- timely/src/order.rs | 243 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) diff --git a/timely/src/order.rs b/timely/src/order.rs index cd4796fae..22c297307 100644 --- a/timely/src/order.rs +++ b/timely/src/order.rs @@ -57,12 +57,14 @@ implement_partial!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isiz implement_total!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, (), ::std::time::Duration,); pub use product::Product; +pub use product::flatcontainer::{ProductRef, ProductRegion as FlatProductRegion}; /// A pair of timestamps, partially ordered by the product order. mod product { use std::fmt::{Formatter, Error, Debug}; use crate::container::columnation::{Columnation, Region}; use crate::order::{Empty, TotalOrder}; + use crate::order::product::flatcontainer::ProductRef; use crate::progress::Timestamp; use crate::progress::timestamp::PathSummary; use crate::progress::timestamp::Refines; @@ -109,6 +111,33 @@ mod product { } } + impl<'a, TOuter, RO, TInner, RI> PartialOrder> for Product + where + TOuter: PartialOrder>, + RO: crate::container::flatcontainer::Region, + TInner: PartialOrder>, + RI: crate::container::flatcontainer::Region, + Self: PartialEq>, + { + #[inline] + fn less_equal(&self, other: &ProductRef<'a, RO, RI>) -> bool { + self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner) + } + } + + impl<'a, TOuter, RO, TInner, RI> PartialEq> for Product + where + TOuter: PartialEq>, + RO: crate::container::flatcontainer::Region, + TInner: PartialEq>, + RI: crate::container::flatcontainer::Region, + { + #[inline] + fn eq(&self, other: &ProductRef<'a, RO, RI>) -> bool { + self.outer.eq(&other.outer) && self.inner.eq(&other.inner) + } + } + impl Timestamp for Product { type Summary = Product; fn minimum() -> Self { Self { outer: TOuter::minimum(), inner: TInner::minimum() }} @@ -188,6 +217,220 @@ mod product { self.inner_region.heap_size(callback); } } + + pub mod flatcontainer { + use timely_container::flatcontainer::{Containerized, IntoOwned, Push, Region, ReserveItems}; + use crate::PartialOrder; + use super::Product; + + impl Containerized for Product { + type Region = ProductRegion; + } + + /// Region to store [`Product`] timestamps. + #[derive(Default, Clone, Debug)] + pub struct ProductRegion { + outer_region: RO, + inner_region: RI, + } + + impl Region for ProductRegion { + type Owned = Product; + type ReadItem<'a> = ProductRef<'a, RO, RI> where Self: 'a; + type Index = (RO::Index, RI::Index); + + #[inline] + fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where Self: 'a { + let outer_region = RO::merge_regions(regions.clone().map(|r| &r.outer_region)); + let inner_region = RI::merge_regions(regions.map(|r| &r.inner_region)); + Self { outer_region, inner_region } + } + + #[inline] + fn index(&self, (outer, inner): Self::Index) -> Self::ReadItem<'_> { + ProductRef { outer: self.outer_region.index(outer), inner: self.inner_region.index(inner) } + } + + #[inline] + fn reserve_regions<'a, I>(&mut self, regions: I) where Self: 'a, I: Iterator + Clone { + self.outer_region.reserve_regions(regions.clone().map(|r| &r.outer_region)); + self.inner_region.reserve_regions(regions.map(|r| &r.inner_region)); + } + + #[inline] + fn clear(&mut self) { + self.outer_region.clear(); + self.inner_region.clear(); + } + + #[inline] + fn heap_size(&self, mut callback: F) { + self.outer_region.heap_size(&mut callback); + self.inner_region.heap_size(callback); + } + + #[inline] + fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b> where Self: 'a { + ProductRef { outer: RO::reborrow(item.outer), inner: RI::reborrow(item.inner) } + } + } + + impl<'a, RO, RI> ReserveItems> for ProductRegion + where + RO: Region + ReserveItems<::ReadItem<'a>> + 'a, + RI: Region + ReserveItems<::ReadItem<'a>> + 'a, + { + #[inline] + fn reserve_items(&mut self, items: I) where I: Iterator> + Clone { + self.outer_region.reserve_items(items.clone().map(|i| i.outer)); + self.inner_region.reserve_items(items.clone().map(|i| i.inner)); + } + } + + impl Push> for ProductRegion + where + RO: Region + Push, + RI: Region + Push, + { + #[inline] + fn push(&mut self, item: Product) -> Self::Index { + ( + self.outer_region.push(item.outer), + self.inner_region.push(item.inner) + ) + } + } + + impl<'a, TO, TI, RO, RI> Push<&'a Product> for ProductRegion + where + RO: Region + Push<&'a TO>, + RI: Region + Push<&'a TI>, + { + #[inline] + fn push(&mut self, item: &'a Product) -> Self::Index { + ( + self.outer_region.push(&item.outer), + self.inner_region.push(&item.inner) + ) + } + } + + impl<'a, TO, TI, RO, RI> Push<&&'a Product> for ProductRegion + where + RO: Region + Push<&'a TO>, + RI: Region + Push<&'a TI>, + { + #[inline] + fn push(&mut self, item: && 'a Product) -> Self::Index { + ( + self.outer_region.push(&item.outer), + self.inner_region.push(&item.inner) + ) + } + } + + impl<'a, RO, RI> Push> for ProductRegion + where + RO: Region + Push<::ReadItem<'a>>, + RI: Region + Push<::ReadItem<'a>>, + { + #[inline] + fn push(&mut self, item: ProductRef<'a, RO, RI>) -> Self::Index { + ( + self.outer_region.push(item.outer), + self.inner_region.push(item.inner) + ) + } + } + + /// A reference type similar to [`Product`] + #[derive(Ord, PartialOrd, Eq, PartialEq)] + pub struct ProductRef<'a, RO: Region + 'a, RI: Region + 'a> { + /// Outer timestamp. + pub outer: RO::ReadItem<'a>, + /// Inner timestamp. + pub inner: RI::ReadItem<'a>, + } + + impl<'a, RO, RI> std::fmt::Debug for ProductRef<'a, RO, RI> + where + RO: Region + 'a, + RO::ReadItem<'a>: std::fmt::Debug, + RI: Region + 'a, + RI::ReadItem<'a>: std::fmt::Debug, + { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "({:?}, {:?})", self.outer, self.inner) + } + } + + impl<'a, RO, RI> Clone for ProductRef<'a, RO, RI> + where + RO: Region + 'a, + RO::ReadItem<'a>: Copy, + RI: Region + 'a, + RI::ReadItem<'a>: Copy, + { + #[inline] + fn clone(&self) -> Self { + Self { outer: self.outer, inner: self.inner } + } + } + + impl<'a, RO, RI> Copy for ProductRef<'a, RO, RI> + where + RO: Region + 'a, + RO::ReadItem<'a>: Copy, + RI: Region + 'a, + RI::ReadItem<'a>: Copy, + {} + + impl<'a, RO: Region, RI: Region> IntoOwned<'a> for ProductRef<'a, RO, RI> { + type Owned = Product; + + #[inline] + fn into_owned(self) -> Self::Owned { + Product::new(self.outer.into_owned(), self.inner.into_owned()) + } + + #[inline] + fn clone_onto(self, other: &mut Self::Owned) { + self.outer.clone_onto(&mut other.outer); + self.inner.clone_onto(&mut other.inner); + } + + #[inline] + fn borrow_as(owned: &'a Self::Owned) -> Self { + Self { outer: IntoOwned::borrow_as(&owned.outer), inner: IntoOwned::borrow_as(&owned.inner) } + } + } + + impl<'a, TOuter, RO, TInner, RI> PartialOrder> for ProductRef<'a, RO, RI> + where + RO: Region, + RO::ReadItem<'a>: PartialOrder, + RI: Region, + RI::ReadItem<'a>: PartialOrder, + { + #[inline] + fn less_equal(&self, other: &Product) -> bool { + self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner) + } + } + + impl<'a, TOuter, RO, TInner, RI> PartialEq> for ProductRef<'a, RO, RI> + where + RO: Region, + RO::ReadItem<'a>: PartialEq, + RI: Region, + RI::ReadItem<'a>: PartialEq, + { + #[inline] + fn eq(&self, other: &Product) -> bool { + self.outer.eq(&other.outer) && self.inner.eq(&other.inner) + } + } + } } /// Rust tuple ordered by the lexicographic order. From 941895012af418a977fa4c2b4ac0551c02a1389d Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Wed, 12 Jun 2024 09:48:09 -0400 Subject: [PATCH 2/2] Remove ProductRef Signed-off-by: Moritz Hoffmann --- timely/src/order.rs | 164 ++++++++------------------------------------ 1 file changed, 27 insertions(+), 137 deletions(-) diff --git a/timely/src/order.rs b/timely/src/order.rs index 22c297307..e9050b3f4 100644 --- a/timely/src/order.rs +++ b/timely/src/order.rs @@ -57,14 +57,13 @@ implement_partial!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isiz implement_total!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, (), ::std::time::Duration,); pub use product::Product; -pub use product::flatcontainer::{ProductRef, ProductRegion as FlatProductRegion}; +pub use product::flatcontainer::ProductRegion as FlatProductRegion; /// A pair of timestamps, partially ordered by the product order. mod product { use std::fmt::{Formatter, Error, Debug}; use crate::container::columnation::{Columnation, Region}; use crate::order::{Empty, TotalOrder}; - use crate::order::product::flatcontainer::ProductRef; use crate::progress::Timestamp; use crate::progress::timestamp::PathSummary; use crate::progress::timestamp::Refines; @@ -111,33 +110,6 @@ mod product { } } - impl<'a, TOuter, RO, TInner, RI> PartialOrder> for Product - where - TOuter: PartialOrder>, - RO: crate::container::flatcontainer::Region, - TInner: PartialOrder>, - RI: crate::container::flatcontainer::Region, - Self: PartialEq>, - { - #[inline] - fn less_equal(&self, other: &ProductRef<'a, RO, RI>) -> bool { - self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner) - } - } - - impl<'a, TOuter, RO, TInner, RI> PartialEq> for Product - where - TOuter: PartialEq>, - RO: crate::container::flatcontainer::Region, - TInner: PartialEq>, - RI: crate::container::flatcontainer::Region, - { - #[inline] - fn eq(&self, other: &ProductRef<'a, RO, RI>) -> bool { - self.outer.eq(&other.outer) && self.inner.eq(&other.inner) - } - } - impl Timestamp for Product { type Summary = Product; fn minimum() -> Self { Self { outer: TOuter::minimum(), inner: TInner::minimum() }} @@ -220,7 +192,6 @@ mod product { pub mod flatcontainer { use timely_container::flatcontainer::{Containerized, IntoOwned, Push, Region, ReserveItems}; - use crate::PartialOrder; use super::Product; impl Containerized for Product { @@ -236,7 +207,7 @@ mod product { impl Region for ProductRegion { type Owned = Product; - type ReadItem<'a> = ProductRef<'a, RO, RI> where Self: 'a; + type ReadItem<'a> = Product, RI::ReadItem<'a>> where Self: 'a; type Index = (RO::Index, RI::Index); #[inline] @@ -248,7 +219,7 @@ mod product { #[inline] fn index(&self, (outer, inner): Self::Index) -> Self::ReadItem<'_> { - ProductRef { outer: self.outer_region.index(outer), inner: self.inner_region.index(inner) } + Product::new(self.outer_region.index(outer), self.inner_region.index(inner)) } #[inline] @@ -271,17 +242,38 @@ mod product { #[inline] fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b> where Self: 'a { - ProductRef { outer: RO::reborrow(item.outer), inner: RI::reborrow(item.inner) } + Product::new(RO::reborrow(item.outer), RI::reborrow(item.inner)) + } + } + + impl<'a, TOuter, TInner> IntoOwned<'a> for Product + where + TOuter: IntoOwned<'a>, + TInner: IntoOwned<'a>, + { + type Owned = Product; + + fn into_owned(self) -> Self::Owned { + Product::new(self.outer.into_owned(), self.inner.into_owned()) + } + + fn clone_onto(self, other: &mut Self::Owned) { + self.outer.clone_onto(&mut other.outer); + self.inner.clone_onto(&mut other.inner); + } + + fn borrow_as(owned: &'a Self::Owned) -> Self { + Product::new(IntoOwned::borrow_as(&owned.outer), IntoOwned::borrow_as(&owned.inner)) } } - impl<'a, RO, RI> ReserveItems> for ProductRegion + impl<'a, RO, RI> ReserveItems, RI::ReadItem<'a>>> for ProductRegion where RO: Region + ReserveItems<::ReadItem<'a>> + 'a, RI: Region + ReserveItems<::ReadItem<'a>> + 'a, { #[inline] - fn reserve_items(&mut self, items: I) where I: Iterator> + Clone { + fn reserve_items(&mut self, items: I) where I: Iterator, RI::ReadItem<'a>>> + Clone { self.outer_region.reserve_items(items.clone().map(|i| i.outer)); self.inner_region.reserve_items(items.clone().map(|i| i.inner)); } @@ -328,108 +320,6 @@ mod product { ) } } - - impl<'a, RO, RI> Push> for ProductRegion - where - RO: Region + Push<::ReadItem<'a>>, - RI: Region + Push<::ReadItem<'a>>, - { - #[inline] - fn push(&mut self, item: ProductRef<'a, RO, RI>) -> Self::Index { - ( - self.outer_region.push(item.outer), - self.inner_region.push(item.inner) - ) - } - } - - /// A reference type similar to [`Product`] - #[derive(Ord, PartialOrd, Eq, PartialEq)] - pub struct ProductRef<'a, RO: Region + 'a, RI: Region + 'a> { - /// Outer timestamp. - pub outer: RO::ReadItem<'a>, - /// Inner timestamp. - pub inner: RI::ReadItem<'a>, - } - - impl<'a, RO, RI> std::fmt::Debug for ProductRef<'a, RO, RI> - where - RO: Region + 'a, - RO::ReadItem<'a>: std::fmt::Debug, - RI: Region + 'a, - RI::ReadItem<'a>: std::fmt::Debug, - { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "({:?}, {:?})", self.outer, self.inner) - } - } - - impl<'a, RO, RI> Clone for ProductRef<'a, RO, RI> - where - RO: Region + 'a, - RO::ReadItem<'a>: Copy, - RI: Region + 'a, - RI::ReadItem<'a>: Copy, - { - #[inline] - fn clone(&self) -> Self { - Self { outer: self.outer, inner: self.inner } - } - } - - impl<'a, RO, RI> Copy for ProductRef<'a, RO, RI> - where - RO: Region + 'a, - RO::ReadItem<'a>: Copy, - RI: Region + 'a, - RI::ReadItem<'a>: Copy, - {} - - impl<'a, RO: Region, RI: Region> IntoOwned<'a> for ProductRef<'a, RO, RI> { - type Owned = Product; - - #[inline] - fn into_owned(self) -> Self::Owned { - Product::new(self.outer.into_owned(), self.inner.into_owned()) - } - - #[inline] - fn clone_onto(self, other: &mut Self::Owned) { - self.outer.clone_onto(&mut other.outer); - self.inner.clone_onto(&mut other.inner); - } - - #[inline] - fn borrow_as(owned: &'a Self::Owned) -> Self { - Self { outer: IntoOwned::borrow_as(&owned.outer), inner: IntoOwned::borrow_as(&owned.inner) } - } - } - - impl<'a, TOuter, RO, TInner, RI> PartialOrder> for ProductRef<'a, RO, RI> - where - RO: Region, - RO::ReadItem<'a>: PartialOrder, - RI: Region, - RI::ReadItem<'a>: PartialOrder, - { - #[inline] - fn less_equal(&self, other: &Product) -> bool { - self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner) - } - } - - impl<'a, TOuter, RO, TInner, RI> PartialEq> for ProductRef<'a, RO, RI> - where - RO: Region, - RO::ReadItem<'a>: PartialEq, - RI: Region, - RI::ReadItem<'a>: PartialEq, - { - #[inline] - fn eq(&self, other: &Product) -> bool { - self.outer.eq(&other.outer) && self.inner.eq(&other.inner) - } - } } }