diff --git a/src/nested/map/fits/write.rs b/src/nested/map/fits/write.rs index df8bc74..9181d99 100644 --- a/src/nested/map/fits/write.rs +++ b/src/nested/map/fits/write.rs @@ -22,7 +22,7 @@ pub fn write_implicit_skymap_fits( // since we already know it. // In the end, using monomorphisation, the binary code is duplicated so... let n_cells = values.len() as u64; - let depth = depth_from_n_hash_unsafe(values.len()); + let depth = depth_from_n_hash_unsafe(values.len() as u64); if n_cells != n_hash(depth) { return Err(FitsError::new_custom(format!( "Number of cell {} not compatible with an HEALPix depth of {}. Expected: {}.", diff --git a/src/nested/map/mom/impls/zvec.rs b/src/nested/map/mom/impls/zvec.rs index 4170cfe..105f7ff 100644 --- a/src/nested/map/mom/impls/zvec.rs +++ b/src/nested/map/mom/impls/zvec.rs @@ -204,6 +204,52 @@ where } Self { depth, entries } } + + fn merge<'s, L, R, S, O, M>(lhs: L, rhs: R, split: S, op: O, merge: M) -> Self + where + L: Mom<'s, ZUniqHType = Z, ValueType = V>, + R: Mom<'s, ZUniqHType = Z, ValueType = V>, + S: Fn( + Self::ValueType, + ) -> ( + Self::ValueType, + Self::ValueType, + Self::ValueType, + Self::ValueType, + ), + O: Fn(Option, Option) -> Option, + M: Fn( + Self::ValueType, + Self::ValueType, + Self::ValueType, + Self::ValueType, + ) -> Result< + Self::ValueType, + ( + Self::ValueType, + Self::ValueType, + Self::ValueType, + Self::ValueType, + ), + >, + { + struct DHZV { + d: u8, + h: ZZ, + z: ZZ, + v: VV, + } + let zv_to_dhzv = |(z, v)| { + let (d, h) = Self::ZUniqHType::from_zuniq(z); + DHZV { d, h, z, v } + }; + let mut stack: Vec<(Z, V)> = Vec::with_capacity(lhs.len() + rhs.len()); + let mut it_left = lhs.owned_entries(); + let mut it_right = rhs.owned_entries(); + let mut left = it_left.next().map(zv_to_dhzv); + let mut right = it_right.next().map(zv_to_dhzv); + todo!() + } } impl MomVecImpl diff --git a/src/nested/map/mom/mod.rs b/src/nested/map/mom/mod.rs index 19aba13..fe8c645 100644 --- a/src/nested/map/mom/mod.rs +++ b/src/nested/map/mom/mod.rs @@ -231,18 +231,19 @@ pub trait Mom<'a>: Sized { M: Fn(Self::ValueType, Self::ValueType, Self::ValueType, Self::ValueType) -> Result, Self::ValueType: 's; - fn merge(lhs: L, rhs: R, split: S, op: O, merge: M) -> Self + fn merge<'s, L, R, S, O, M>(lhs: L, rhs: R, split: S, op: O, merge: M) -> Self where + L: Mom<'s, ZUniqHType = Self::ZUniqHType, ValueType = Self::ValueType>, + R: Mom<'s, ZUniqHType = Self::ZUniqHType, ValueType = Self::ValueType>, // Split a parent cell into for siblings S: Fn(Self::ValueType) -> (Self::ValueType, Self::ValueType, Self::ValueType, Self::ValueType), // Merge the values of a same cell from both MOMs - O: Fn(Self::ValueType, Self::ValueType) -> Self::ValuesIt, - // Performs a post-merge operation? - M: Fn(Self::ValueType, Self::ValueType, Self::ValueType, Self::ValueType) -> Self::ValueType, - { - // get both owned iterators - todo!() - } + // or decide what to do is one of the MOM has a value and the other does not + // (the (None, None) must never be called). + // This allow for various types of JOIN (inner, left, right, full). + O: Fn(Option, Option) -> Option, + // Possibly performs a post-merge operation. + M: Fn(Self::ValueType, Self::ValueType, Self::ValueType, Self::ValueType) -> Result; } diff --git a/src/nested/map/skymap.rs b/src/nested/map/skymap.rs index bfa9f34..c37f619 100644 --- a/src/nested/map/skymap.rs +++ b/src/nested/map/skymap.rs @@ -172,14 +172,14 @@ impl<'a, H: HHash, V: SkyMapValue + 'a> SkyMap<'a> for ImplicitSkyMapArray self.depth } - fn len(&self) -> usize { - self.values.len() - } - fn is_implicit(&self) -> bool { true } + fn len(&self) -> usize { + self.values.len() + } + fn get(&self, hash: Self::HashType) -> &Self::ValueType { &self.values.deref()[hash.as_()] } @@ -207,6 +207,73 @@ impl<'a, H: HHash, V: SkyMapValue + 'a> SkyMap<'a> for ImplicitSkyMapArray } } +pub struct ImplicitSkyMapArrayRef<'a, H: HHash, V: SkyMapValue> { + depth: u8, + values: &'a [V], + _htype: PhantomData, +} +impl<'a, H: HHash, V: SkyMapValue + 'a> ImplicitSkyMapArrayRef<'a, H, V> { + /// WARNING: we assume that the coherency between the depth and the number of elements in the + ///array has already been tested. + pub fn new(depth: u8, values: &'a [V]) -> Self { + assert_eq!( + n_hash(depth) as usize, + values.deref().len(), + "Wrong implicit skymap size. Epecgted: {}. Actual: {}.", + n_hash(depth), + values.len() + ); + Self { + depth, + values, + _htype: PhantomData, + } + } +} +impl<'a, H: HHash, V: SkyMapValue + Clone + 'a> SkyMap<'a> for ImplicitSkyMapArrayRef<'a, H, V> { + type HashType = H; + type ValueType = V; + type ValuesIt = Iter<'a, Self::ValueType>; + type EntriesIt = Map, fn((usize, &V)) -> (H, &V)>; + type OwnedEntriesIt = Map, fn((usize, &V)) -> (H, V)>; + + fn depth(&self) -> u8 { + self.depth + } + + fn is_implicit(&self) -> bool { + true + } + + fn len(&self) -> usize { + self.values.len() + } + + fn get(&self, hash: Self::HashType) -> &Self::ValueType { + &self.values.deref()[hash.as_()] + } + + fn values(&'a self) -> Self::ValuesIt { + self.values.deref().iter() + } + + fn entries(&'a self) -> Self::EntriesIt { + self + .values + .iter() + .enumerate() + .map(move |(h, v)| (H::from_usize(h), v)) + } + + fn owned_entries(self) -> Self::OwnedEntriesIt { + self + .values + .iter() + .enumerate() + .map(move |(h, v)| (H::from_usize(h), v.clone())) + } +} + pub enum SkyMapEnum { ImplicitU64U8(ImplicitSkyMapArray), ImplicitU64I16(ImplicitSkyMapArray),